From 9e78f6feb269050b4059bdcab76034cfdc702a8b Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 15 Mar 2013 19:30:28 +0530 Subject: [PATCH 001/137] 8010136: Make jrunscript's init.js to work on nashorn Reviewed-by: lagergren, hannesw --- .../com/sun/tools/script/shell/init.js | 1015 +++++++++-------- 1 file changed, 538 insertions(+), 477 deletions(-) diff --git a/jdk/src/share/classes/com/sun/tools/script/shell/init.js b/jdk/src/share/classes/com/sun/tools/script/shell/init.js index 35256fa8ccd..5f294b4684f 100644 --- a/jdk/src/share/classes/com/sun/tools/script/shell/init.js +++ b/jdk/src/share/classes/com/sun/tools/script/shell/init.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, 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 @@ -28,7 +28,7 @@ */ /** - * Creates an object that delegates all method calls on + * Creates an object that delegates all method calls on * it to the 'invoke' method on the given delegate object.
* * Example: @@ -43,13 +43,13 @@ * @constructor */ function JSInvoker(obj) { - return new JSAdapter({ - __get__ : function(name) { - return function() { - return obj.invoke(name, arguments); - } - } - }); + return new JSAdapter({ + __get__ : function(name) { + return function() { + return obj.invoke(name, arguments); + } + } + }); } /** @@ -58,24 +58,24 @@ function JSInvoker(obj) { * example, env.PATH will return PATH value configured. */ var env = new JSAdapter({ - __get__ : function (name) { - return java.lang.System.getenv(name); - }, - __has__ : function (name) { - return java.lang.System.getenv().containsKey(name); - }, - __getIds__ : function() { - return java.lang.System.getenv().keySet().toArray(); - }, - __delete__ : function(name) { - println("can't delete env item"); - }, - __put__ : function (name, value) { - println("can't change env item"); - }, - toString: function() { - return java.lang.System.getenv().toString(); - } + __get__ : function (name) { + return java.lang.System.getenv(name); + }, + __has__ : function (name) { + return java.lang.System.getenv().containsKey(name); + }, + __getIds__ : function() { + return java.lang.System.getenv().keySet().toArray(); + }, + __delete__ : function(name) { + println("can't delete env item"); + }, + __put__ : function (name, value) { + println("can't change env item"); + }, + toString: function() { + return java.lang.System.getenv().toString(); + } }); /** @@ -91,36 +91,36 @@ var env = new JSAdapter({ * delete y['java.class.path']; // remove java.class.path System property * * - * + * * @param map java.util.Map instance that will be wrapped * @constructor */ -function jmap(map) { - return new JSAdapter({ - __get__ : function(name) { - if (map.containsKey(name)) { - return map.get(name); - } else { - return undefined; - } - }, - __has__ : function(name) { - return map.containsKey(name); - }, +function jmap(map) { + return new JSAdapter({ + __get__ : function(name) { + if (map.containsKey(name)) { + return map.get(name); + } else { + return undefined; + } + }, + __has__ : function(name) { + return map.containsKey(name); + }, - __delete__ : function (name) { - return map.remove(name); - }, - __put__ : function(name, value) { - map.put(name, value); - }, - __getIds__ : function() { - return map.keySet().toArray(); - }, - toString: function() { - return map.toString(); - } - }); + __delete__ : function (name) { + return map.remove(name); + }, + __put__ : function(name, value) { + map.put(name, value); + }, + __getIds__ : function() { + return map.keySet().toArray(); + }, + toString: function() { + return map.toString(); + } + }); } /** @@ -146,52 +146,72 @@ function jmap(map) { * @constructor */ function jlist(list) { - function isValid(index) { - return typeof(index) == 'number' && - index > -1 && index < list.size(); - } - return new JSAdapter({ - __get__ : function(name) { - if (isValid(name)) { - return list.get(name); - } else if (name == 'length') { - return list.size(); - } else { - return undefined; - } - }, - __has__ : function (name) { - return isValid(name) || name == 'length'; - }, - __delete__ : function(name) { - if (isValid(name)) { - list.remove(name); - } - }, - __put__ : function(name, value) { - if (isValid(name)) { - list.set(name, value); - } - }, - __getIds__: function() { - var res = new Array(list.size()); - for (var i = 0; i < res.length; i++) { - res[i] = i; - } - return res; - }, - toString: function() { - return list.toString(); - } - }); + function isValid(index) { + return typeof(index) == 'number' && + index > -1 && index < list.size(); + } + return new JSAdapter({ + __get__ : function(name) { + if (isValid(name)) { + return list.get(name); + } else if (name == 'length') { + return list.size(); + } else { + return undefined; + } + }, + __has__ : function (name) { + return isValid(name) || name == 'length'; + }, + __delete__ : function(name) { + if (isValid(name)) { + list.remove(name); + } + }, + __put__ : function(name, value) { + if (isValid(name)) { + list.set(name, value); + } + }, + __getIds__: function() { + var res = new Array(list.size()); + for (var i = 0; i < res.length; i++) { + res[i] = i; + } + return res; + }, + toString: function() { + return list.toString(); + } + }); } /** - * This is java.lang.System properties wrapped by jmap. + * This is java.lang.System properties wrapped by JSAdapter. * For eg. to access java.class.path property, you can use * the syntax sysProps["java.class.path"] */ -var sysProps = jmap(java.lang.System.getProperties()); +var sysProps = new JSAdapter({ + __get__ : function (name) { + return java.lang.System.getProperty(name); + }, + __has__ : function (name) { + return java.lang.System.getProperty(name) != null; + }, + __getIds__ : function() { + return java.lang.System.getProperties().keySet().toArray(); + }, + __delete__ : function(name) { + java.lang.System.clearProperty(name); + return true; + }, + __put__ : function (name, value) { + java.lang.System.setProperty(name, value); + }, + toString: function() { + return ""; + } +}); // stdout, stderr & stdin var out = java.lang.System.out; @@ -199,76 +219,85 @@ var err = java.lang.System.err; // can't use 'in' because it is a JavaScript keyword :-( var inp = java.lang.System["in"]; -// useful imports for often used io, net classes -importPackage(java.io); -importPackage(java.net); +var BufferedInputStream = java.io.BufferedInputStream; +var BufferedOutputStream = java.io.BufferedOutputStream; +var BufferedReader = java.io.BufferedReader; +var DataInputStream = java.io.DataInputStream; +var File = java.io.File; +var FileInputStream = java.io.FileInputStream; +var FileOutputStream = java.io.FileOutputStream; +var InputStream = java.io.InputStream; +var InputStreamReader = java.io.InputStreamReader; +var OutputStream = java.io.OutputStream; +var Reader = java.io.Reader; +var URL = java.net.URL; /** * Generic any object to input stream mapper - * @param str input file name, URL or InputStream + * @param str input file name, URL or InputStream * @return InputStream object * @private */ function inStream(str) { - if (typeof(str) == "string") { - // '-' means standard input - if (str == '-') { - return java.lang.System["in"]; - } - // try file first - var file = null; - try { - file = pathToFile(str); - } catch (e) { - } - if (file && file.exists()) { - return new FileInputStream(file); - } else { - try { - // treat the string as URL - return new URL(str).openStream(); - } catch (e) { - throw 'file or URL ' + str + ' not found'; - } - } - } else { - if (str instanceof InputStream) { - return str; - } else if (str instanceof URL) { - return str.openStream(); - } else if (str instanceof File) { - return new FileInputStream(str); - } - } - // everything failed, just give input stream - return java.lang.System["in"]; + if (typeof(str) == "string") { + // '-' means standard input + if (str == '-') { + return java.lang.System["in"]; + } + // try file first + var file = null; + try { + file = pathToFile(str); + } catch (e) { + } + if (file && file.exists()) { + return new FileInputStream(file); + } else { + try { + // treat the string as URL + return new URL(str).openStream(); + } catch (e) { + throw 'file or URL ' + str + ' not found'; + } + } + } else { + if (str instanceof InputStream) { + return str; + } else if (str instanceof URL) { + return str.openStream(); + } else if (str instanceof File) { + return new FileInputStream(str); + } + } + // everything failed, just give input stream + return java.lang.System["in"]; } /** * Generic any object to output stream mapper - * + * * @param out output file name or stream * @return OutputStream object * @private */ function outStream(out) { - if (typeof(out) == "string") { - if (out == '>') { - return java.lang.System.out; - } else { - // treat it as file - return new FileOutputStream(pathToFile(out)); - } - } else { - if (out instanceof OutputStream) { - return out; - } else if (out instanceof File) { - return new FileOutputStream(out); - } - } + if (typeof(out) == "string") { + if (out == '>') { + return java.lang.System.out; + } else { + // treat it as file + return new FileOutputStream(pathToFile(out)); + } + } else { + if (out instanceof OutputStream) { + return out; + } else if (out instanceof File) { + return new FileOutputStream(out); + } + } - // everything failed, just return System.out - return java.lang.System.out; + // everything failed, just return System.out + return java.lang.System.out; } /** @@ -276,17 +305,17 @@ function outStream(out) { * @private */ function streamClose(stream) { - if (stream) { - if (stream != java.lang.System["in"] && - stream != java.lang.System.out && - stream != java.lang.System.err) { - try { - stream.close(); - } catch (e) { - println(e); - } - } - } + if (stream) { + if (stream != java.lang.System["in"] && + stream != java.lang.System.out && + stream != java.lang.System.err) { + try { + stream.close(); + } catch (e) { + println(e); + } + } + } } /** @@ -302,18 +331,20 @@ function streamClose(stream) { * * @param str input from which script is loaded and evaluated */ -function load(str) { - var stream = inStream(str); - var bstream = new BufferedInputStream(stream); - var reader = new BufferedReader(new InputStreamReader(bstream)); - var oldFilename = engine.get(engine.FILENAME); - engine.put(engine.FILENAME, str); - try { - engine.eval(reader); - } finally { - engine.put(engine.FILENAME, oldFilename); - streamClose(stream); - } +if (typeof(load) == 'undefined') { + var load = function(str) { + var stream = inStream(str); + var bstream = new BufferedInputStream(stream); + var reader = new BufferedReader(new InputStreamReader(bstream)); + var oldFilename = engine.get(engine.FILENAME); + engine.put(engine.FILENAME, str); + try { + engine.eval(reader); + } finally { + engine.put(engine.FILENAME, oldFilename); + streamClose(stream); + } + } } // file system utilities @@ -324,7 +355,7 @@ function load(str) { * @private */ function javaByteArray(len) { - return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len); + return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len); } var curDir = new File('.'); @@ -333,7 +364,7 @@ var curDir = new File('.'); * Print present working directory */ function pwd() { - println(curDir.getAbsolutePath()); + println(curDir.getAbsolutePath()); } /** @@ -341,17 +372,17 @@ function pwd() { * @param target directory to change to. optional, defaults to user's HOME */ function cd(target) { - if (target == undefined) { - target = sysProps["user.home"]; - } - if (!(target instanceof File)) { - target = pathToFile(target); - } - if (target.exists() && target.isDirectory()) { - curDir = target; - } else { - println(target + " is not a directory"); - } + if (target == undefined) { + target = sysProps["user.home"]; + } + if (!(target instanceof File)) { + target = pathToFile(target); + } + if (target.exists() && target.isDirectory()) { + curDir = target; + } else { + println(target + " is not a directory"); + } } /** @@ -361,15 +392,15 @@ function cd(target) { * @private */ function pathToFile(pathname) { - var tmp = pathname; - if (!(tmp instanceof File)) { - tmp = new File(tmp); - } - if (!tmp.isAbsolute()) { - return new File(curDir, pathname); - } else { - return tmp; - } + var tmp = pathname; + if (!(tmp instanceof File)) { + tmp = new File(tmp); + } + if (!tmp.isAbsolute()) { + return new File(curDir, pathname); + } else { + return tmp; + } } /** @@ -379,22 +410,22 @@ function pathToFile(pathname) { * @param to output stream or file */ function cp(from, to) { - if (from == to) { - println("file " + from + " cannot be copied onto itself!"); - return; - } - var inp = inStream(from); - var out = outStream(to); - var binp = new BufferedInputStream(inp); - var bout = new BufferedOutputStream(out); - var buff = javaByteArray(1024); - var len; - while ((len = binp.read(buff)) > 0 ) - bout.write(buff, 0, len); + if (from == to) { + println("file " + from + " cannot be copied onto itself!"); + return; + } + var inp = inStream(from); + var out = outStream(to); + var binp = new BufferedInputStream(inp); + var bout = new BufferedOutputStream(out); + var buff = javaByteArray(1024); + var len; + while ((len = binp.read(buff)) > 0 ) + bout.write(buff, 0, len); - bout.flush(); - streamClose(inp); - streamClose(out); + bout.flush(); + streamClose(inp); + streamClose(out); } /** @@ -403,37 +434,37 @@ function cp(from, to) { *
  * 
  *    cat('test.txt'); // show test.txt file contents
- *    cat('http://java.net'); // show the contents from the URL http://java.net 
+ *    cat('http://java.net'); // show the contents from the URL http://java.net
  * 
  * 
* @param obj input to show * @param pattern optional. show only the lines matching the pattern */ function cat(obj, pattern) { - if (obj instanceof File && obj.isDirectory()) { - ls(obj); - return; - } - - var inp = null; - if (!(obj instanceof Reader)) { - inp = inStream(obj); - obj = new BufferedReader(new InputStreamReader(inp)); - } - var line; - if (pattern) { - var count = 1; - while ((line=obj.readLine()) != null) { - if (line.match(pattern)) { - println(count + "\t: " + line); - } - count++; - } - } else { - while ((line=obj.readLine()) != null) { - println(line); - } - } + if (obj instanceof File && obj.isDirectory()) { + ls(obj); + return; + } + + var inp = null; + if (!(obj instanceof Reader)) { + inp = inStream(obj); + obj = new BufferedReader(new InputStreamReader(inp)); + } + var line; + if (pattern) { + var count = 1; + while ((line=obj.readLine()) != null) { + if (line.match(pattern)) { + println(count + "\t: " + line); + } + count++; + } + } else { + while ((line=obj.readLine()) != null) { + println(line); + } + } } /** @@ -443,13 +474,13 @@ function cat(obj, pattern) { * @return directory part of the given file name */ function dirname(pathname) { - var dirName = "."; - // Normalize '/' to local file separator before work. - var i = pathname.replace('/', File.separatorChar ).lastIndexOf( - File.separator ); - if ( i != -1 ) - dirName = pathname.substring(0, i); - return dirName; + var dirName = "."; + // Normalize '/' to local file separator before work. + var i = pathname.replace('/', File.separatorChar ).lastIndexOf( + File.separator ); + if ( i != -1 ) + dirName = pathname.substring(0, i); + return dirName; } /** @@ -458,34 +489,34 @@ function dirname(pathname) { * @param dir name of the new directory */ function mkdir(dir) { - var dir = pathToFile(dir); - println(dir.mkdir()? "created" : "can not create dir"); + dir = pathToFile(dir); + println(dir.mkdir()? "created" : "can not create dir"); } /** - * Creates the directory named by given pathname, including + * Creates the directory named by given pathname, including * any necessary but nonexistent parent directories. * * @param dir input path name */ function mkdirs(dir) { - var dir = pathToFile(dir); - println(dir.mkdirs()? "created" : "can not create dirs"); + dir = pathToFile(dir); + println(dir.mkdirs()? "created" : "can not create dirs"); } - + /** - * Removes a given file + * Removes a given file * - * @param pathname name of the file + * @param pathname name of the file */ function rm(pathname) { - file = pathToFile(pathname); - if (!file.exists()) { - println("file not found: " + pathname); - return false; - } - // note that delete is a keyword in JavaScript! - println(file["delete"]()? "deleted" : "can not delete"); + var file = pathToFile(pathname); + if (!file.exists()) { + println("file not found: " + pathname); + return false; + } + // note that delete is a keyword in JavaScript! + println(file["delete"]()? "deleted" : "can not delete"); } /** @@ -494,14 +525,14 @@ function rm(pathname) { * @param pathname name of the directory */ function rmdir(pathname) { - rm(pathname); + rm(pathname); } /** * Synonym for 'rm' */ function del(pathname) { - rm(pathname); + rm(pathname); } /** @@ -511,62 +542,62 @@ function del(pathname) { * @param to new name for the file */ function mv(from, to) { - println(pathToFile(from).renameTo(pathToFile(to))? - "moved" : "can not move"); + println(pathToFile(from).renameTo(pathToFile(to))? + "moved" : "can not move"); } /** * Synonym for 'mv'. */ function ren(from, to) { - mv(from, to); + mv(from, to); } -var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; +var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; /** * Helper function called by ls * @private - */ + */ function printFile(f) { - var sb = new java.lang.StringBuffer(); - sb.append(f.isDirectory()? "d" : "-"); - sb.append(f.canRead() ? "r": "-" ); - sb.append(f.canWrite() ? "w": "-" ); - sb.append(" "); + var sb = new java.lang.StringBuffer(); + sb.append(f.isDirectory()? "d" : "-"); + sb.append(f.canRead() ? "r": "-" ); + sb.append(f.canWrite() ? "w": "-" ); + sb.append(" "); - var d = new java.util.Date(f.lastModified()); - var c = new java.util.GregorianCalendar(); - c.setTime(d); - var day = c.get(java.util.Calendar.DAY_OF_MONTH); - sb.append(months[c.get(java.util.Calendar.MONTH)] - + " " + day ); - if (day < 10) { - sb.append(" "); - } + var d = new java.util.Date(f.lastModified()); + var c = new java.util.GregorianCalendar(); + c.setTime(d); + var day = c.get(java.util.Calendar.DAY_OF_MONTH); + sb.append(months[c.get(java.util.Calendar.MONTH)] + + " " + day ); + if (day < 10) { + sb.append(" "); + } - // to get fixed length 'length' field - var fieldlen = 8; - var len = new java.lang.StringBuffer(); - for(var j=0; j * - * Examples: + * Examples: *
  * 
- *    find('.') 
- *    find('.', '.*\.class', rm);  // remove all .class files 
- *    find('.', '.*\.java');       // print fullpath of each .java file 
- *    find('.', '.*\.java', cat);  // print all .java files 
+ *    find('.')
+ *    find('.', '.*\.class', rm);  // remove all .class files
+ *    find('.', '.*\.java');       // print fullpath of each .java file
+ *    find('.', '.*\.java', cat);  // print all .java files
  * 
  * 
* @@ -637,23 +668,23 @@ function grep(pattern, files /*, one or more files */) { * @param callback function to call for matching files */ function find(dir, pattern, callback) { - dir = pathToFile(dir); - if (!callback) callback = print; - var files = dir.listFiles(); - for (var f in files) { - var file = files[f]; - if (file.isDirectory()) { - find(file, pattern, callback); - } else { - if (pattern) { - if (file.getName().match(pattern)) { - callback(file); - } - } else { - callback(file); - } - } - } + dir = pathToFile(dir); + if (!callback) callback = print; + var files = dir.listFiles(); + for (var f in files) { + var file = files[f]; + if (file.isDirectory()) { + find(file, pattern, callback); + } else { + if (pattern) { + if (file.getName().match(pattern)) { + callback(file); + } + } else { + callback(file); + } + } + } } // process utilities @@ -664,40 +695,44 @@ function find(dir, pattern, callback) { * @param cmd command to execute in child process */ function exec(cmd) { - var process = java.lang.Runtime.getRuntime().exec(cmd); - var inp = new DataInputStream(process.getInputStream()); - var line = null; - while ((line = inp.readLine()) != null) { - println(line); - } - process.waitFor(); - $exit = process.exitValue(); + var process = java.lang.Runtime.getRuntime().exec(cmd); + var inp = new DataInputStream(process.getInputStream()); + var line = null; + while ((line = inp.readLine()) != null) { + println(line); + } + process.waitFor(); + $exit = process.exitValue(); } -/** - * Exit the shell program. - * - * @param exitCode integer code returned to OS shell. - * optional, defaults to 0 - */ -function exit(code) { - if (code) { - java.lang.System.exit(code + 0); - } else { - java.lang.System.exit(0); - } +if (typeof(exit) == 'undefined') { + /** + * Exit the shell program. + * + * @param exitCode integer code returned to OS shell. + * optional, defaults to 0 + */ + var exit = function (code) { + if (code) { + java.lang.System.exit(code + 0); + } else { + java.lang.System.exit(0); + } + } } -/** - * synonym for exit - */ -function quit(code) { - exit(code); +if (typeof(quit) == 'undefined') { + /** + * synonym for exit + */ + var quit = function (code) { + exit(code); + } } // XML utilities -/** +/** * Converts input to DOM Document object * * @param inp file or reader. optional, without this param, @@ -705,17 +740,17 @@ function quit(code) { * @return returns a DOM Document object */ function XMLDocument(inp) { - var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); - var builder = factory.newDocumentBuilder(); - if (inp) { - if (typeof(inp) == "string") { - return builder.parse(pathToFile(inp)); - } else { - return builder.parse(inp); - } - } else { - return builder.newDocument(); - } + var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); + var builder = factory.newDocumentBuilder(); + if (inp) { + if (typeof(inp) == "string") { + return builder.parse(pathToFile(inp)); + } else { + return builder.parse(inp); + } + } else { + return builder.newDocument(); + } } /** @@ -725,14 +760,14 @@ function XMLDocument(inp) { * @return XMLSource object */ function XMLSource(inp) { - if (inp instanceof javax.xml.transform.Source) { - return inp; - } else if (inp instanceof Packages.org.w3c.dom.Document) { - return new javax.xml.transform.dom.DOMSource(inp); - } else { - inp = new BufferedInputStream(inStream(inp)); - return new javax.xml.transform.stream.StreamSource(inp); - } + if (inp instanceof javax.xml.transform.Source) { + return inp; + } else if (inp instanceof Packages.org.w3c.dom.Document) { + return new javax.xml.transform.dom.DOMSource(inp); + } else { + inp = new BufferedInputStream(inStream(inp)); + return new javax.xml.transform.stream.StreamSource(inp); + } } /** @@ -742,73 +777,73 @@ function XMLSource(inp) { * @return XMLResult object */ function XMLResult(out) { - if (out instanceof javax.xml.transform.Result) { - return out; - } else if (out instanceof Packages.org.w3c.dom.Document) { - return new javax.xml.transform.dom.DOMResult(out); - } else { - out = new BufferedOutputStream(outStream(out)); - return new javax.xml.transform.stream.StreamResult(out); - } + if (out instanceof javax.xml.transform.Result) { + return out; + } else if (out instanceof Packages.org.w3c.dom.Document) { + return new javax.xml.transform.dom.DOMResult(out); + } else { + out = new BufferedOutputStream(outStream(out)); + return new javax.xml.transform.stream.StreamResult(out); + } } /** - * Perform XSLT transform + * Perform XSLT transform * * @param inp Input XML to transform (URL, File or InputStream) * @param style XSL Stylesheet to be used (URL, File or InputStream). optional. * @param out Output XML (File or OutputStream */ function XSLTransform(inp, style, out) { - switch (arguments.length) { - case 2: - inp = arguments[0]; - out = arguments[1]; - break; - case 3: - inp = arguments[0]; - style = arguments[1]; - out = arguments[2]; - break; - default: - println("XSL tranform requires 2 or 3 arguments"); - return; - } + switch (arguments.length) { + case 2: + inp = arguments[0]; + out = arguments[1]; + break; + case 3: + inp = arguments[0]; + style = arguments[1]; + out = arguments[2]; + break; + default: + println("XSL tranform requires 2 or 3 arguments"); + return; + } - var factory = javax.xml.transform.TransformerFactory.newInstance(); - var tranformer; - if (style) { - transformer = factory.newTransformer(XMLSource(style)); - } else { - transformer = factory.newTransformer(); - } - var source = XMLSource(inp); - var result = XMLResult(out); - transformer.transform(source, result); - if (source.getInputStream) { - streamClose(source.getInputStream()); - } - if (result.getOutputStream) { - streamClose(result.getOutputStream()); - } + var factory = javax.xml.transform.TransformerFactory.newInstance(); + var transformer; + if (style) { + transformer = factory.newTransformer(XMLSource(style)); + } else { + transformer = factory.newTransformer(); + } + var source = XMLSource(inp); + var result = XMLResult(out); + transformer.transform(source, result); + if (source.getInputStream) { + streamClose(source.getInputStream()); + } + if (result.getOutputStream) { + streamClose(result.getOutputStream()); + } } // miscellaneous utilities /** - * Prints which command is selected from PATH + * Prints which command is selected from PATH * * @param cmd name of the command searched from PATH */ function which(cmd) { - var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator); - while (st.hasMoreTokens()) { - var file = new File(st.nextToken(), cmd); - if (file.exists()) { - println(file.getAbsolutePath()); - return; - } - } + var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator); + while (st.hasMoreTokens()) { + var file = new File(st.nextToken(), cmd); + if (file.exists()) { + println(file.getAbsolutePath()); + return; + } + } } /** @@ -817,41 +852,43 @@ function which(cmd) { * @param name domain name */ function ip(name) { - var addrs = InetAddress.getAllByName(name); - for (var i in addrs) { - println(addrs[i]); - } + var addrs = InetAddress.getAllByName(name); + for (var i in addrs) { + println(addrs[i]); + } } /** * Prints current date in current locale */ function date() { - println(new Date().toLocaleString()); + println(new Date().toLocaleString()); } /** * Echoes the given string arguments */ function echo(x) { - for (var i = 0; i < arguments.length; i++) { - println(arguments[i]); - } + for (var i = 0; i < arguments.length; i++) { + println(arguments[i]); + } } -/** - * This is C-like printf - * - * @param format string to format the rest of the print items - * @param args variadic argument list - */ -function printf(format, args/*, more args*/) { - var array = java.lang.reflect.Array.newInstance(java.lang.Object, - arguments.length - 1); - for (var i = 0; i < array.length; i++) { - array[i] = arguments[i+1]; - } - return java.lang.System.out.printf(format, array); +if (typeof(printf) == 'undefined') { + /** + * This is C-like printf + * + * @param format string to format the rest of the print items + * @param args variadic argument list + */ + var printf = function (format, args/*, more args*/) { + var array = java.lang.reflect.Array.newInstance(java.lang.Object, + arguments.length - 1); + for (var i = 0; i < array.length; i++) { + array[i] = arguments[i+1]; + } + java.lang.System.out.printf(format, array); + } } /** @@ -861,24 +898,48 @@ function printf(format, args/*, more args*/) { * @param multiline to tell whether to read single line or multiple lines */ function read(prompt, multiline) { - if (!prompt) { - prompt = '>'; - } - var inp = java.lang.System["in"]; - var reader = new BufferedReader(new InputStreamReader(inp)); - if (multiline) { - var line = ''; - while (true) { - java.lang.System.err.print(prompt); - java.lang.System.err.flush(); - var tmp = reader.readLine(); - if (tmp == '' || tmp == null) break; - line += tmp + '\n'; - } - return line; - } else { - java.lang.System.err.print(prompt); - java.lang.System.err.flush(); - return reader.readLine(); - } + if (!prompt) { + prompt = '>'; + } + var inp = java.lang.System["in"]; + var reader = new BufferedReader(new InputStreamReader(inp)); + if (multiline) { + var line = ''; + while (true) { + java.lang.System.err.print(prompt); + java.lang.System.err.flush(); + var tmp = reader.readLine(); + if (tmp == '' || tmp == null) break; + line += tmp + '\n'; + } + return line; + } else { + java.lang.System.err.print(prompt); + java.lang.System.err.flush(); + return reader.readLine(); + } +} + +if (typeof(println) == 'undefined') { + var print = function(str, newline) { + if (typeof(str) == 'undefined') { + str = 'undefined'; + } else if (str == null) { + str = 'null'; + } + + if (!(out instanceof java.io.PrintWriter)) { + out = new java.io.PrintWriter(out); + } + + out.print(String(str)); + if (newline) { + out.print('\n'); + } + out.flush(); + } + + var println = function(str) { + print(str, true); + }; } From 9aba745d56106c09cf0ae9c776dfd7980f010436 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 6 Mar 2013 16:59:42 +0400 Subject: [PATCH 002/137] 8009222: java.lang.IllegalArgumentException: not invocable, no method type when attempting to get getter method handle for a static field Reviewed-by: jrose, twisti --- .../java/lang/invoke/DirectMethodHandle.java | 3 +- .../java/lang/invoke/8009222/Test8009222.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/lang/invoke/8009222/Test8009222.java diff --git a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java index 7793bc2dd98..b9c10d827d2 100644 --- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -52,7 +52,8 @@ class DirectMethodHandle extends MethodHandle { super(mtype, form); if (!member.isResolved()) throw new InternalError(); - if (member.getDeclaringClass().isInterface() && !member.isAbstract()) { + if (member.getDeclaringClass().isInterface() && + member.isMethod() && !member.isAbstract()) { // Check for corner case: invokeinterface of Object method MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind()); m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null); diff --git a/jdk/test/java/lang/invoke/8009222/Test8009222.java b/jdk/test/java/lang/invoke/8009222/Test8009222.java new file mode 100644 index 00000000000..212e09a00cd --- /dev/null +++ b/jdk/test/java/lang/invoke/8009222/Test8009222.java @@ -0,0 +1,49 @@ +/* + * 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 8009222 + * @summary java.lang.IllegalArgumentException: not invocable, no method type + * when attempting to get getter method handle for a static field + * + * @run main/othervm Test8009222 + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +interface Intf { + static int i = 0; +} + +public class Test8009222 { + public static void main(String[] args) throws Exception { + MethodHandles.lookup() + .findStaticGetter(Intf.class, "i", int.class) + .getClass(); // null check + + System.out.println("TEST PASSED"); + } +} From bb6c34adc762828c5dcb2822e70b06cf8696b198 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 12 Mar 2013 18:12:42 +0530 Subject: [PATCH 003/137] 8009757: Package access clean up and refactoring Reviewed-by: jlaskey, lagergren, attila --- .../docs/JavaScriptingProgrammersGuide.html | 8 +-- nashorn/docs/source/javaarray.js | 3 +- nashorn/make/build.xml | 4 +- nashorn/make/java.security.override | 4 +- .../scripting/NashornScriptEngineFactory.java | 10 ++++ .../nashorn/api/scripting/ScriptUtils.java | 48 +++++++++++++++ .../jdk/nashorn/internal/objects/Global.java | 24 +++++++- .../nashorn/internal/objects/NativeDebug.java | 2 +- .../nashorn/internal/objects/NativeJava.java | 17 ++++++ .../jdk/nashorn/internal/runtime/Context.java | 25 ++++++-- .../internal/runtime/NashornLoader.java | 47 ++++++++++++++- .../internal/runtime/ScriptLoader.java | 7 ++- .../internal/runtime/StructureLoader.java | 3 +- .../internal/runtime/linker/Bootstrap.java | 2 +- .../runtime/linker/JavaAdapterFactory.java | 28 ++++++++- .../runtime/linker/ReflectionCheckLinker.java | 60 +++++++++++++++++++ .../runtime/resources/mozilla_compat.js | 18 +++--- .../internal/runtime/resources/parser.js | 10 ++-- nashorn/test/script/basic/JDK-8008448.js | 4 +- nashorn/test/script/basic/NASHORN-401.js | 2 +- nashorn/test/script/basic/consstring.js | 2 +- nashorn/test/script/basic/fileline.js | 4 +- nashorn/test/script/basic/javainnerclasses.js | 18 +++--- nashorn/test/script/basic/list.js | 2 +- nashorn/test/script/basic/map.js | 2 +- nashorn/test/script/basic/stdin.js | 6 +- nashorn/test/script/sandbox/javaextend.js | 2 +- .../script/sandbox/javaextend.js.EXPECTED | 6 +- nashorn/test/script/sandbox/reflection.js | 4 +- .../script/sandbox/reflection.js.EXPECTED | 1 - nashorn/test/script/sandbox/unsafe.js | 4 +- .../test/script/sandbox/unsafe.js.EXPECTED | 4 -- nashorn/test/script/trusted/urlreader.js | 6 +- .../api/scripting/ScriptEngineTest.java | 52 ---------------- .../runtime/TrustedScriptEngineTest.java | 31 +++++++++- .../test/models/ConstructorWithArgument.java | 2 +- .../test/models/DessertTopping.java | 2 +- .../models/DessertToppingFloorWaxDriver.java | 2 +- .../test/models/FinalClass.java | 2 +- .../{internal => }/test/models/FloorWax.java | 2 +- .../models}/Nashorn401TestSubject.java | 2 +- .../models/NoAccessibleConstructorClass.java | 2 +- .../test/models/NonPublicClass.java | 2 +- .../test/models/OuterClass.java | 2 +- .../test/models/OverloadedSam.java | 2 +- .../test/models/OverrideObject.java | 2 +- .../jdk/nashorn/test/models/SourceHelper.java | 55 +++++++++++++++++ .../test/models/StringArgs.java | 2 +- .../test/models/Toothpaste.java | 2 +- 49 files changed, 409 insertions(+), 142 deletions(-) create mode 100644 nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java delete mode 100644 nashorn/test/script/sandbox/reflection.js.EXPECTED delete mode 100644 nashorn/test/script/sandbox/unsafe.js.EXPECTED rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/ConstructorWithArgument.java (97%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/DessertTopping.java (96%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/DessertToppingFloorWaxDriver.java (97%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/FinalClass.java (96%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/FloorWax.java (96%) rename nashorn/test/src/jdk/nashorn/{internal/runtime => test/models}/Nashorn401TestSubject.java (97%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/NoAccessibleConstructorClass.java (96%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/NonPublicClass.java (96%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/OuterClass.java (98%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/OverloadedSam.java (96%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/OverrideObject.java (97%) create mode 100644 nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/StringArgs.java (97%) rename nashorn/test/src/jdk/nashorn/{internal => }/test/models/Toothpaste.java (97%) diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html index cf248140c15..dd243d3aa3c 100644 --- a/nashorn/docs/JavaScriptingProgrammersGuide.html +++ b/nashorn/docs/JavaScriptingProgrammersGuide.html @@ -533,9 +533,8 @@ with (SwingGui) {

Creating, Converting and Using Java Arrays

-

While creating a Java object is the same as in Java, to create -Java arrays in JavaScript we can use Java reflection -explicitly. But once created the element access or length access is +

+Array element access or length access is the same as in Java. Also, a script array can be used when a Java method expects a Java array (auto conversion). So in most cases we don't have to create Java arrays explicitly.

@@ -543,7 +542,8 @@ don't have to create Java arrays explicitly.

// javaarray.js // create Java String array of 5 elements -var a = java.lang.reflect.Array.newInstance(java.lang.String.class, 5); +var StringArray = Java.type("java.lang.String[]"); +var a = new StringArray(5); // Accessing elements and length access is by usual Java syntax a[0] = "scripting is great!"; diff --git a/nashorn/docs/source/javaarray.js b/nashorn/docs/source/javaarray.js index b9d93f0d42c..a02aa3ca9f6 100644 --- a/nashorn/docs/source/javaarray.js +++ b/nashorn/docs/source/javaarray.js @@ -30,7 +30,8 @@ */ // create Java String array of 5 elements -var a = java.lang.reflect.Array.newInstance(java.lang.String.class, 5); +var StringArray = Java.type("java.lang.String[]"); +var a = new StringArray(5); // Accessing elements and length access is by usual Java syntax a[0] = "scripting is great!"; diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 34f56e4602b..e2d8f0ccb31 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -191,12 +191,12 @@ - + - + diff --git a/nashorn/make/java.security.override b/nashorn/make/java.security.override index 0021985287e..a7edf33b5ee 100644 --- a/nashorn/make/java.security.override +++ b/nashorn/make/java.security.override @@ -3,7 +3,7 @@ # We ensure that by overriding "package.access" security property. # The following "package.access" value was copied from default java.security -# of jre/lib/security and appended with nashorn IR, Codegen and Parser packages. +# of jre/lib/security and appended with nashorn sensitive packages. # # List of comma-separated packages that start with or equal this string @@ -11,4 +11,4 @@ # passed to checkPackageAccess unless the # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. -package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.,jdk.nashorn.internal.ir., jdk.nashorn.internal.codegen., jdk.nashorn.internal.lookup., jdk.nashorn.internal.parser. +package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.,jdk.nashorn.internal.,jdk.nashorn.tools. diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java index 47a0c595236..4672f6a073e 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java @@ -147,6 +147,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { * @return newly created script engine. */ public ScriptEngine getScriptEngine(final ClassLoader appLoader) { + checkConfigPermission(); return new NashornScriptEngine(this, appLoader); } @@ -157,6 +158,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { * @return newly created script engine. */ public ScriptEngine getScriptEngine(final String[] args) { + checkConfigPermission(); return new NashornScriptEngine(this, args, getAppClassLoader()); } @@ -168,11 +170,19 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { * @return newly created script engine. */ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) { + checkConfigPermission(); return new NashornScriptEngine(this, args, appLoader); } // -- Internals only below this point + private void checkConfigPermission() { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new RuntimePermission("nashorn.setConfig")); + } + } + private static final List names; private static final List mimeTypes; private static final List extensions; diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java new file mode 100644 index 00000000000..63358bd7db9 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java @@ -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. 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.scripting; + +import jdk.nashorn.internal.runtime.ScriptRuntime; + +/** + * Utilities that are to be called from script code + */ +public final class ScriptUtils { + private ScriptUtils() {} + + /** + * Returns AST as JSON compatible string. This is used to + * implement "parse" function in resources/parse.js script. + * + * @param code code to be parsed + * @param name name of the code source (used for location) + * @param includeLoc tells whether to include location information for nodes or not + * @return JSON string representation of AST of the supplied code + */ + public static String parse(final String code, final String name, final boolean includeLoc) { + return ScriptRuntime.parse(code, name, includeLoc); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index b89d207344b..a9835f6fea9 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -34,6 +34,9 @@ import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.ref.SoftReference; +import java.lang.reflect.Field; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -1503,8 +1506,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value); // Nashorn extension: global.$OPTIONS (scripting-mode-only) - value = context.getEnv(); - addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, value); + final ScriptObject options = newEmptyInstance(); + final ScriptEnvironment scriptEnv = context.getEnv(); + copyOptions(options, scriptEnv); + addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options); // Nashorn extension: global.$ENV (scripting-mode-only) if (System.getSecurityManager() == null) { @@ -1523,6 +1528,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED); } + private void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + for (Field f : scriptEnv.getClass().getFields()) { + try { + options.set(f.getName(), f.get(scriptEnv), false); + } catch (final IllegalArgumentException | IllegalAccessException exp) { + throw new RuntimeException(exp); + } + } + return null; + } + }); + } + private void initTypedArray() { this.builtinArrayBuffer = initConstructor("ArrayBuffer"); this.builtinInt8Array = initConstructor("Int8Array"); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java index 3d6fcbc8e7a..8188f426f23 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java @@ -66,7 +66,7 @@ public final class NativeDebug extends ScriptObject { public static Object getContext(final Object self) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission("getNashornContext")); + sm.checkPermission(new RuntimePermission("nashorn.getContext")); } return Global.getThisContext(); } diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java index fc16962e185..2519c0284fd 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java @@ -222,6 +222,23 @@ public final class NativeJava { return simpleType(typeName); } + /** + * Returns name of a java type {@link StaticClass}. + * @param self not used + * @param type the type whose name is returned + * @return name of the given type + */ + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) + public static Object typeName(final Object self, final Object type) { + if (type instanceof StaticClass) { + return ((StaticClass)type).getRepresentedClass().getName(); + } else if (type instanceof Class) { + return ((Class)type).getName(); + } else { + return UNDEFINED; + } + } + /** * Given a JavaScript array and a Java type, returns a Java array with the same initial contents, and with the * specified component type. Example: diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 1c4a08c843b..516c0a79892 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -39,10 +39,13 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; +import java.security.AccessControlContext; import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; +import java.security.Permissions; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; import jdk.nashorn.internal.codegen.Compiler; @@ -123,7 +126,7 @@ public final class Context { if (callerLoader != myLoader && !(callerLoader instanceof StructureLoader) && !(JavaAdapterFactory.isAdapterClass(caller))) { - sm.checkPermission(new RuntimePermission("getNashornGlobal")); + sm.checkPermission(new RuntimePermission("nashorn.getGlobal")); } } @@ -137,7 +140,7 @@ public final class Context { public static void setGlobal(final ScriptObject global) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission("setNashornGlobal")); + sm.checkPermission(new RuntimePermission("nashorn.setGlobal")); } if (global != null && !(global instanceof GlobalObject)) { @@ -154,7 +157,7 @@ public final class Context { public static Context getContext() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission("getNashornContext")); + sm.checkPermission(new RuntimePermission("nashorn.getContext")); } return getContextTrusted(); } @@ -267,7 +270,7 @@ public final class Context { public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission("createNashornContext")); + sm.checkPermission(new RuntimePermission("nashorn.createContext")); } this.env = new ScriptEnvironment(options, out, err); @@ -533,7 +536,13 @@ public final class Context { if (index != -1) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPackageAccess(fullName.substring(0, index)); + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + sm.checkPackageAccess(fullName.substring(0, index)); + return null; + } + }, createNoPermissionsContext()); } } @@ -599,7 +608,7 @@ public final class Context { public ScriptObject newGlobal() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission("createNashornGlobal")); + sm.checkPermission(new RuntimePermission("nashorn.newGlobal")); } return newGlobalTrusted(); @@ -676,6 +685,10 @@ public final class Context { return (context != null) ? context : Context.getContextTrusted(); } + private static AccessControlContext createNoPermissionsContext() { + return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); + } + private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { ScriptFunction script = null; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java index 80a0b8e6ef1..5ce31008088 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java @@ -30,6 +30,10 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; import java.security.SecureClassLoader; import jdk.nashorn.tools.Shell; @@ -40,6 +44,28 @@ import jdk.nashorn.tools.Shell; * */ abstract class NashornLoader extends SecureClassLoader { + private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; + private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime"; + private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker"; + private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts"; + + private static final Permission[] SCRIPT_PERMISSIONS; + static { + SCRIPT_PERMISSIONS = new Permission[4]; + + /* + * Generated classes get access to runtime, runtime.linker, objects, scripts packages. + * Note that the actual scripts can not access these because Java.type, Packages + * prevent these restricted packages. And Java reflection and JSR292 access is prevented + * for scripts. In other words, nashorn generated portions of script classes can access + * clases in these implementation packages. + */ + SCRIPT_PERMISSIONS[0] = new RuntimePermission("accessClassInPackage." + RUNTIME_PKG); + SCRIPT_PERMISSIONS[1] = new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG); + SCRIPT_PERMISSIONS[2] = new RuntimePermission("accessClassInPackage." + OBJECTS_PKG); + SCRIPT_PERMISSIONS[3] = new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG); + } + private final Context context; final Context getContext() { @@ -68,11 +94,30 @@ abstract class NashornLoader extends SecureClassLoader { if (i != -1) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPackageAccess(name.substring(0, i)); + final String pkgName = name.substring(0, i); + switch (pkgName) { + case RUNTIME_PKG: + case RUNTIME_LINKER_PKG: + case OBJECTS_PKG: + case SCRIPTS_PKG: + // allow it. + break; + default: + sm.checkPackageAccess(pkgName); + } } } } + @Override + protected PermissionCollection getPermissions(CodeSource codesource) { + final Permissions permCollection = new Permissions(); + for (final Permission perm : SCRIPT_PERMISSIONS) { + permCollection.add(perm); + } + return permCollection; + } + /** * Create a secure URL class loader for the given classpath * @param classPath classpath for the loader to search from diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java index d632166270a..adecd8a3cbe 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.runtime; import java.security.CodeSource; +import java.security.ProtectionDomain; /** * Responsible for loading script generated classes. @@ -57,6 +58,10 @@ final class ScriptLoader extends NashornLoader { * @return Installed class. */ synchronized Class installClass(final String name, final byte[] data, final CodeSource cs) { - return defineClass(name, data, 0, data.length, cs); + if (cs == null) { + return defineClass(name, data, 0, data.length, new ProtectionDomain(null, getPermissions(null))); + } else { + return defineClass(name, data, 0, data.length, cs); + } } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java index da64655f9a5..35786b0b85f 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java @@ -38,6 +38,7 @@ import java.security.CodeSigner; import java.security.CodeSource; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; +import java.security.ProtectionDomain; import jdk.nashorn.internal.codegen.ObjectClassGenerator; /** @@ -129,6 +130,6 @@ final class StructureLoader extends NashornLoader { } final byte[] code = new ObjectClassGenerator(context).generate(descriptor); - return defineClass(name, code, 0, code.length); + return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null))); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index 3c5e2d81b51..6b55656ba17 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -57,7 +57,7 @@ public final class Bootstrap { static { final DynamicLinkerFactory factory = new DynamicLinkerFactory(); factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(), - new JSObjectLinker()); + new JSObjectLinker(), new ReflectionCheckLinker()); factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker()); factory.setSyncOnRelink(true); final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java index a9e4bd01469..ba599da1a98 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java @@ -54,6 +54,7 @@ import java.security.CodeSigner; import java.security.CodeSource; import java.security.Permissions; import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.security.SecureClassLoader; import java.security.SecureRandom; @@ -410,9 +411,13 @@ public final class JavaAdapterFactory { */ public static MethodHandle getConstructor(final Class sourceType, final Class targetType) throws Exception { final StaticClass adapterClass = getAdapterClassFor(new Class[] { targetType }); - return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get( - "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false, - adapterClass, null)).getInvocation(), adapterClass); + return AccessController.doPrivileged(new PrivilegedExceptionAction() { + public MethodHandle run() throws Exception { + return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get( + "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false, + adapterClass, null)).getInvocation(), adapterClass); + } + }); } /** @@ -456,8 +461,25 @@ public final class JavaAdapterFactory { private static ClassLoader createClassLoader(final ClassLoader parentLoader, final String className, final byte[] classBytes, final String privilegedActionClassName) { return new AdapterLoader(parentLoader) { + private final ClassLoader myLoader = getClass().getClassLoader(); private final ProtectionDomain myProtectionDomain = getClass().getProtectionDomain(); + @Override + public Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { + try { + return super.loadClass(name, resolve); + } catch (final SecurityException se) { + // we may be implementing an interface or extending a class that was + // loaded by a loader that prevents package.access. If so, it'd throw + // SecurityException for nashorn's classes!. For adapter's to work, we + // should be able to refer to nashorn classes. + if (name.startsWith("jdk.nashorn.internal.")) { + return myLoader.loadClass(name); + } + throw se; + } + } + @Override protected Class findClass(final String name) throws ClassNotFoundException { if(name.equals(className)) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java new file mode 100644 index 00000000000..eb8837a8d70 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java @@ -0,0 +1,60 @@ +/* + * 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.runtime.linker; + +import jdk.internal.dynalink.linker.GuardedInvocation; +import jdk.internal.dynalink.linker.LinkRequest; +import jdk.internal.dynalink.linker.LinkerServices; +import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; + +/** + * Check java reflection permission for java reflective and java.lang.invoke access from scripts + */ +final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{ + @Override + public boolean canLinkType(final Class type) { + return canLinkTypeStatic(type); + } + + private static boolean canLinkTypeStatic(final Class type) { + if (type == Class.class || ClassLoader.class.isAssignableFrom(type)) { + return true; + } + final String name = type.getName(); + return name.startsWith("java.lang.reflect.") || name.startsWith("java.lang.invoke."); + } + + @Override + public GuardedInvocation getGuardedInvocation(final LinkRequest origRequest, final LinkerServices linkerServices) + throws Exception { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new RuntimePermission("nashorn.JavaReflection")); + } + // let the next linker deal with actual linking + return null; + } +} 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 15c67f9419b..0b967d69a8d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -1,21 +1,21 @@ /* * 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. @@ -34,7 +34,7 @@ Object.defineProperty(this, "JavaAdapter", { if (arguments.length < 2) { throw new TypeError("JavaAdapter requires atleast two arguments"); } - + var types = Array.prototype.slice.call(arguments, 0, arguments.length - 1); var NewType = Java.extend.apply(Java, types); return new NewType(arguments[arguments.length - 1]); @@ -56,10 +56,10 @@ Object.defineProperty(this, "importPackage", { return type; } catch (e) {} } - + return oldNoSuchProperty? oldNoSuchProperty(name) : undefined; } - + var prefix = "[JavaPackage "; return function() { for (var i in arguments) { @@ -343,7 +343,9 @@ Object.defineProperty(this, "importClass", { configurable: true, enumerable: false, writable: true, value: function(clazz) { if (Java.isType(clazz)) { - this[clazz.class.getSimpleName()] = 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/src/jdk/nashorn/internal/runtime/resources/parser.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js index b89f7e12873..8671d365902 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js @@ -1,21 +1,21 @@ /* * 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. @@ -47,7 +47,7 @@ function parse(/*code, [name], [location]*/) { code = arguments[0]; } - var jsonStr = Packages.jdk.nashorn.internal.runtime.ScriptRuntime.parse(code, name, location); + var jsonStr = Packages.jdk.nashorn.api.scripting.ScriptUtils.parse(code, name, location); return JSON.parse(jsonStr, function (prop, value) { if (typeof(value) == 'string' && prop == "value") { diff --git a/nashorn/test/script/basic/JDK-8008448.js b/nashorn/test/script/basic/JDK-8008448.js index d5ffbd4c729..b30e3417b54 100644 --- a/nashorn/test/script/basic/JDK-8008448.js +++ b/nashorn/test/script/basic/JDK-8008448.js @@ -32,7 +32,7 @@ var File = Java.type("java.io.File"); var FilenameFilter = Java.type("java.io.FilenameFilter"); -var Source = Java.type("jdk.nashorn.internal.runtime.Source") +var SourceHelper = Java.type("jdk.nashorn.test.models.SourceHelper") // Filter out non .js files var files = new File(__DIR__).listFiles(new FilenameFilter() { @@ -44,5 +44,5 @@ load("nashorn:parser.js"); // parse each file to make sure it does not result in exception for each (var f in files) { - parse(new Source(f.toString(), f).getString()); + parse(SourceHelper.readFully(f)); } diff --git a/nashorn/test/script/basic/NASHORN-401.js b/nashorn/test/script/basic/NASHORN-401.js index b6058a9bdc1..6a663e1a178 100644 --- a/nashorn/test/script/basic/NASHORN-401.js +++ b/nashorn/test/script/basic/NASHORN-401.js @@ -28,7 +28,7 @@ * @run */ -var t = new Packages.jdk.nashorn.internal.runtime.Nashorn401TestSubject(); +var t = new Packages.jdk.nashorn.test.models.Nashorn401TestSubject(); print(t.method2(10)); print(t.method2(10.2)); diff --git a/nashorn/test/script/basic/consstring.js b/nashorn/test/script/basic/consstring.js index b8dc51d88f5..0cc8b1f8c17 100644 --- a/nashorn/test/script/basic/consstring.js +++ b/nashorn/test/script/basic/consstring.js @@ -37,4 +37,4 @@ list.add(String(new String(str + "2"))); // String() called as function with list.add((str + "3").toString()); // toString() called on primitive string list.add(new String(str + "4").toString()); // toString() called on String object -Packages.jdk.nashorn.internal.test.models.StringArgs.checkString(list); +Packages.jdk.nashorn.test.models.StringArgs.checkString(list); diff --git a/nashorn/test/script/basic/fileline.js b/nashorn/test/script/basic/fileline.js index 3323a12640e..ccf879b2454 100644 --- a/nashorn/test/script/basic/fileline.js +++ b/nashorn/test/script/basic/fileline.js @@ -41,8 +41,8 @@ print(file + " : " + __LINE__); load(__DIR__ + "loadedfile.js"); // Add check for base part of a URL. We can't test __DIR__ inside -// a script that is downloaded from a URL. check for Source.baseURL +// a script that is downloaded from a URL. check for SourceHelper.baseURL // which is exposed as __DIR__ for URL case. var url = new java.net.URL("http://www.acme.com:8080/foo/bar.js"); -print(Packages.jdk.nashorn.internal.runtime.Source.baseURL(url)); +print(Packages.jdk.nashorn.test.models.SourceHelper.baseURL(url)); diff --git a/nashorn/test/script/basic/javainnerclasses.js b/nashorn/test/script/basic/javainnerclasses.js index df1e74df191..c84571d718f 100644 --- a/nashorn/test/script/basic/javainnerclasses.js +++ b/nashorn/test/script/basic/javainnerclasses.js @@ -29,25 +29,25 @@ */ // Do it with Java.type() -var outer = new (Java.type("jdk.nashorn.internal.test.models.OuterClass"))("apple") +var outer = new (Java.type("jdk.nashorn.test.models.OuterClass"))("apple") print(outer) -var innerStatic = new (Java.type("jdk.nashorn.internal.test.models.OuterClass$InnerStaticClass"))("orange") +var innerStatic = new (Java.type("jdk.nashorn.test.models.OuterClass$InnerStaticClass"))("orange") print(innerStatic) -var innerNonStatic = new (Java.type("jdk.nashorn.internal.test.models.OuterClass$InnerNonStaticClass"))(outer, "pear") +var innerNonStatic = new (Java.type("jdk.nashorn.test.models.OuterClass$InnerNonStaticClass"))(outer, "pear") print(innerNonStatic) // Now do it with Packages and explicit $ names -var outer = new Packages.jdk.nashorn.internal.test.models.OuterClass("red") +var outer = new Packages.jdk.nashorn.test.models.OuterClass("red") print(outer) -var innerStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass$InnerStaticClass("green") +var innerStatic = new Packages.jdk.nashorn.test.models.OuterClass$InnerStaticClass("green") print(innerStatic) -var innerNonStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass$InnerNonStaticClass(outer, "blue") +var innerNonStatic = new Packages.jdk.nashorn.test.models.OuterClass$InnerNonStaticClass(outer, "blue") print(innerNonStatic) // Now do it with Packages and nested properties -var outer = new Packages.jdk.nashorn.internal.test.models.OuterClass("sweet") +var outer = new Packages.jdk.nashorn.test.models.OuterClass("sweet") print(outer) -var innerStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass.InnerStaticClass("sour") +var innerStatic = new Packages.jdk.nashorn.test.models.OuterClass.InnerStaticClass("sour") print(innerStatic) -var innerNonStatic = new Packages.jdk.nashorn.internal.test.models.OuterClass.InnerNonStaticClass(outer, "bitter") +var innerNonStatic = new Packages.jdk.nashorn.test.models.OuterClass.InnerNonStaticClass(outer, "bitter") print(innerNonStatic) diff --git a/nashorn/test/script/basic/list.js b/nashorn/test/script/basic/list.js index 12e4071b6aa..72ae0be7617 100644 --- a/nashorn/test/script/basic/list.js +++ b/nashorn/test/script/basic/list.js @@ -28,7 +28,7 @@ * @run */ var l = new java.util.ArrayList(); -print("l.class.name=" + l.class.name) // Has "class" property like any POJO +print("l.class.name=" + Java.typeName(l.class)) // Has "class" property like any POJO l.add("foo") l.add("bar") diff --git a/nashorn/test/script/basic/map.js b/nashorn/test/script/basic/map.js index 2ab27aba9cb..c024f6eb17a 100644 --- a/nashorn/test/script/basic/map.js +++ b/nashorn/test/script/basic/map.js @@ -28,7 +28,7 @@ * @run */ var m = new (Java.type("java.util.LinkedHashMap")); -print("m.class.name=" + m.class.name) // Has "class" property like any POJO +print("m.class.name=" + Java.typeName(m.class)) // Has "class" property like any POJO var empty_key = "empty" diff --git a/nashorn/test/script/basic/stdin.js b/nashorn/test/script/basic/stdin.js index ba546d5967f..a3a93324be2 100644 --- a/nashorn/test/script/basic/stdin.js +++ b/nashorn/test/script/basic/stdin.js @@ -28,8 +28,8 @@ * @run */ -print(java.lang.System.in.class.name); +print(Java.typeName(java.lang.System.in.class)); var prop = "in"; -print(java.lang.System[prop].class.name); -print(java.lang.System["in"].class.name); +print(Java.typeName(java.lang.System[prop].class)); +print(Java.typeName(java.lang.System["in"].class)); diff --git a/nashorn/test/script/sandbox/javaextend.js b/nashorn/test/script/sandbox/javaextend.js index 318a679417f..33cc6b01fa0 100644 --- a/nashorn/test/script/sandbox/javaextend.js +++ b/nashorn/test/script/sandbox/javaextend.js @@ -27,7 +27,7 @@ */ function model(n) { - return Java.type("jdk.nashorn.internal.test.models." + n) + return Java.type("jdk.nashorn.test.models." + n) } // Can't extend a final class diff --git a/nashorn/test/script/sandbox/javaextend.js.EXPECTED b/nashorn/test/script/sandbox/javaextend.js.EXPECTED index 2a5ad63a5e1..69c7818929c 100644 --- a/nashorn/test/script/sandbox/javaextend.js.EXPECTED +++ b/nashorn/test/script/sandbox/javaextend.js.EXPECTED @@ -1,6 +1,6 @@ -TypeError: Can not extend final class jdk.nashorn.internal.test.models.FinalClass. -TypeError: Can not extend class jdk.nashorn.internal.test.models.NoAccessibleConstructorClass as it has no public or protected constructors. -TypeError: Can not extend/implement non-public class/interface jdk.nashorn.internal.test.models.NonPublicClass. +TypeError: Can not extend final class jdk.nashorn.test.models.FinalClass. +TypeError: Can not extend class jdk.nashorn.test.models.NoAccessibleConstructorClass as it has no public or protected constructors. +TypeError: Can not extend/implement non-public class/interface jdk.nashorn.test.models.NonPublicClass. TypeError: Can not extend multiple classes java.lang.Number and java.lang.Thread. At most one of the specified types can be a class, the rest must all be interfaces. abcdabcd run-object diff --git a/nashorn/test/script/sandbox/reflection.js b/nashorn/test/script/sandbox/reflection.js index 7364879ddd9..e892c646d44 100644 --- a/nashorn/test/script/sandbox/reflection.js +++ b/nashorn/test/script/sandbox/reflection.js @@ -30,9 +30,7 @@ */ function check(e) { - if (e instanceof java.lang.SecurityException) { - print(e); - } else { + if (! (e instanceof java.lang.SecurityException)) { fail("expected SecurityException, got " + e); } } diff --git a/nashorn/test/script/sandbox/reflection.js.EXPECTED b/nashorn/test/script/sandbox/reflection.js.EXPECTED deleted file mode 100644 index 202333ead8a..00000000000 --- a/nashorn/test/script/sandbox/reflection.js.EXPECTED +++ /dev/null @@ -1 +0,0 @@ -java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers") diff --git a/nashorn/test/script/sandbox/unsafe.js b/nashorn/test/script/sandbox/unsafe.js index b273cd0b709..6b3f43af6a5 100644 --- a/nashorn/test/script/sandbox/unsafe.js +++ b/nashorn/test/script/sandbox/unsafe.js @@ -30,9 +30,7 @@ */ function check(e) { - if (e instanceof java.lang.SecurityException) { - print(e); - } else { + if (! (e instanceof java.lang.SecurityException)) { fail("expected SecurityException, got " + e); } } diff --git a/nashorn/test/script/sandbox/unsafe.js.EXPECTED b/nashorn/test/script/sandbox/unsafe.js.EXPECTED deleted file mode 100644 index 3f1cbec0a80..00000000000 --- a/nashorn/test/script/sandbox/unsafe.js.EXPECTED +++ /dev/null @@ -1,4 +0,0 @@ -java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.misc") -java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.misc") -java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun") -java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader") diff --git a/nashorn/test/script/trusted/urlreader.js b/nashorn/test/script/trusted/urlreader.js index a5e06ee5328..ca037306df6 100644 --- a/nashorn/test/script/trusted/urlreader.js +++ b/nashorn/test/script/trusted/urlreader.js @@ -9,7 +9,7 @@ var URLReader = Java.type("jdk.nashorn.api.scripting.URLReader"); var URL = Java.type("java.net.URL"); var File = Java.type("java.io.File"); var JString = Java.type("java.lang.String"); -var Source = Java.type("jdk.nashorn.internal.runtime.Source"); +var SourceHelper = Java.type("jdk.nashorn.test.models.SourceHelper"); var url = new File(__FILE__).toURI().toURL(); var reader = new URLReader(url); @@ -19,9 +19,9 @@ var reader = new URLReader(url); // check URL read // read URL content by directly reading from URL -var str = new Source(url.toString(), url).getString(); +var str = SourceHelper.readFully(url); // read URL content via URLReader -var content = new JString(Source.readFully(reader)); +var content = new JString(SourceHelper.readFully(reader)); // assert that the content is same Assert.assertEquals(str, content); diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index f4fd114fa89..0994b0d26ca 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -47,7 +47,6 @@ import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; -import jdk.nashorn.internal.runtime.Version; import netscape.javascript.JSObject; import org.testng.Assert; import org.testng.annotations.Test; @@ -129,7 +128,6 @@ public class ScriptEngineTest { assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); assertEquals(fac.getEngineName(), "Oracle Nashorn"); - assertEquals(fac.getEngineVersion(), Version.version()); assertEquals(fac.getOutputStatement("context"), "print(context)"); assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');"); assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); @@ -313,27 +311,6 @@ public class ScriptEngineTest { } } - public static void alert(final Object msg) { - System.out.println(msg); - } - - @Test - public void exposeMethodTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - final Method alert = ScriptEngineTest.class.getMethod("alert", Object.class); - // expose a Method object as global var. - e.put("alert", alert); - // call the global var. - e.eval("alert.invoke(null, 'alert! alert!!')"); - } catch (final NoSuchMethodException | SecurityException | ScriptException exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - @Test public void putGlobalFunctionTest() { final ScriptEngineManager m = new ScriptEngineManager(); @@ -592,13 +569,6 @@ public class ScriptEngineTest { } } - @Test - public void versionTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - assertEquals(e.getFactory().getEngineVersion(), Version.version()); - } - @Test public void noEnumerablePropertiesTest() { final ScriptEngineManager m = new ScriptEngineManager(); @@ -874,26 +844,4 @@ public class ScriptEngineTest { fail(se.getMessage()); } } - - @Test - public void factoryOptionsTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - // specify --no-syntax-extensions flag - final String[] options = new String[] { "--no-syntax-extensions" }; - final ScriptEngine e = nfac.getScriptEngine(options); - try { - // try nashorn specific extension - e.eval("var f = funtion(x) 2*x;"); - fail("should have thrown exception!"); - } catch (final ScriptException se) { - } - return; - } - } - - fail("Cannot find nashorn factory!"); - } } diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java index 0f147562fea..0f740a483c6 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java @@ -25,7 +25,7 @@ package jdk.nashorn.internal.runtime; - +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -40,6 +40,13 @@ import org.testng.annotations.Test; * Tests for trusted client usage of nashorn script engine factory extension API */ public class TrustedScriptEngineTest { + @Test + public void versionTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + assertEquals(e.getFactory().getEngineVersion(), Version.version()); + } + private static class MyClassLoader extends ClassLoader { // to check if script engine uses the specified class loader private final boolean[] reached = new boolean[1]; @@ -116,4 +123,26 @@ public class TrustedScriptEngineTest { fail("Cannot find nashorn factory!"); } + + @Test + public void factoryOptionsTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + // specify --no-syntax-extensions flag + final String[] options = new String[] { "--no-syntax-extensions" }; + final ScriptEngine e = nfac.getScriptEngine(options); + try { + // try nashorn specific extension + e.eval("var f = funtion(x) 2*x;"); + fail("should have thrown exception!"); + } catch (final ScriptException se) { + } + return; + } + } + + fail("Cannot find nashorn factory!"); + } } diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java b/nashorn/test/src/jdk/nashorn/test/models/ConstructorWithArgument.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java rename to nashorn/test/src/jdk/nashorn/test/models/ConstructorWithArgument.java index ba4a21637d0..9a201575aa5 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java +++ b/nashorn/test/src/jdk/nashorn/test/models/ConstructorWithArgument.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public abstract class ConstructorWithArgument { private final String token; diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java b/nashorn/test/src/jdk/nashorn/test/models/DessertTopping.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java rename to nashorn/test/src/jdk/nashorn/test/models/DessertTopping.java index 8427c837548..591e032d147 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertTopping.java +++ b/nashorn/test/src/jdk/nashorn/test/models/DessertTopping.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public interface DessertTopping { public String pourOnDessert(); diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java b/nashorn/test/src/jdk/nashorn/test/models/DessertToppingFloorWaxDriver.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java rename to nashorn/test/src/jdk/nashorn/test/models/DessertToppingFloorWaxDriver.java index dc04a0d1059..856029add5f 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/DessertToppingFloorWaxDriver.java +++ b/nashorn/test/src/jdk/nashorn/test/models/DessertToppingFloorWaxDriver.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public class DessertToppingFloorWaxDriver { public void decorateDessert(DessertTopping dt) { diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java b/nashorn/test/src/jdk/nashorn/test/models/FinalClass.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java rename to nashorn/test/src/jdk/nashorn/test/models/FinalClass.java index b20257cb81c..8a3e8432b2b 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java +++ b/nashorn/test/src/jdk/nashorn/test/models/FinalClass.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public final class FinalClass { //empty diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java b/nashorn/test/src/jdk/nashorn/test/models/FloorWax.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java rename to nashorn/test/src/jdk/nashorn/test/models/FloorWax.java index c094ccf65a1..44ac96e90cb 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/FloorWax.java +++ b/nashorn/test/src/jdk/nashorn/test/models/FloorWax.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public interface FloorWax { public String shineUpTheFloor(); diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java b/nashorn/test/src/jdk/nashorn/test/models/Nashorn401TestSubject.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java rename to nashorn/test/src/jdk/nashorn/test/models/Nashorn401TestSubject.java index ed6475de942..2e7d9c6c8ae 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java +++ b/nashorn/test/src/jdk/nashorn/test/models/Nashorn401TestSubject.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.runtime; +package jdk.nashorn.test.models; public class Nashorn401TestSubject { public String method2(int arg) { diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java b/nashorn/test/src/jdk/nashorn/test/models/NoAccessibleConstructorClass.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java rename to nashorn/test/src/jdk/nashorn/test/models/NoAccessibleConstructorClass.java index c79edfbb96e..f0ddb1aab62 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java +++ b/nashorn/test/src/jdk/nashorn/test/models/NoAccessibleConstructorClass.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public class NoAccessibleConstructorClass { NoAccessibleConstructorClass() { } diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java b/nashorn/test/src/jdk/nashorn/test/models/NonPublicClass.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java rename to nashorn/test/src/jdk/nashorn/test/models/NonPublicClass.java index 046cdf244ab..d0a61856c38 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java +++ b/nashorn/test/src/jdk/nashorn/test/models/NonPublicClass.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; class NonPublicClass { public NonPublicClass() { } diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java b/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java similarity index 98% rename from nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java rename to nashorn/test/src/jdk/nashorn/test/models/OuterClass.java index cb9484b94ca..5db86f28c1b 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java +++ b/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public class OuterClass { private final String value; diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSam.java similarity index 96% rename from nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java rename to nashorn/test/src/jdk/nashorn/test/models/OverloadedSam.java index c63da54c2b8..05736bcab3a 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java +++ b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSam.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public interface OverloadedSam { public void sam(String s); diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java b/nashorn/test/src/jdk/nashorn/test/models/OverrideObject.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java rename to nashorn/test/src/jdk/nashorn/test/models/OverrideObject.java index 40cf7f97a6e..5312ffbb0f9 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java +++ b/nashorn/test/src/jdk/nashorn/test/models/OverrideObject.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public class OverrideObject { @Override diff --git a/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java b/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java new file mode 100644 index 00000000000..46b1e488170 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/test/models/SourceHelper.java @@ -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. 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.test.models; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.net.URL; +import jdk.nashorn.internal.runtime.Source; + +/** + * Helper class to facilitate script access of nashorn Source class. + */ +public final class SourceHelper { + private SourceHelper() {} + + public static String baseURL(final URL url) { + return Source.baseURL(url); + } + + public static String readFully(final File file) throws IOException { + return new String(Source.readFully(file)); + } + + public static String readFully(final URL url) throws IOException { + return new Source(url.toString(), url).getString(); + } + + public static String readFully(final Reader reader) throws IOException { + return new String(Source.readFully(reader)); + } +} diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java b/nashorn/test/src/jdk/nashorn/test/models/StringArgs.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java rename to nashorn/test/src/jdk/nashorn/test/models/StringArgs.java index 8ecdbfd3a4b..1fdcd5dedb5 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/StringArgs.java +++ b/nashorn/test/src/jdk/nashorn/test/models/StringArgs.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; import java.util.List; diff --git a/nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java b/nashorn/test/src/jdk/nashorn/test/models/Toothpaste.java similarity index 97% rename from nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java rename to nashorn/test/src/jdk/nashorn/test/models/Toothpaste.java index 0946eb35078..7eae95f33e6 100644 --- a/nashorn/test/src/jdk/nashorn/internal/test/models/Toothpaste.java +++ b/nashorn/test/src/jdk/nashorn/test/models/Toothpaste.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.nashorn.internal.test.models; +package jdk.nashorn.test.models; public abstract class Toothpaste { public void applyToBrush() { From 1af08ef100641385501f65459f0c90c5c88f45f4 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Tue, 12 Mar 2013 15:30:53 +0100 Subject: [PATCH 004/137] 8009718: Lazy execution architecture continued - ScriptFunctionData is either final or recompilable. Moved ScriptFunctionData creation logic away from runtime to compile time. Prepared for method generation/specialization. Got rid of ScriptFunctionImplTrampoline whose semantics could be done as part of the relinking anyway. Merge with the lookup package change Reviewed-by: attila, jlaskey --- .../jdk/nashorn/internal/codegen/Attr.java | 143 ++- .../internal/codegen/BranchOptimizer.java | 1 - .../internal/codegen/CodeGenerator.java | 47 +- .../internal/codegen/CompilationPhase.java | 51 +- .../nashorn/internal/codegen/CompileUnit.java | 20 + .../nashorn/internal/codegen/Compiler.java | 181 ++- .../internal/codegen/FinalizeTypes.java | 14 +- .../internal/codegen/FoldConstants.java | 16 + .../internal/codegen/FunctionSignature.java | 10 +- .../jdk/nashorn/internal/codegen/Lower.java | 5 +- .../nashorn/internal/codegen/Splitter.java | 10 +- .../nashorn/internal/codegen/types/Type.java | 15 +- .../src/jdk/nashorn/internal/ir/Block.java | 19 +- .../jdk/nashorn/internal/ir/FunctionNode.java | 50 +- .../jdk/nashorn/internal/ir/ObjectNode.java | 21 +- .../jdk/nashorn/internal/ir/UnaryNode.java | 6 +- .../internal/ir/annotations/ChildNode.java | 42 - .../internal/ir/annotations/ParentNode.java | 44 - .../internal/ir/annotations/Reference.java | 1 - .../nashorn/internal/ir/debug/ASTWriter.java | 38 +- .../nashorn/internal/objects/NativeArray.java | 4 +- .../nashorn/internal/objects/NativeDebug.java | 15 - .../nashorn/internal/objects/NativeError.java | 2 +- .../internal/objects/ScriptFunctionImpl.java | 11 +- .../objects/ScriptFunctionTrampolineImpl.java | 122 -- .../nashorn/internal/parser/JSONParser.java | 2 +- .../jdk/nashorn/internal/parser/Parser.java | 200 ++-- .../internal/runtime/AccessorProperty.java | 4 +- .../internal/runtime/CodeInstaller.java | 6 +- .../internal/runtime/CompiledFunction.java | 162 +++ .../internal/runtime/CompiledFunctions.java | 73 ++ .../jdk/nashorn/internal/runtime/Context.java | 2 +- .../internal/runtime/ECMAException.java | 2 +- .../runtime/FinalScriptFunctionData.java | 100 ++ .../RecompilableScriptFunctionData.java | 185 +++ .../internal/runtime/ScriptEnvironment.java | 4 + .../internal/runtime/ScriptFunction.java | 115 +- .../internal/runtime/ScriptFunctionData.java | 1019 +++++++---------- .../runtime/SpecializedMethodChooser.java | 99 -- .../linker/JavaArgumentConverters.java | 2 +- .../runtime/linker/NashornGuards.java | 39 - .../runtime/options/OptionTemplate.java | 2 +- .../runtime/resources/Options.properties | 6 + .../script/currently-failing/JDK-8006529.js | 13 +- .../test/script/currently-failing/clone_ir.js | 100 ++ 45 files changed, 1658 insertions(+), 1365 deletions(-) delete mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java delete mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java delete mode 100644 nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java create mode 100644 nashorn/test/script/currently-failing/clone_ir.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 211140e4123..a441ef4d94c 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -42,6 +42,7 @@ import static jdk.nashorn.internal.ir.Symbol.IS_VAR; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -51,6 +52,7 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CallNode.EvalArgs; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.ForNode; @@ -332,8 +334,14 @@ final class Attr extends NodeOperatorVisitor { functionNode.setNeedsSelfSymbol(functionNode.getSelfSymbolInit().accept(this)); } + if (functionNode.hasLazyChildren()) { + objectifySymbols(functionNode); + } + functionNode.popFrame(); + functionNode.setState(CompilationState.ATTR); + end(functionNode, false); return null; @@ -957,20 +965,17 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveBIT_AND(final BinaryNode binaryNode) { - newTemporary(Type.INT, binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.INT)); } @Override public Node leaveBIT_OR(final BinaryNode binaryNode) { - newTemporary(Type.INT, binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.INT)); } @Override public Node leaveBIT_XOR(final BinaryNode binaryNode) { - newTemporary(Type.INT, binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.INT)); } @Override @@ -1002,14 +1007,28 @@ final class Attr extends NodeOperatorVisitor { return binaryNode; } + private Node coerce(final BinaryNode binaryNode, final Type operandType, final Type destType) { + // TODO we currently don't support changing inferred type based on uses, only on + // definitions. we would need some additional logic. We probably want to do that + // in the future, if e.g. a specialized method gets parameter that is only used + // as, say, an int : function(x) { return x & 4711 }, and x is not defined in + // the function. to make this work, uncomment the following two type inferences + // and debug. + + //newType(binaryNode.lhs().getSymbol(), operandType); + //newType(binaryNode.rhs().getSymbol(), operandType); + newTemporary(destType, binaryNode); + return binaryNode; + } + + private Node coerce(final BinaryNode binaryNode, final Type type) { + return coerce(binaryNode, type, type); + } + //leave a binary node and inherit the widest type of lhs , rhs private Node leaveBinaryArithmetic(final BinaryNode binaryNode) { - if (!Compiler.shouldUseIntegerArithmetic()) { - newTemporary(Type.NUMBER, binaryNode); - return binaryNode; - } - newTemporary(Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType(), Type.NUMBER), binaryNode); - return binaryNode; + assert !Compiler.shouldUseIntegerArithmetic(); + return end(coerce(binaryNode, Type.NUMBER)); } @Override @@ -1089,23 +1108,17 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveSAR(final BinaryNode binaryNode) { - newTemporary(Type.INT, binaryNode); - end(binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.INT)); } @Override public Node leaveSHL(final BinaryNode binaryNode) { - newTemporary(Type.INT, binaryNode); - end(binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.INT)); } @Override public Node leaveSHR(final BinaryNode binaryNode) { - newTemporary(Type.LONG, binaryNode); - end(binaryNode); - return binaryNode; + return end(coerce(binaryNode, Type.LONG)); } @Override @@ -1211,11 +1224,17 @@ final class Attr extends NodeOperatorVisitor { // type or its parameters with the widest (OBJECT) type for safety. functionNode.setReturnType(Type.UNKNOWN); - for (final IdentNode ident : functionNode.getParameters()) { - addLocalDef(ident.getName()); - final Symbol paramSymbol = functionNode.defineSymbol(ident.getName(), IS_PARAM, ident); + for (final IdentNode param : functionNode.getParameters()) { + addLocalDef(param.getName()); + final Symbol paramSymbol = functionNode.defineSymbol(param.getName(), IS_PARAM, param); if (paramSymbol != null) { - newType(paramSymbol, Type.UNKNOWN); + final Type callSiteParamType = functionNode.getSpecializedType(param); + if (callSiteParamType != null) { + LOG.info("Param " + paramSymbol + " has a callsite type " + callSiteParamType + ". Using that."); + + System.err.println("Param " + param + " has a callsite type " + callSiteParamType + ". Using that."); + } + newType(paramSymbol, callSiteParamType == null ? Type.UNKNOWN : callSiteParamType); } LOG.info("Initialized param " + paramSymbol); @@ -1229,36 +1248,29 @@ final class Attr extends NodeOperatorVisitor { * @param functionNode functionNode */ private static void finalizeParameters(final FunctionNode functionNode) { - boolean nonObjectParams = false; - List paramSpecializations = new ArrayList<>(); + final boolean isVarArg = functionNode.isVarArg(); for (final IdentNode ident : functionNode.getParameters()) { final Symbol paramSymbol = ident.getSymbol(); - if (paramSymbol != null) { - Type type = paramSymbol.getSymbolType(); - if (type.isUnknown()) { - type = Type.OBJECT; - } - paramSpecializations.add(type); - if (!type.isObject()) { - nonObjectParams = true; - } - newType(paramSymbol, Type.OBJECT); + + assert paramSymbol != null; + Type type = functionNode.getSpecializedType(ident); + if (type == null) { + type = Type.OBJECT; } - } - if (!nonObjectParams) { - paramSpecializations = null; - // Later, when resolving a call to this method, the linker can say "I have a double, an int and an object" as parameters - // here. If the callee has parameter specializations, we can regenerate it with those particular types for speed. - } else { - LOG.info("parameter specialization possible: " + functionNode.getName() + " " + paramSpecializations); - } + // if we know that a parameter is only used as a certain type throughout + // this function, we can tell the runtime system that no matter what the + // call site is, use this information. TODO + if (!paramSymbol.getSymbolType().isObject()) { + LOG.finest("Parameter " + ident + " could profit from specialization to " + paramSymbol.getSymbolType()); + } - // parameters should not be slots for a function that uses variable arity signature - if (functionNode.isVarArg()) { - for (final IdentNode param : functionNode.getParameters()) { - param.getSymbol().setNeedsSlot(false); + newType(paramSymbol, Type.widest(type, paramSymbol.getSymbolType())); + + // parameters should not be slots for a function that uses variable arity signature + if (isVarArg) { + paramSymbol.setNeedsSlot(false); } } } @@ -1548,6 +1560,39 @@ final class Attr extends NodeOperatorVisitor { localUses.add(name); } + /** + * Pessimistically promote all symbols in current function node to Object types + * This is done when the function contains unevaluated black boxes such as + * lazy sub-function nodes that have not been compiled. + * + * @param functionNode function node in whose scope symbols should conservatively be made objects + */ + private static void objectifySymbols(final FunctionNode functionNode) { + functionNode.accept(new NodeVisitor() { + private void toObject(final Block block) { + for (final Iterator iter = block.symbolIterator(); iter.hasNext();) { + final Symbol symbol = iter.next(); + newType(symbol, Type.OBJECT); + } + } + + @Override + public Node enter(final Block block) { + toObject(block); + return block; + } + + @Override + public Node enter(final FunctionNode node) { + toObject(node); + if (node.isLazy()) { + return null; + } + return node; + } + }); + } + private static String name(final Node node) { final String cn = node.getClass().getName(); int lastDot = cn.lastIndexOf('.'); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java index 84cef43764a..ee922115d15 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -32,7 +32,6 @@ import static jdk.nashorn.internal.codegen.Condition.LE; import static jdk.nashorn.internal.codegen.Condition.LT; import static jdk.nashorn.internal.codegen.Condition.NE; -import jdk.nashorn.internal.codegen.Label; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Node; diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 2ffb5bd887d..71a2eb0fe1e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -25,10 +25,8 @@ package jdk.nashorn.internal.codegen; -import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.HANDLE_STATIC; import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE; import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC; -import static jdk.nashorn.internal.codegen.CompilerConstants.ALLOCATE; import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; import static jdk.nashorn.internal.codegen.CompilerConstants.LEAF; @@ -50,7 +48,6 @@ import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALL import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT; import java.io.PrintWriter; -import java.lang.invoke.MethodHandle; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; @@ -84,6 +81,7 @@ import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.LineNumberNode; import jdk.nashorn.internal.ir.LiteralNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; import jdk.nashorn.internal.ir.Node; @@ -108,14 +106,13 @@ import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Lexer.RegexToken; import jdk.nashorn.internal.parser.TokenType; -import jdk.nashorn.internal.runtime.CodeInstaller; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.Scope; import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptFunctionData; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.Source; @@ -149,8 +146,6 @@ final class CodeGenerator extends NodeOperatorVisitor { /** Name of the ScriptFunctionImpl, cannot be referred to as .class @see FunctionObjectCreator */ private static final String SCRIPTFUNCTION_IMPL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionImpl"; - private static final String SCRIPTFUNCTION_TRAMPOLINE_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionTrampolineImpl"; - /** Constant data & installation. The only reason the compiler keeps this is because it is assigned * by reflection in class installation */ private final Compiler compiler; @@ -982,6 +977,7 @@ final class CodeGenerator extends NodeOperatorVisitor { method.label(functionNode.getEntryLabel()); initLocals(functionNode); + functionNode.setState(CompilationState.EMITTED); return functionNode; } @@ -3234,42 +3230,23 @@ final class CodeGenerator extends NodeOperatorVisitor { } private void newFunctionObject(final FunctionNode functionNode) { - final boolean isLazy = functionNode.isLazy(); - final Class[] cparams = new Class[] { ScriptFunctionData.class, ScriptObject.class, MethodHandle.class }; + final boolean isLazy = functionNode.isLazy(); + final Class[] cparams = new Class[] { RecompilableScriptFunctionData.class, ScriptObject.class }; new ObjectCreator(this, new ArrayList(), new ArrayList(), false, false) { @Override - protected void makeObject(final MethodEmitter method) { - final String className = isLazy ? SCRIPTFUNCTION_TRAMPOLINE_OBJECT : SCRIPTFUNCTION_IMPL_OBJECT; + protected void makeObject(final MethodEmitter m) { + final String className = SCRIPTFUNCTION_IMPL_OBJECT; - method._new(className).dup(); - if (isLazy) { - loadConstant(compiler.getCodeInstaller()); - loadConstant(functionNode); - } else { - final String signature = new FunctionSignature(true, functionNode.needsCallee(), functionNode.getReturnType(), functionNode.isVarArg() ? null : functionNode.getParameters()).toString(); - method.loadHandle(functionNode.getCompileUnit().getUnitClassName(), functionNode.getName(), signature, EnumSet.of(HANDLE_STATIC)); // function - } - loadConstant(new ScriptFunctionData(functionNode, makeMap())); + m._new(className).dup(); + loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), Compiler.binaryName(getClassName()), makeMap())); if (isLazy || functionNode.needsParentScope()) { - method.loadScope(); + m.loadScope(); } else { - method.loadNull(); + m.loadNull(); } - - method.loadHandle(getClassName(), ALLOCATE.tag(), methodDescriptor(ScriptObject.class, PropertyMap.class), EnumSet.of(HANDLE_STATIC)); - - final List> cparamList = new ArrayList<>(); - if (isLazy) { - cparamList.add(CodeInstaller.class); - cparamList.add(FunctionNode.class); - } else { - cparamList.add(MethodHandle.class); - } - cparamList.addAll(Arrays.asList(cparams)); - - method.invoke(constructorNoLookup(className, cparamList.toArray(new Class[cparamList.size()]))); + m.invoke(constructorNoLookup(className, cparams)); } }.makeObject(method); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java index e22454cc459..0125efff65e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java @@ -2,10 +2,10 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.ATTR; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED; -import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.EMITTED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED; +import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.PARSED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT; import java.io.File; @@ -39,7 +39,7 @@ enum CompilationPhase { * default policy. The will get trampolines and only be generated when * called */ - LAZY_INITIALIZATION_PHASE(EnumSet.of(FunctionNode.CompilationState.INITIALIZED)) { + LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { @@ -79,9 +79,11 @@ enum CompilationPhase { if (node == outermostFunctionNode) { return node; } - assert Compiler.LAZY_JIT; + assert compiler.isLazy(); lazy.add(node); + //also needs scope, potentially needs arguments etc etc + return node; } }); @@ -113,7 +115,7 @@ enum CompilationPhase { * Constant folding pass * Simple constant folding that will make elementary constructs go away */ - CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED), CONSTANT_FOLDED) { + CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { fn.accept(new FoldConstants()); @@ -134,7 +136,7 @@ enum CompilationPhase { * as runtime nodes where applicable. * */ - LOWERING_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED), LOWERED) { + LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { fn.accept(new Lower()); @@ -150,19 +152,10 @@ enum CompilationPhase { * Attribution * Assign symbols and types to all nodes. */ - ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED), ATTR) { + ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { - final ScriptEnvironment env = compiler.getEnv(); - fn.accept(new Attr()); - if (env._print_lower_ast) { - env.getErr().println(new ASTWriter(fn)); - } - - if (env._print_lower_parse) { - env.getErr().println(new PrintVisitor(fn)); - } } @Override @@ -178,7 +171,7 @@ enum CompilationPhase { * a + b a ScriptRuntime.ADD with call overhead or a dadd with much * less). Split IR can lead to scope information being changed. */ - SPLITTING_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR), SPLIT) { + SPLITTING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName()); @@ -212,10 +205,20 @@ enum CompilationPhase { * Contract: all variables must have slot assignments and scope assignments * before type finalization. */ - TYPE_FINALIZATION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT), FINALIZED) { + TYPE_FINALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { + final ScriptEnvironment env = compiler.getEnv(); + fn.accept(new FinalizeTypes()); + + if (env._print_lower_ast) { + env.getErr().println(new ASTWriter(fn)); + } + + if (env._print_lower_parse) { + env.getErr().println(new PrintVisitor(fn)); + } } @Override @@ -229,7 +232,7 @@ enum CompilationPhase { * * Generate the byte code class(es) resulting from the compiled FunctionNode */ - BYTECODE_GENERATION_PHASE(EnumSet.of(INITIALIZED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT, FINALIZED), EMITTED) { + BYTECODE_GENERATION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR, SPLIT, FINALIZED)) { @Override void transform(final Compiler compiler, final FunctionNode fn) { final ScriptEnvironment env = compiler.getEnv(); @@ -306,18 +309,12 @@ enum CompilationPhase { }; private final EnumSet pre; - private final CompilationState post; private long startTime; private long endTime; private boolean isFinished; private CompilationPhase(final EnumSet pre) { - this(pre, null); - } - - private CompilationPhase(final EnumSet pre, final CompilationState post) { - this.pre = pre; - this.post = post; + this.pre = pre; } boolean isApplicable(final FunctionNode functionNode) { @@ -343,10 +340,6 @@ enum CompilationPhase { endTime = System.currentTimeMillis(); Timing.accumulateTime(toString(), endTime - startTime); - if (post != null) { - functionNode.setState(post); - } - isFinished = true; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java index 5e62116b9a1..ff88fa9986a 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java @@ -37,6 +37,8 @@ public class CompileUnit { private long weight; + private Class clazz; + CompileUnit(final String className, final ClassEmitter classEmitter) { this(className, classEmitter, 0L); } @@ -47,6 +49,24 @@ public class CompileUnit { this.weight = initialWeight; } + /** + * Return the class that contains the code for this unit, null if not + * generated yet + * + * @return class with compile unit code + */ + public Class getCode() { + return clazz; + } + + /** + * Set class when it exists. Only accessible from compiler + * @param clazz class with code for this compile unit + */ + void setCode(final Class clazz) { + this.clazz = clazz; + } + /** * Add weight to this compile unit * @param w weight to add diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index ca23c42809e..a799ee0506f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -45,11 +45,15 @@ import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +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.Node; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.CodeInstaller; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ScriptEnvironment; @@ -71,8 +75,6 @@ public final class Compiler { /** Name of the objects package */ public static final String OBJECTS_PACKAGE = "jdk/nashorn/internal/objects"; - static final boolean LAZY_JIT = Options.getBooleanProperty("nashorn.compiler.lazy"); - private final Map bytecode; private final Set compileUnits; @@ -164,7 +166,7 @@ public final class Compiler { * and JIT it at once. This can lead to long startup time and fewer type * specializations */ - final static CompilationSequence SEQUENCE_NORMAL = new CompilationSequence( + final static CompilationSequence SEQUENCE_EAGER = new CompilationSequence( CompilationPhase.CONSTANT_FOLDING_PHASE, CompilationPhase.LOWERING_PHASE, CompilationPhase.ATTRIBUTION_PHASE, @@ -173,12 +175,15 @@ public final class Compiler { CompilationPhase.BYTECODE_GENERATION_PHASE); final static CompilationSequence SEQUENCE_LAZY = - SEQUENCE_NORMAL.insertFirst(CompilationPhase.LAZY_INITIALIZATION_PHASE); + SEQUENCE_EAGER.insertFirst(CompilationPhase.LAZY_INITIALIZATION_PHASE); - final static CompilationSequence SEQUENCE_DEFAULT = - LAZY_JIT ? - SEQUENCE_LAZY : - SEQUENCE_NORMAL; + private static CompilationSequence sequence(final boolean lazy) { + return lazy ? SEQUENCE_LAZY : SEQUENCE_EAGER; + } + + boolean isLazy() { + return sequence == SEQUENCE_LAZY; + } private static String lazyTag(final FunctionNode functionNode) { if (functionNode.isLazy()) { @@ -213,10 +218,7 @@ public final class Compiler { this.scriptName = sb.toString(); - LOG.info("Initializing compiler for '" + functionNode.getName() + "' scriptName = " + scriptName + ", root function: '" + functionNode.getName() + "'"); - if (functionNode.isLazy()) { - LOG.info(">>> This is a lazy recompilation triggered by a trampoline"); - } + LOG.info("Initializing compiler for '" + functionNode.getName() + "' scriptName = " + scriptName + ", root function: '" + functionNode.getName() + "' lazy=" + functionNode.isLazy()); } /** @@ -227,7 +229,7 @@ public final class Compiler { * @param strict should this compilation use strict mode semantics */ public Compiler(final CodeInstaller installer, final FunctionNode functionNode, final boolean strict) { - this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, strict); + this(installer.getOwner(), installer, functionNode, sequence(installer.getOwner()._lazy_compilation), strict); } /** @@ -237,7 +239,7 @@ public final class Compiler { * @param functionNode function node (in any available {@link CompilationState}) to compile */ public Compiler(final CodeInstaller installer, final FunctionNode functionNode) { - this(installer.getOwner(), installer, functionNode, SEQUENCE_DEFAULT, installer.getOwner()._strict); + this(installer.getOwner(), installer, functionNode, sequence(installer.getOwner()._lazy_compilation), installer.getOwner()._strict); } /** @@ -247,28 +249,104 @@ public final class Compiler { * @param functionNode functionNode to compile */ public Compiler(final ScriptEnvironment env, final FunctionNode functionNode) { - this(env, null, functionNode, SEQUENCE_DEFAULT, env._strict); + this(env, null, functionNode, sequence(env._lazy_compilation), env._strict); } /** * Execute the compilation this Compiler was created with + * @params param types if known, for specialization * @throws CompilationException if something goes wrong + * @return this compiler, for possible chaining */ - public void compile() throws CompilationException { + public Compiler compile() throws CompilationException { + return compile(null); + } + + /** + * Execute the compilation this Compiler was created with + * @param paramTypes param types if known, for specialization + * @throws CompilationException if something goes wrong + * @return this compiler, for possible chaining + */ + public Compiler compile(final Class paramTypes) throws CompilationException { for (final String reservedName : RESERVED_NAMES) { functionNode.uniqueName(reservedName); } + final boolean fine = !LOG.levelAbove(Level.FINE); + final boolean info = !LOG.levelAbove(Level.INFO); + + long time = 0L; + for (final CompilationPhase phase : sequence) { phase.apply(this, functionNode); - final String end = phase.toString() + " done for function '" + functionNode.getName() + "'"; - if (Timing.isEnabled()) { - final long duration = phase.getEndTime() - phase.getStartTime(); - LOG.info(end + " in " + duration + " ms"); - } else { - LOG.info(end); + + final long duration = Timing.isEnabled() ? (phase.getEndTime() - phase.getStartTime()) : 0L; + time += duration; + + if (fine) { + final StringBuilder sb = new StringBuilder(); + + sb.append(phase.toString()). + append(" done for function '"). + append(functionNode.getName()). + append('\''); + + if (duration > 0L) { + sb.append(" in "). + append(duration). + append(" ms "); + } + + LOG.fine(sb.toString()); } } + + if (info) { + final StringBuilder sb = new StringBuilder(); + sb.append("Compile job for '"). + append(functionNode.getName()). + append("' finished"); + + if (time > 0L) { + sb.append(" in "). + append(time). + append(" ms"); + } + + LOG.info(sb.toString()); + } + + return this; + } + + private Class install(final String className, final byte[] code) { + LOG.fine("Installing class " + className); + + final Class clazz = installer.install(Compiler.binaryName(className), code); + + try { + final Source source = getSource(); + final Object[] constants = getConstantData().toArray(); + // Need doPrivileged because these fields are private + AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Void run() throws Exception { + //use reflection to write source and constants table to installed classes + final Field sourceField = clazz.getDeclaredField(SOURCE.tag()); + final Field constantsField = clazz.getDeclaredField(CONSTANTS.tag()); + sourceField.setAccessible(true); + constantsField.setAccessible(true); + sourceField.set(null, source); + constantsField.set(null, constants); + return null; + } + }); + } catch (final PrivilegedActionException e) { + throw new RuntimeException(e); + } + + return clazz; } /** @@ -280,42 +358,38 @@ public final class Compiler { assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed"; - Class rootClass = null; + final Map> installedClasses = new HashMap<>(); + + final String rootClassName = firstCompileUnitName(); + final Class rootClass = install(rootClassName, bytecode.get(rootClassName)); + + installedClasses.put(rootClassName, rootClass); for (final Entry entry : bytecode.entrySet()) { - final String className = entry.getKey(); - LOG.fine("Installing class " + className); - - final byte[] code = entry.getValue(); - final Class clazz = installer.install(Compiler.binaryName(className), code); - - if (rootClass == null && firstCompileUnitName().equals(className)) { - rootClass = clazz; - } - - try { - final Source source = getSource(); - final Object[] constants = getConstantData().toArray(); - // Need doPrivileged because these fields are private - AccessController.doPrivileged(new PrivilegedExceptionAction() { - @Override - public Void run() throws Exception { - //use reflection to write source and constants table to installed classes - final Field sourceField = clazz.getDeclaredField(SOURCE.tag()); - final Field constantsField = clazz.getDeclaredField(CONSTANTS.tag()); - sourceField.setAccessible(true); - constantsField.setAccessible(true); - sourceField.set(null, source); - constantsField.set(null, constants); - return null; - } - }); - } catch (final PrivilegedActionException e) { - throw new RuntimeException(e); + final String className = entry.getKey(); + if (className.equals(rootClassName)) { + continue; } + installedClasses.put(className, install(className, entry.getValue())); } + for (final CompileUnit unit : compileUnits) { + unit.setCode(installedClasses.get(unit.getUnitClassName())); + } + + functionNode.accept(new NodeVisitor() { + @Override + public Node enter(final FunctionNode node) { + if (node.isLazy()) { + return null; + } + node.setState(CompilationState.INSTALLED); + return node; + } + }); + LOG.info("Installed root class: " + rootClass + " and " + bytecode.size() + " compile unit classes"); + if (Timing.isEnabled()) { final long duration = System.currentTimeMillis() - t0; Timing.accumulateTime("[Code Installation]", duration); @@ -444,8 +518,6 @@ public final class Compiler { * TODO: We currently generate no overflow checks so this is * disabled * - * @see #shouldUseIntegers() - * * @return true if arithmetic operations should not widen integer * operands by default. */ @@ -460,4 +532,5 @@ public final class Compiler { assert !USE_INT_ARITH : "Integer arithmetic is not enabled"; } + } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java index 28dfda7da9a..b302d6fe470 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java @@ -34,6 +34,7 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CallNode.EvalArgs; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.DoWhileNode; @@ -235,19 +236,19 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveBIT_AND(BinaryNode binaryNode) { - assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : binaryNode.getSymbol(); + assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); return leaveBinary(binaryNode, Type.INT, Type.INT); } @Override public Node leaveBIT_OR(BinaryNode binaryNode) { - assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger(); + assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); return leaveBinary(binaryNode, Type.INT, Type.INT); } @Override public Node leaveBIT_XOR(BinaryNode binaryNode) { - assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger(); + assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); return leaveBinary(binaryNode, Type.INT, Type.INT); } @@ -255,7 +256,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { public Node leaveCOMMALEFT(final BinaryNode binaryNode) { assert binaryNode.getSymbol() != null; binaryNode.setRHS(discard(binaryNode.rhs())); - // AccessSpecializer - the type of rhs, which is the remaining value of this node may have changed + // 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 propagateType(binaryNode, binaryNode.lhs().getType()); return binaryNode; @@ -344,7 +345,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveSHR(final BinaryNode binaryNode) { - assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isLong(); + assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isLong() : "long coercion expected: " + binaryNode.getSymbol(); return leaveBinary(binaryNode, Type.INT, Type.INT); } @@ -432,6 +433,8 @@ final class FinalizeTypes extends NodeOperatorVisitor { } updateSymbols(functionNode); + functionNode.setState(CompilationState.FINALIZED); + return functionNode; } @@ -511,7 +514,6 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leave(final VarNode varNode) { - final Node rhs = varNode.getInit(); if (rhs != null) { Type destType = specialize(varNode); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java index 4ea53a04351..af2b02ab706 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java @@ -30,11 +30,13 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; +import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.TernaryNode; import jdk.nashorn.internal.ir.UnaryNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.JSType; @@ -71,6 +73,20 @@ final class FoldConstants extends NodeVisitor { return binaryNode; } + @Override + public Node enter(final FunctionNode functionNode) { + if (functionNode.isLazy()) { + return null; + } + return functionNode; + } + + @Override + public Node leave(final FunctionNode functionNode) { + functionNode.setState(CompilationState.CONSTANT_FOLDED); + return functionNode; + } + @Override public Node leave(final IfNode ifNode) { final Node test = ifNode.getTest(); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java index ded12b0c007..5f3740a7240 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java @@ -146,7 +146,7 @@ public final class FunctionSignature { /** * Create a function signature given a function node, using as much - * type information for parameters and return types that is availabe + * type information for parameters and return types that is available * * @param functionNode the function node */ @@ -202,6 +202,14 @@ public final class FunctionSignature { return methodType; } + /** + * Return the return type for this function signature + * @return the return type + */ + public Type getReturnType() { + return returnType; + } + private static Type[] objectArgs(final int nArgs) { final Type[] array = new Type[nArgs]; for (int i = 0; i < nArgs; i++) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index 7a83469bc98..4be28193cc7 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -69,6 +69,7 @@ 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.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Token; @@ -332,6 +333,8 @@ final class Lower extends NodeOperatorVisitor { LOG.info("END FunctionNode: " + functionNode.getName()); unnest(functionNode); + functionNode.setState(CompilationState.LOWERED); + return null; } @@ -636,7 +639,7 @@ final class Lower extends NodeOperatorVisitor { } else if (conservativeAlwaysTrue(test)) { node = new ForNode(whileNode.getSource(), whileNode.getToken(), whileNode.getFinish()); ((ForNode)node).setBody(body); - ((ForNode)node).accept(this); + node.accept(this); setTerminal(node, !escapes); } } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java index b92f2383b3a..b338ced5f47 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java @@ -39,6 +39,7 @@ import jdk.nashorn.internal.ir.ContinueNode; import jdk.nashorn.internal.ir.DoWhileNode; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.LabelNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; @@ -92,15 +93,16 @@ final class Splitter extends NodeVisitor { */ void split() { if (functionNode.isLazy()) { - LOG.fine("Postponing split of '" + functionNode.getName() + "' as it's lazy"); + LOG.finest("Postponing split of '" + functionNode.getName() + "' as it's lazy"); return; } - LOG.fine("Initiating split of '" + functionNode.getName() + "'"); + + LOG.finest("Initiating split of '" + functionNode.getName() + "'"); long weight = WeighNodes.weigh(functionNode); if (weight >= SPLIT_THRESHOLD) { - LOG.fine("Splitting '" + functionNode.getName() + "' as its weight " + weight + " exceeds split threshold " + SPLIT_THRESHOLD); + LOG.finest("Splitting '" + functionNode.getName() + "' as its weight " + weight + " exceeds split threshold " + SPLIT_THRESHOLD); functionNode.accept(this); @@ -133,6 +135,8 @@ final class Splitter extends NodeVisitor { for (final FunctionNode function : functionNode.getFunctions()) { new Splitter(compiler, function, outermostCompileUnit).split(); } + + functionNode.setState(CompilationState.SPLIT); } /** diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java index d36dd20db34..775588352f4 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java @@ -647,21 +647,20 @@ public abstract class Type implements Comparable, BytecodeOps { } private static void swap(final MethodVisitor method, final Type above, final Type below) { - final MethodVisitor mv = method; if (below.isCategory2()) { if (above.isCategory2()) { - mv.visitInsn(DUP2_X2); - mv.visitInsn(POP2); + method.visitInsn(DUP2_X2); + method.visitInsn(POP2); } else { - mv.visitInsn(DUP_X2); - mv.visitInsn(POP); + method.visitInsn(DUP_X2); + method.visitInsn(POP); } } else { if (above.isCategory2()) { - mv.visitInsn(DUP2_X1); - mv.visitInsn(POP2); + method.visitInsn(DUP2_X1); + method.visitInsn(POP2); } else { - mv.visitInsn(SWAP); + method.visitInsn(SWAP); } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk/nashorn/internal/ir/Block.java index 9449be5b0a5..e729d307b8c 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Block.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java @@ -38,26 +38,25 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import jdk.nashorn.internal.codegen.Frame; import jdk.nashorn.internal.codegen.Label; -import jdk.nashorn.internal.ir.annotations.Ignore; -import jdk.nashorn.internal.ir.annotations.ParentNode; +import jdk.nashorn.internal.ir.annotations.Reference; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.Source; /** * IR representation for a list of statements and functions. All provides the * basis for script body. - * */ public class Block extends Node { /** Parent context */ - @ParentNode @Ignore + @Reference private Block parent; - /** Owning function. */ - @Ignore //don't print it, it is apparent in the tree + /** Owning function - a FunctionNode has itself as function */ + @Reference protected FunctionNode function; /** List of statements */ @@ -273,6 +272,14 @@ public class Block extends Node { return this; } + /** + * Get an iterator for all the symbols defined in this block + * @return symbol iterator + */ + public Iterator symbolIterator() { + return symbols.values().iterator(); + } + /** * Search for symbol. * diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java index d928aa71529..63590932d44 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -33,8 +33,10 @@ import static jdk.nashorn.internal.ir.Symbol.IS_TEMP; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Stack; import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.Compiler; @@ -45,13 +47,13 @@ import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Parser; +import jdk.nashorn.internal.runtime.Debug; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.UserAccessorProperty; import jdk.nashorn.internal.runtime.linker.LinkerCallSite; /** * IR representation for function (or script.) - * */ public class FunctionNode extends Block { @@ -86,7 +88,9 @@ public class FunctionNode extends Block { /** method has had its types finalized */ FINALIZED, /** method has been emitted to bytecode */ - EMITTED + EMITTED, + /** code installed in a class loader */ + INSTALLED } /** External function identifier. */ @@ -173,6 +177,9 @@ public class FunctionNode extends Block { @Ignore private final EnumSet compilationState; + /** Type hints, e.g based on parameters at call site */ + private final Map specializedTypes; + /** Function flags. */ private int flags; @@ -256,22 +263,27 @@ public class FunctionNode extends Block { // constructed, so it can't be seen from other threads. this.function = this; this.compilationState = EnumSet.of(CompilationState.INITIALIZED); + this.specializedTypes = new HashMap<>(); } @SuppressWarnings("LeakingThisInConstructor") private FunctionNode(final FunctionNode functionNode, final CopyState cs) { super(functionNode, cs); + this.functions = new ArrayList<>(); + for (final FunctionNode f : functionNode.getFunctions()) { + this.functions.add((FunctionNode)cs.existingOrCopy(f)); + } + this.ident = (IdentNode)cs.existingOrCopy(functionNode.ident); this.name = functionNode.name; this.kind = functionNode.kind; this.parameters = new ArrayList<>(); for (final IdentNode param : functionNode.getParameters()) { - this.parameters.add((IdentNode) cs.existingOrCopy(param)); + this.parameters.add((IdentNode)cs.existingOrCopy(param)); } - this.functions = new ArrayList<>(); this.firstToken = functionNode.firstToken; this.lastToken = functionNode.lastToken; this.namespace = functionNode.getNamespace(); @@ -300,6 +312,7 @@ public class FunctionNode extends Block { this.function = this; this.compilationState = EnumSet.copyOf(functionNode.compilationState); + this.specializedTypes = new HashMap<>(); } @Override @@ -710,10 +723,14 @@ public class FunctionNode extends Block { * Check if this function's generated Java method needs a {@code callee} parameter. Functions that need access to * their parent scope, functions that reference themselves, and non-strict functions that need an Arguments object * (since it exposes {@code arguments.callee} property) will need to have a callee parameter. + * + * We also conservatively need a callee if we have lazy children, i.e. nested function nodes that have not yet + * been evaluated. _They_ may need the callee and we don't know it + * * @return true if the function's generated Java method needs a {@code callee} parameter. */ public boolean needsCallee() { - return needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode()); + return hasLazyChildren() || needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode()); } /** @@ -918,6 +935,27 @@ public class FunctionNode extends Block { this.parameters = parameters; } + /** + * Get a specialized type for an identity, if one exists + * @param node node to check specialized type for + * @return null if no specialization exists, otherwise type + */ + public Type getSpecializedType(final IdentNode node) { + return specializedTypes.get(node); + } + + /** + * Set parameter type hints for specialization. + * @param types types array of length equal to parameter list size + */ + public void setParameterTypes(final Class[] types) { + assert types.length == parameters.size() : "Type vector length doesn't correspond to parameter types"; + //diff - skip the callee and this etc, they are not explicit params in the parse tree + for (int i = 0; i < types.length ; i++) { + specializedTypes.put(parameters.get(i), Type.typeFor(types[i])); + } + } + /** * Get the identifier for the variable in which the function return value * should be stored @@ -1266,7 +1304,7 @@ public class FunctionNode extends Block { * @param parentBlock a block to remember as parent */ public void addReferencingParentBlock(final Block parentBlock) { - assert parentBlock.getFunction() == function.findParentFunction(); // all parent blocks must be in the same function + assert parentBlock.getFunction() == function.findParentFunction() : Debug.id(parentBlock.getFunction()) + "!=" + Debug.id(function.findParentFunction()); // all parent blocks must be in the same function if (parentBlock != function.getParent()) { if (referencingParentBlocks == null) { referencingParentBlocks = new LinkedList<>(); diff --git a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java index ab7e49e4650..8b720de41b0 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java @@ -28,7 +28,6 @@ package jdk.nashorn.internal.ir; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.Source; @@ -36,9 +35,6 @@ import jdk.nashorn.internal.runtime.Source; * IR representation of an object literal. */ public class ObjectNode extends Node { - /** Literal context. */ - @Ignore - private Block context; /** Literal elements. */ private final List elements; @@ -49,13 +45,11 @@ public class ObjectNode extends Node { * @param source the source * @param token token * @param finish finish - * @param context the block for this ObjectNode * @param elements the elements used to initialize this ObjectNode */ - public ObjectNode(final Source source, final long token, final int finish, final Block context, final List elements) { + public ObjectNode(final Source source, final long token, final int finish, final List elements) { super(source, token, finish); - this.context = context; this.elements = elements; } @@ -68,7 +62,6 @@ public class ObjectNode extends Node { newElements.add(cs.existingOrCopy(element)); } - this.context = (Block)cs.existingOrCopy(objectNode.context); this.elements = newElements; } @@ -80,10 +73,6 @@ public class ObjectNode extends Node { @Override public Node accept(final NodeVisitor visitor) { if (visitor.enter(this) != null) { - if (context != null) { - context = (Block)context.accept(visitor); - } - for (int i = 0, count = elements.size(); i < count; i++) { elements.set(i, elements.get(i).accept(visitor)); } @@ -116,14 +105,6 @@ public class ObjectNode extends Node { sb.append('}'); } - /** - * Get the block that is this ObjectNode's literal context - * @return the block - */ - public Block getContext() { - return context; - } - /** * Get the elements of this literal node * @return a list of elements diff --git a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java index 7b608edf7ac..491151fa296 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java @@ -152,9 +152,9 @@ public class UnaryNode extends Node implements Assignment { if (isConvert) { convertPos = sb.length(); - sb.append("(("); + sb.append("("); sb.append(getType()); - sb.append(")"); + sb.append(")("); } if (!isPostfix && !isConvert) { @@ -191,8 +191,6 @@ public class UnaryNode extends Node implements Assignment { sb.setCharAt(convertPos, ' '); } } - - //TODO - conversions still have too many parenthesis - makes --print-lower-parse hard to read } /** diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java deleted file mode 100644 index 181c63d8322..00000000000 --- a/nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java +++ /dev/null @@ -1,42 +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.annotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * This is a child node, a real node, not a reference, to an IR node that should - * be traversed. - *

- * TODO Currently not in use. Would make e.g. accept methods simple and unified - * @see jdk.nashorn.internal.ir.Node - */ -@Retention(value=RetentionPolicy.RUNTIME) -public @interface ChildNode { - /** order of traversal compared to other children */ - public int order() default -1; -} diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java deleted file mode 100644 index 6a9de3a455d..00000000000 --- a/nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java +++ /dev/null @@ -1,44 +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.annotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Signifies a parent of a node, i.e. node that should not be traversed if we - * go down the AST. In automatic parsing this can be handled by @Reference - * annotations instead, as all parents are references. - *

- * TODO The use case is automating and creating one implementation of something like - * Node.getParent() - * - * @see jdk.nashorn.internal.ir.Node - */ -@Retention(value=RetentionPolicy.RUNTIME) -public @interface ParentNode { - // EMPTY -} diff --git a/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java b/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java index 1dd002c1f5f..20c8ffca53b 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java +++ b/nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java @@ -33,7 +33,6 @@ import java.lang.annotation.RetentionPolicy; * AST traversal and cloning. Cloning currently as a rule uses * existingOrSame for references and otherwise existingOrCopy *

- * TODO this could probably be automated using the @Reference annotation. */ @Retention(value=RetentionPolicy.RUNTIME) diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java index 3c66aa12d0e..7bbe3836694 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java @@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir.debug; import java.lang.reflect.Field; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Collection; import java.util.Deque; import java.util.Iterator; @@ -36,10 +37,10 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.TernaryNode; import jdk.nashorn.internal.ir.annotations.Ignore; -import jdk.nashorn.internal.ir.annotations.ParentNode; import jdk.nashorn.internal.ir.annotations.Reference; import jdk.nashorn.internal.parser.Token; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.Debug; /** * AST-as-text visualizer. Sometimes you want tree form and not source @@ -47,7 +48,6 @@ import jdk.nashorn.internal.runtime.Context; * * see the flags --print-ast and --print-ast-lower */ - public final class ASTWriter { /** Root node from which to start the traversal */ private final Node root; @@ -71,12 +71,22 @@ public final class ASTWriter { @Override public String toString() { final StringBuilder sb = new StringBuilder(); - printAST(sb, null, "root", root, 0); + printAST(sb, null, null, "root", root, 0); return sb.toString(); } + /** + * Return the visited nodes in an ordered list + * @return the list of nodes in order + */ + public Node[] toArray() { + final List preorder = new ArrayList<>(); + printAST(new StringBuilder(), preorder, null, "root", root, 0); + return preorder.toArray(new Node[preorder.size()]); + } + @SuppressWarnings("unchecked") - private void printAST(final StringBuilder sb, final Field field, final String name, final Node node, final int indent) { + private void printAST(final StringBuilder sb, final List preorder, final Field field, final String name, final Node node, final int indent) { ASTWriter.indent(sb, indent); if (node == null) { sb.append("[Object "); @@ -85,13 +95,23 @@ public final class ASTWriter { return; } + if (preorder != null) { + preorder.add(node); + } + final boolean isReference = field != null && field.getAnnotation(Reference.class) != null; Class clazz = node.getClass(); String type = clazz.getName(); type = type.substring(type.lastIndexOf('.') + 1, type.length()); -// type += "@" + Debug.id(node) + "#" + node.getSymbol(); + if (isReference) { + type = "ref: " + type; + } + type += "@" + Debug.id(node); + if (node.getSymbol() != null) { + type += "#" + node.getSymbol(); + } final List children = new LinkedList<>(); @@ -153,9 +173,7 @@ public final class ASTWriter { append('\n'); for (final Field child : children) { - if (child.getAnnotation(ParentNode.class) != null) { - continue; - } else if (child.getAnnotation(Ignore.class) != null) { + if (child.getAnnotation(Ignore.class) != null) { continue; } @@ -168,7 +186,7 @@ public final class ASTWriter { } if (value instanceof Node) { - printAST(sb, child, child.getName(), (Node)value, indent + 1); + printAST(sb, preorder, child, child.getName(), (Node)value, indent + 1); } else if (value instanceof Collection) { int pos = 0; ASTWriter.indent(sb, indent + 1); @@ -180,7 +198,7 @@ public final class ASTWriter { append('\n'); for (final Node member : (Collection)value) { - printAST(sb, child, child.getName() + "[" + pos++ + "]", member, indent + 2); + printAST(sb, preorder, child, child.getName() + "[" + pos++ + "]", member, indent + 2); } } } diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java index 31c1d972cad..16e237ba521 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java @@ -605,7 +605,7 @@ public final class NativeArray extends ScriptObject { final boolean strict = sobj.isStrictContext(); if (bulkable(sobj)) { - return ((NativeArray)sobj).getArray().pop(); + return sobj.getArray().pop(); } final long len = JSType.toUint32(sobj.getLength()); @@ -725,7 +725,7 @@ public final class NativeArray extends ScriptObject { first = sobj.get(0); if (bulkable(sobj)) { - ((NativeArray) sobj).getArray().shiftLeft(1); + sobj.getArray().shiftLeft(1); } else { for (long k = 1; k < len; k++) { sobj.set(k - 1, sobj.get(k), strict); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java index 8188f426f23..b311981e655 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java @@ -161,21 +161,6 @@ public final class NativeDebug extends ScriptObject { return UNDEFINED; } - /** - * Nashorn extension: get invocation handle from {@link ScriptFunction} - * - * @param self self reference - * @param obj script function - * @return the invocation handle for the given ScriptFunction - */ - @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) - public static Object methodHandle(final Object self, final Object obj) { - if (obj instanceof ScriptFunction) { - return ((ScriptFunction)obj).getInvokeHandle(); - } - return UNDEFINED; - } - /** * Check object identity comparison regardless of type * diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java index 8cea0c70271..433f9317469 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java @@ -317,7 +317,7 @@ public final class NativeError extends ScriptObject { return name; } // Step 10 : return name + ": " + msg - return (String)name + ": " + (String)msg; + return name + ": " + msg; } private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 0514bd25bf0..46b353f1421 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -31,6 +31,7 @@ import java.lang.invoke.MethodHandle; import jdk.nashorn.internal.runtime.GlobalFunctions; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunctionData; import jdk.nashorn.internal.runtime.ScriptObject; @@ -86,8 +87,8 @@ public class ScriptFunctionImpl extends ScriptFunction { * @param builtin is this a built-in function * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted). */ - ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) { - super(name, methodHandle, getMap(strict), scope, specs, strict, builtin, isConstructor); + ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { + super(name, methodHandle, getMap(isStrict), scope, specs, isStrict, isBuiltin, isConstructor); init(); } @@ -95,14 +96,10 @@ public class ScriptFunctionImpl extends ScriptFunction { * Constructor called by (compiler) generated code for {@link ScriptObject}s. * * @param data static function data - * @param methodHandle handle for invocation * @param scope scope object - * @param allocator instance constructor for function */ - public ScriptFunctionImpl(final MethodHandle methodHandle, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) { + public ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope) { super(data, getMap(data.isStrict()), scope); - // Set method handles in script data - data.setMethodHandles(methodHandle, allocator); init(); } diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java deleted file mode 100644 index 4d3df5093ed..00000000000 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionTrampolineImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -package jdk.nashorn.internal.objects; - -import static jdk.nashorn.internal.lookup.Lookup.MH; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import jdk.nashorn.internal.codegen.CompilationException; -import jdk.nashorn.internal.codegen.Compiler; -import jdk.nashorn.internal.codegen.FunctionSignature; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.runtime.CodeInstaller; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ScriptEnvironment; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptFunctionData; -import jdk.nashorn.internal.runtime.ScriptObject; - -/** - * A trampoline is a promise to compile a {@link ScriptFunction} later. It just looks like - * the call to the script function, but when invoked it will compile the script function - * (in a new compile unit) and invoke it - */ -public final class ScriptFunctionTrampolineImpl extends ScriptFunctionImpl { - - private CodeInstaller installer; - - /** Function node to lazily recompile when trampoline is hit */ - private FunctionNode functionNode; - - /** - * Constructor - * - * @param installer opaque code installer from context - * @param functionNode function node to lazily compile when trampoline is hit - * @param data {@link ScriptFunctionData} for function - * @param scope scope - * @param allocator allocator - */ - public ScriptFunctionTrampolineImpl(final CodeInstaller installer, final FunctionNode functionNode, final ScriptFunctionData data, final ScriptObject scope, final MethodHandle allocator) { - super(null, data, scope, allocator); - - this.installer = installer; - this.functionNode = functionNode; - - data.setMethodHandles(makeTrampoline(), allocator); - } - - private final MethodHandle makeTrampoline() { - final MethodType mt = - new FunctionSignature( - true, - functionNode.needsCallee(), - Type.OBJECT, - functionNode.getParameters().size()). - getMethodType(); - - return - MH.bindTo( - MH.asCollector( - findOwnMH( - "trampoline", - Object.class, - Object[].class), - Object[].class, - mt.parameterCount()), - this); - } - - private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { - return MH.findVirtual(MethodHandles.lookup(), ScriptFunctionTrampolineImpl.class, name, MH.type(rtype, types)); - } - - @Override - protected ScriptFunction makeBoundFunction(final ScriptFunctionData data) { - //prevent trampoline recompilation cycle if a function is bound before use - compile(); - return super.makeBoundFunction(data); - } - - private MethodHandle compile() throws CompilationException { - final Compiler compiler = new Compiler(installer, functionNode); - - compiler.compile(); - - final Class clazz = compiler.install(); - /* compute function signature for lazy method. this can be done first after compilation, as only then do we know - * the final state about callees, scopes and specialized parameter types */ - final FunctionSignature signature = new FunctionSignature(true, functionNode.needsCallee(), Type.OBJECT, functionNode.getParameters().size()); - final MethodType mt = signature.getMethodType(); - - MethodHandle mh = MH.findStatic(MethodHandles.publicLookup(), clazz, functionNode.getName(), mt); - if (functionNode.needsCallee()) { - mh = MH.bindTo(mh, this); - } - - // now the invoker method looks like the one our superclass is expecting - resetInvoker(mh); - - return mh; - } - - @SuppressWarnings("unused") - private Object trampoline(final Object... args) throws CompilationException { - Compiler.LOG.info(">>> TRAMPOLINE: Hitting trampoline for '" + functionNode.getName() + "'"); - MethodHandle mh = compile(); - - Compiler.LOG.info("<<< COMPILED TO: " + mh); - // spread the array to invididual args of the correct type - mh = MH.asSpreader(mh, Object[].class, mh.type().parameterCount()); - - try { - //invoke the real method the trampoline points to. this only happens once - return mh.invoke(args); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - } -} diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java index 39cf549e50a..5468ca3d74e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java @@ -313,7 +313,7 @@ loop: } // Construct new object literal. - return new ObjectNode(source, objectToken, finish, null, elements); + return new ObjectNode(source, objectToken, finish, elements); } /** diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index 41149e4b9f6..bfc96abf47c 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -59,6 +59,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Stack; + import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -96,7 +97,7 @@ 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.runtime.Context; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.JSErrorType; @@ -116,9 +117,6 @@ public class Parser extends AbstractParser { /** Is scripting mode. */ private final boolean scripting; - /** Top level script being parsed. */ - private FunctionNode script; - /** Current function being parsed. */ private FunctionNode function; @@ -304,6 +302,7 @@ loop: final FunctionNode functionBlock = new FunctionNode(source, token, Token.descPosition(token), namespace, block, ident, name); block = function = functionBlock; function.setStrictMode(isStrictMode); + function.setState(errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED); return functionBlock; } @@ -312,7 +311,7 @@ loop: * Restore the current block. */ private void restoreBlock() { - block = block.getParent(); + block = block.getParent(); function = block.getFunction(); } @@ -338,7 +337,7 @@ loop: popControlNode(); } - final int possibleEnd = Token.descPosition(token) + Token.descLength(token); + final int possibleEnd = Token.descPosition(token) + Token.descLength(token); // Block closing brace. if (needsBraces) { @@ -438,7 +437,7 @@ loop: } if (lhs instanceof IdentNode) { - if (! checkIdentLValue((IdentNode)lhs)) { + if (!checkIdentLValue((IdentNode)lhs)) { return referenceError(lhs, rhs); } verifyStrictIdent((IdentNode)lhs, "assignment"); @@ -621,15 +620,13 @@ loop: // Make a fake token for the script. final long functionToken = Token.toDesc(FUNCTION, 0, source.getLength()); // Set up the script to append elements. - script = newFunctionBlock(new IdentNode(source, functionToken, Token.descPosition(functionToken), scriptName)); - // set kind to be SCRIPT + + final FunctionNode script = newFunctionBlock(new IdentNode(source, functionToken, Token.descPosition(functionToken), scriptName)); + script.setKind(FunctionNode.Kind.SCRIPT); - // Set the first token of the script. script.setFirstToken(functionToken); - // Gather source elements. sourceElements(); expect(EOF); - // Set the last token of the script. script.setLastToken(token); script.setFinish(source.getLength() - 1); @@ -1231,7 +1228,7 @@ loop: } if (init instanceof IdentNode) { - if (! checkIdentLValue((IdentNode)init)) { + if (!checkIdentLValue((IdentNode)init)) { error(AbstractParser.message("not.lvalue.for.in.loop"), init.getToken()); } verifyStrictIdent((IdentNode)init, "for-in iterator"); @@ -2026,7 +2023,7 @@ loop: break; default: - if (! elision) { + if (!elision) { error(AbstractParser.message("expected.comma", type.getNameOrType())); } // Add expression element. @@ -2067,15 +2064,11 @@ loop: next(); // Object context. - Block objectContext = null; // Prepare to accumulate elements. final List elements = new ArrayList<>(); final Map map = new HashMap<>(); - try { - // Create a block for the object literal. - objectContext = newBlock(); - + // Create a block for the object literal. boolean commaSeen = true; loop: while (true) { @@ -2090,97 +2083,90 @@ loop: break; default: - if (! commaSeen) { + if (!commaSeen) { error(AbstractParser.message("expected.comma", type.getNameOrType())); - } - - commaSeen = false; - // Get and add the next property. - final PropertyNode property = propertyAssignment(); - final Object key = property.getKeyName(); - final PropertyNode existingProperty = map.get(key); - - if (existingProperty != null) { - // ECMA section 11.1.5 Object Initialiser - // point # 4 on property assignment production - final Node value = property.getValue(); - final Node getter = property.getGetter(); - final Node setter = property.getSetter(); - - final Node prevValue = existingProperty.getValue(); - final Node prevGetter = existingProperty.getGetter(); - final Node prevSetter = existingProperty.getSetter(); - - boolean redefinitionOk = true; - // ECMA 11.1.5 strict mode restrictions - if (isStrictMode) { - if (value != null && prevValue != null) { - redefinitionOk = false; - } - } - - final boolean isPrevAccessor = prevGetter != null || prevSetter != null; - final boolean isAccessor = getter != null || setter != null; - - // data property redefined as accessor property - if (prevValue != null && isAccessor) { - redefinitionOk = false; - } - - // accessor property redefined as data - if (isPrevAccessor && value != null) { - redefinitionOk = false; - } - - if (isAccessor && isPrevAccessor) { - if (getter != null && prevGetter != null || - setter != null && prevSetter != null) { - redefinitionOk = false; - } - } - - if (! redefinitionOk) { - error(AbstractParser.message("property.redefinition", key.toString()), property.getToken()); - } - - if (value != null) { - final Node existingValue = existingProperty.getValue(); - - if (existingValue == null) { - existingProperty.setValue(value); - } else { - final long propertyToken = Token.recast(existingProperty.getToken(), COMMARIGHT); - existingProperty.setValue(new BinaryNode(source, propertyToken, existingValue, value)); - } - - existingProperty.setGetter(null); - existingProperty.setSetter(null); - } - - if (getter != null) { - existingProperty.setGetter(getter); - } - - if (setter != null) { - existingProperty.setSetter(setter); - } - } else { - map.put(key, property); - elements.add(property); - } - - break; } + + commaSeen = false; + // Get and add the next property. + final PropertyNode property = propertyAssignment(); + final Object key = property.getKeyName(); + final PropertyNode existingProperty = map.get(key); + + if (existingProperty != null) { + // ECMA section 11.1.5 Object Initialiser + // point # 4 on property assignment production + final Node value = property.getValue(); + final Node getter = property.getGetter(); + final Node setter = property.getSetter(); + + final Node prevValue = existingProperty.getValue(); + final Node prevGetter = existingProperty.getGetter(); + final Node prevSetter = existingProperty.getSetter(); + + boolean redefinitionOk = true; + // ECMA 11.1.5 strict mode restrictions + if (isStrictMode) { + if (value != null && prevValue != null) { + redefinitionOk = false; + } + } + + final boolean isPrevAccessor = prevGetter != null || prevSetter != null; + final boolean isAccessor = getter != null || setter != null; + + // data property redefined as accessor property + if (prevValue != null && isAccessor) { + redefinitionOk = false; + } + + // accessor property redefined as data + if (isPrevAccessor && value != null) { + redefinitionOk = false; + } + + if (isAccessor && isPrevAccessor) { + if (getter != null && prevGetter != null || + setter != null && prevSetter != null) { + redefinitionOk = false; + } + } + + if (!redefinitionOk) { + error(AbstractParser.message("property.redefinition", key.toString()), property.getToken()); + } + + if (value != null) { + final Node existingValue = existingProperty.getValue(); + + if (existingValue == null) { + existingProperty.setValue(value); + } else { + final long propertyToken = Token.recast(existingProperty.getToken(), COMMARIGHT); + existingProperty.setValue(new BinaryNode(source, propertyToken, existingValue, value)); + } + + existingProperty.setGetter(null); + existingProperty.setSetter(null); + } + + if (getter != null) { + existingProperty.setGetter(getter); + } + + if (setter != null) { + existingProperty.setSetter(setter); + } + } else { + map.put(key, property); + elements.add(property); + } + + break; } - } finally { - restoreBlock(); } - // Construct new object literal. - objectContext.setFinish(finish); - objectContext.setStart(Token.descPosition(objectToken)); - - return new ObjectNode(source, objectToken, finish, objectContext, elements); + return new ObjectNode(source, objectToken, finish, elements); } /** @@ -2845,7 +2831,7 @@ loop: } if (lhs instanceof IdentNode) { - if (! checkIdentLValue((IdentNode)lhs)) { + if (!checkIdentLValue((IdentNode)lhs)) { return referenceError(lhs, null); } verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator"); @@ -2872,7 +2858,7 @@ loop: return referenceError(lhs, null); } if (lhs instanceof IdentNode) { - if (! checkIdentLValue((IdentNode)lhs)) { + if (!checkIdentLValue((IdentNode)lhs)) { next(); return referenceError(lhs, null); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java index 9f6867ddaf8..996bea35166 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -164,7 +164,6 @@ public class AccessorProperty extends Property { super(key, flags, slot); /* - * * primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also * works in dual field mode, it only means that the property never has a primitive * representation. @@ -348,11 +347,10 @@ public class AccessorProperty extends Property { private MethodHandle debug(final MethodHandle mh, final Class forType, final Class type, final String tag) { if (DEBUG_FIELDS) { - final MethodHandle mhd = MethodHandleFactory.addDebugPrintout( + return MethodHandleFactory.addDebugPrintout( LOG, mh, tag + " '" + getKey() + "' (property="+ Debug.id(this) + ", forType=" + stripName(forType) + ", type=" + stripName(type) + ')'); - return mhd; } return mh; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java index 5fd16528e22..80fac179cb0 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java @@ -25,6 +25,8 @@ package jdk.nashorn.internal.runtime; +import jdk.nashorn.internal.codegen.ClassEmitter; + /** * Interface for installing classes passed to the compiler. * As only the code generating package (i.e. Context) knows about @@ -52,12 +54,12 @@ public interface CodeInstaller { */ public Class install(final String className, final byte[] bytecode); - /* + /** * Verify generated bytecode before emission. This is called back from the * {@link ClassEmitter} or the {@link Compiler}. If the "--verify-code" parameter * hasn't been given, this is a nop * - * @param bytecode bytecode to verify + * @param code bytecode to verify */ public void verify(final byte[] code); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java new file mode 100644 index 00000000000..3cc9f09d238 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java @@ -0,0 +1,162 @@ +/* + * 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.runtime; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +import jdk.nashorn.internal.codegen.types.Type; + +/** + * An version of a JavaScript function, native or JavaScript. + * Supports lazily generating a constructor version of the invocation. + */ +final class CompiledFunction implements Comparable { + + private final MethodHandle invoker; + private MethodHandle constructor; + + CompiledFunction(final MethodHandle invoker) { + this(invoker, null); + } + + CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) { + this.invoker = invoker; + this.constructor = constructor; //isConstructor + } + + @Override + public String toString() { + return ""; + } + + MethodHandle getInvoker() { + return invoker; + } + + MethodHandle getConstructor() { + return constructor; + } + + void setConstructor(final MethodHandle constructor) { + this.constructor = constructor; + } + + boolean hasConstructor() { + return constructor != null; + } + + MethodType type() { + return invoker.type(); + } + + @Override + public int compareTo(final CompiledFunction o) { + return weight() - o.weight(); + } + + private int weight() { + return weight(type()); + } + + private static int weight(final MethodType type) { + if (isVarArgsType(type)) { + return Integer.MAX_VALUE; //if there is a varargs it should be the heavist and last fallback + } + + int weight = Type.typeFor(type.returnType()).getWeight(); + for (final Class paramType : type.parameterArray()) { + final int pweight = Type.typeFor(paramType).getWeight(); + weight += pweight; + } + return weight; + } + + private static boolean isVarArgsType(final MethodType type) { + assert type.parameterCount() >= 1 : type; + return type.parameterType(type.parameterCount() - 1) == Object[].class; + } + + boolean moreGenericThan(final CompiledFunction o) { + return weight() > o.weight(); + } + + boolean moreGenericThan(final MethodType type) { + return weight() > weight(type); + } + + /** + * Check whether a given method descriptor is compatible with this invocation. + * It is compatible if the types are narrower than the invocation type so that + * a semantically equivalent linkage can be performed. + * + * @param typesc + * @return + */ + boolean typeCompatible(final MethodType type) { + final Class[] wantedParams = type.parameterArray(); + final Class[] existingParams = type().parameterArray(); + + //if we are not examining a varargs type, the number of parameters must be the same + if (wantedParams.length != existingParams.length && !isVarArgsType(type)) { + return false; + } + + //we only go as far as the shortest array. the only chance to make this work if + //parameters lengths do not match is if our type ends with a varargs argument. + //then every trailing parameter in the given callsite can be folded into it, making + //us compatible (albeit slower than a direct specialization) + final int lastParamIndex = Math.min(wantedParams.length, existingParams.length); + for (int i = 0; i < lastParamIndex; i++) { + final Type w = Type.typeFor(wantedParams[i]); + final Type e = Type.typeFor(existingParams[i]); + + //don't specialize on booleans, we have the "true" vs int 1 ambiguity in resolution + //we also currently don't support boolean as a javascript function callsite type. + //it will always box. + if (w.isBoolean()) { + return false; + } + + //This callsite type has a vararg here. it will swallow all remaining args. + //for consistency, check that it's the last argument + if (e.isArray()) { + return true; + } + + //Our arguments must be at least as wide as the wanted one, if not wider + if (Type.widest(w, e) != e) { + //e.g. this invocation takes double and callsite says "object". reject. won't fit + //but if invocation takes a double and callsite says "int" or "long" or "double", that's fine + return false; + } + } + + return true; // anything goes for return type, take the convenient one and it will be upcasted thru dynalink magic. + } + + + +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java new file mode 100644 index 00000000000..ff660d3d3b4 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunctions.java @@ -0,0 +1,73 @@ +/* + * 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.runtime; + +import java.lang.invoke.MethodType; +import java.util.Iterator; +import java.util.TreeSet; + +/** + * This is a list of code versions of a function. + * The list is sorted in ascending order of generic descriptors + */ +@SuppressWarnings("serial") +final class CompiledFunctions extends TreeSet { + + CompiledFunction best(final MethodType type) { + final Iterator iter = iterator(); + while (iter.hasNext()) { + final CompiledFunction next = iter.next(); + if (next.typeCompatible(type)) { + return next; + } + } + return mostGeneric(); + } + + boolean needsCallee() { + for (final CompiledFunction inv : this) { + assert ScriptFunctionData.needsCallee(inv.getInvoker()) == ScriptFunctionData.needsCallee(mostGeneric().getInvoker()); + } + return ScriptFunctionData.needsCallee(mostGeneric().getInvoker()); + } + + CompiledFunction mostGeneric() { + return last(); + } + + /** + * Is the given type even more specific than this entire list? That means + * we have an opportunity for more specific versions of the method + * through lazy code generation + * + * @param type type to check against + * @return true if the given type is more specific than all invocations available + */ + boolean isLessSpecificThan(final MethodType type) { + return best(type).moreGenericThan(type); + } + + +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 516c0a79892..151615c07df 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -80,7 +80,7 @@ public final class Context { /** * Return the context for this installer - * @return context + * @return ScriptEnvironment */ @Override public ScriptEnvironment getOwner() { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java index a07fb580d69..a32e721cc46 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java @@ -237,7 +237,7 @@ public final class ECMAException extends NashornException { return (String)name; } - return (String)name + ": " + (String)msg; + return name + ": " + msg; } private static Throwable asThrowable(final Object obj) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java new file mode 100644 index 00000000000..ed54b2e92a3 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java @@ -0,0 +1,100 @@ +/* + * 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.runtime; + +import static jdk.nashorn.internal.lookup.Lookup.MH; + +import java.lang.invoke.MethodHandle; + +/** + * This is a subclass that represents a script function that may not be regenerated. + * This is used for example for bound functions and builtins. + */ +public final class FinalScriptFunctionData extends ScriptFunctionData { + + /** + * Constructor - used for bind + * + * @param name name + * @param arity arity + * @param list precompiled code + * @param isStrict strict + * @param isBuiltin builtin + * @param isConstructor constructor + */ + FinalScriptFunctionData(final String name, int arity, CompiledFunctions functions, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { + super(name, arity, isStrict, isBuiltin, isConstructor); + code.addAll(functions); + } + + /** + * Constructor - used from ScriptFunction. This assumes that we have code alraedy for the + * method (typically a native method) and possibly specializations. + * + * @param name name + * @param mh method handle for generic version of method + * @param specs specializations + * @param isStrict strict + * @param isBuiltin builtin + * @param isConstructor constructor + */ + FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { + super(name, arity(mh), isStrict, isBuiltin, isConstructor); + + addInvoker(mh); + if (specs != null) { + for (final MethodHandle spec : specs) { + addInvoker(spec); + } + } + } + + private void addInvoker(final MethodHandle mh) { + boolean needsCallee = needsCallee(mh); + if (isConstructor(mh)) { + //only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor + //is too conservative a check. However, isConstructor(mh) always implies isConstructor param + assert isConstructor(); + code.add(new CompiledFunction(MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor + } else { + code.add(new CompiledFunction(mh)); + } + } + + private static int arity(final MethodHandle mh) { + if (isVarArg(mh)) { + return -1; + } + + //drop self, callee and boolean constructor flag to get real arity + return mh.type().parameterCount() - 1 - (needsCallee(mh) ? 1 : 0) - (isConstructor(mh) ? 1 : 0); + } + + private static boolean isConstructor(final MethodHandle mh) { + return mh.type().parameterCount() >= 1 && mh.type().parameterType(0) == boolean.class; + } + +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java new file mode 100644 index 00000000000..03f0ab5d906 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java @@ -0,0 +1,185 @@ +/* + * 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.runtime; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import jdk.nashorn.internal.codegen.Compiler; +import jdk.nashorn.internal.codegen.CompilerConstants; +import jdk.nashorn.internal.codegen.FunctionSignature; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; +import jdk.nashorn.internal.parser.Token; +import jdk.nashorn.internal.parser.TokenType; + +import static jdk.nashorn.internal.lookup.Lookup.MH; + +/** + * This is a subclass that represents a script function that may be regenerated, + * for example with specialization based on call site types, or lazily generated. + * The common denominator is that it can get new invokers during its lifespan, + * unlike {@link FinalScriptFunctionData} + */ +public final class RecompilableScriptFunctionData extends ScriptFunctionData { + + private final FunctionNode functionNode; + private final PropertyMap allocatorMap; + private final CodeInstaller installer; + private final String allocatorClassName; + + /** lazily generated allocator */ + private MethodHandle allocator; + + private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); + + /** + * Constructor - public as scripts use it + * + * @param functionNode functionNode that represents this function code + * @param installer installer for code regeneration versions of this function + * @param allocatorClassName name of our allocator class, will be looked up dynamically if used as a constructor + * @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(), + functionNode.getParameters().size(), + functionNode.isStrictMode(), + false, + true); + + this.functionNode = functionNode; + this.installer = installer; + this.allocatorClassName = allocatorClassName; + this.allocatorMap = allocatorMap; + } + + @Override + String toSource() { + final Source source = functionNode.getSource(); + final long token = tokenFor(functionNode); + + if (source != null && token != 0) { + return source.getString(Token.descPosition(token), Token.descLength(token)); + } + + return "function " + (name == null ? "" : name) + "() { [native code] }"; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + final Source source = functionNode.getSource(); + final long token = tokenFor(functionNode); + + if (source != null) { + sb.append(source.getName()) + .append(':') + .append(source.getLine(Token.descPosition(token))) + .append(' '); + } + + return sb.toString() + super.toString(); + } + + 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()); + + return Token.toDesc(TokenType.FUNCTION, position, length); + } + + @Override + ScriptObject allocate() { + try { + ensureHasAllocator(); //if allocatorClass name is set to null (e.g. for bound functions) we don't even try + return allocator == null ? null : (ScriptObject)allocator.invokeExact(allocatorMap); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + } + + private void ensureHasAllocator() throws ClassNotFoundException { + if (allocator == null && allocatorClassName != null) { + this.allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName), CompilerConstants.ALLOCATE.tag(), MH.type(ScriptObject.class, PropertyMap.class)); + } + } + + @Override + protected void ensureCodeGenerated() { + if (!code.isEmpty()) { + return; // nothing to do, we have code, at least some. + } + + // check if function node is lazy, need to compile it. + // note that currently function cloning is not working completely, which + // means that the compiler will mutate the function node it has been given + // once it has been compiled, it cannot be recompiled. This means that + // lazy compilation works (not compiled yet) but e.g. specializations won't + // until the copy-on-write changes for IR are in, making cloning meaningless. + // therefore, currently method specialization is disabled. TODO + + if (functionNode.isLazy()) { + Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '" + functionNode.getName() + "'"); + new Compiler(installer, functionNode).compile().install(); + + // we don't need to update any flags - varArgs and needsCallee are instrincic + // in the function world we need to get a destination node from the compile instead + // and replace it with our function node. TODO + } + + // we can't get here unless we have bytecode, either from eager compilation or from + // running a lazy compile on the lines above + + assert functionNode.hasState(CompilationState.INSTALLED); + + // code exists - look it up and add it into the automatically sorted invoker list + code.add( + new CompiledFunction( + MH.findStatic( + LOOKUP, + functionNode.getCompileUnit().getCode(), + functionNode.getName(), + new FunctionSignature(functionNode). + getMethodType()))); + } + + @Override + MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) { + final MethodHandle mh = super.getBestInvoker(callSiteType, args); + if (code.isLessSpecificThan(callSiteType)) { + // opportunity for code specialization - we can regenerate a better version of this method + } + return mh; + } + +} + diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java index def0313f948..36a1d2ac4de 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java @@ -82,6 +82,9 @@ public final class ScriptEnvironment { /** Show full Nashorn version */ public final boolean _fullversion; + /** Should lazy compilation take place */ + public final boolean _lazy_compilation; + /** Create a new class loaded for each compilation */ public final boolean _loader_per_compile; @@ -155,6 +158,7 @@ public final class ScriptEnvironment { _early_lvalue_error = options.getBoolean("early.lvalue.error"); _empty_statements = options.getBoolean("empty.statements"); _fullversion = options.getBoolean("fullversion"); + _lazy_compilation = options.getBoolean("lazy.compilation"); _loader_per_compile = options.getBoolean("loader.per.compile"); _no_syntax_extensions = options.getBoolean("no.syntax.extensions"); _package = options.getString("package"); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java index 2d28f91e1a4..512a0b16506 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java @@ -33,11 +33,11 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; + import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.nashorn.internal.codegen.CompilerConstants.Call; -import jdk.nashorn.internal.objects.annotations.SpecializedFunction; import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; import jdk.nashorn.internal.runtime.linker.NashornGuards; @@ -48,16 +48,16 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards; public abstract class ScriptFunction extends ScriptObject { /** Method handle for prototype getter for this ScriptFunction */ - public static final MethodHandle G$PROTOTYPE = findOwnMH("G$prototype", Object.class, Object.class); + public static final MethodHandle G$PROTOTYPE = findOwnMH("G$prototype", Object.class, Object.class); /** Method handle for prototype setter for this ScriptFunction */ - public static final MethodHandle S$PROTOTYPE = findOwnMH("S$prototype", void.class, Object.class, Object.class); + public static final MethodHandle S$PROTOTYPE = findOwnMH("S$prototype", void.class, Object.class, Object.class); /** Method handle for length getter for this ScriptFunction */ - public static final MethodHandle G$LENGTH = findOwnMH("G$length", int.class, Object.class); + public static final MethodHandle G$LENGTH = findOwnMH("G$length", int.class, Object.class); /** Method handle for name getter for this ScriptFunction */ - public static final MethodHandle G$NAME = findOwnMH("G$name", Object.class, Object.class); + public static final MethodHandle G$NAME = findOwnMH("G$name", Object.class, Object.class); /** Method handle for allocate function for this ScriptFunction */ static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class); @@ -67,7 +67,9 @@ public abstract class ScriptFunction extends ScriptObject { /** method handle to scope getter for this ScriptFunction */ public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class); - private final ScriptFunctionData data; + private static final MethodHandle IS_FUNCTION_MH = findOwnMH("isFunctionMH", boolean.class, Object.class, ScriptFunctionData.class); + + private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class); /** Reference to constructor prototype. */ protected Object prototype; @@ -75,6 +77,8 @@ public abstract class ScriptFunction extends ScriptObject { /** The parent scope. */ private final ScriptObject scope; + private final ScriptFunctionData data; + /** * Constructor * @@ -97,7 +101,7 @@ public abstract class ScriptFunction extends ScriptObject { final boolean builtin, final boolean isConstructor) { - this (new ScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope); + this(new FinalScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope); } /** @@ -118,8 +122,8 @@ public abstract class ScriptFunction extends ScriptObject { constructorCount++; } - this.data = data; - this.scope = scope; + this.data = data; + this.scope = scope; } @Override @@ -295,20 +299,20 @@ public abstract class ScriptFunction extends ScriptObject { /** * Return the most appropriate invoke handle if there are specializations * @param type most specific method type to look for invocation with + * @param callsite args for trampoline invocation * @return invoke method handle */ - private final MethodHandle getBestInvoker(final MethodType type) { - return data.getBestInvoker(type); + private MethodHandle getBestInvoker(final MethodType type, final Object[] args) { + return data.getBestInvoker(type, args); } /** - * Get the invoke handle - the most generic (and if no specializations are in place, only) invocation - * method handle for this ScriptFunction - * @see SpecializedFunction - * @return invokeHandle + * Return the most appropriate invoke handle if there are specializations + * @param type most specific method type to look for invocation with + * @return invoke method handle */ - public final MethodHandle getInvokeHandle() { - return data.getInvoker(); + public MethodHandle getBestInvoker(final MethodType type) { + return getBestInvoker(type, null); } /** @@ -319,7 +323,7 @@ public abstract class ScriptFunction extends ScriptObject { * @return bound invoke handle */ public final MethodHandle getBoundInvokeHandle(final ScriptObject self) { - return MH.bindTo(bindToCalleeIfNeeded(getInvokeHandle()), self); + return MH.bindTo(bindToCalleeIfNeeded(data.getGenericInvoker()), self); } /** @@ -329,7 +333,8 @@ public abstract class ScriptFunction extends ScriptObject { * @return the potentially bound method handle */ private MethodHandle bindToCalleeIfNeeded(final MethodHandle methodHandle) { - return data.needsCallee() ? MH.bindTo(methodHandle, this) : methodHandle; + return ScriptFunctionData.needsCallee(methodHandle) ? MH.bindTo(methodHandle, this) : methodHandle; + } /** @@ -340,15 +345,6 @@ public abstract class ScriptFunction extends ScriptObject { return data.getName(); } - /** - * Does this script function need to be compiled. This determined by - * null checking invokeHandle - * - * @return true if this needs compilation - */ - public final boolean needsCompilation() { - return data.getInvoker() == null; - } /** * Get the scope for this function @@ -358,15 +354,6 @@ public abstract class ScriptFunction extends ScriptObject { return scope; } - /** - * Reset the invoker handle. This is used by trampolines for - * lazy code generation - * @param invoker new invoker - */ - protected void resetInvoker(final MethodHandle invoker) { - data.resetInvoker(invoker); - } - /** * Prototype getter for this ScriptFunction - follows the naming convention * used by Nasgen and the code generator @@ -464,7 +451,7 @@ public abstract class ScriptFunction extends ScriptObject { @Override protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc) { final MethodType type = desc.getMethodType(); - return new GuardedInvocation(pairArguments(data.getBestConstructor(type), type), null, NashornGuards.getFunctionGuard(this)); + return new GuardedInvocation(pairArguments(data.getBestConstructor(type.changeParameterType(0, ScriptFunction.class), null), type), null, getFunctionGuard(this)); } @SuppressWarnings("unused") @@ -472,7 +459,7 @@ public abstract class ScriptFunction extends ScriptObject { if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) { return obj; } - return ((GlobalObject) Context.getGlobalTrusted()).wrapAsObject(obj); + return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(obj); } /** @@ -506,8 +493,7 @@ public abstract class ScriptFunction extends ScriptObject { MethodHandle guard = null; if (data.needsCallee()) { - final MethodHandle callHandle = getBestInvoker(type); - + final MethodHandle callHandle = getBestInvoker(type, request.getArguments()); if (NashornCallSiteDescriptor.isScope(desc)) { // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined // (callee, this, args...) => (callee, args...) @@ -525,13 +511,12 @@ public abstract class ScriptFunction extends ScriptObject { if (ScriptFunctionData.isPrimitiveThis(request.getArguments()[1])) { boundHandle = MH.filterArguments(boundHandle, 1, WRAPFILTER); } else { - guard = NashornGuards.getNonStrictFunctionGuard(this); + guard = getNonStrictFunctionGuard(this); } } } } else { - final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1)); - + final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments()); if (NashornCallSiteDescriptor.isScope(desc)) { // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined // (this, args...) => (args...) @@ -545,7 +530,8 @@ public abstract class ScriptFunction extends ScriptObject { } boundHandle = pairArguments(boundHandle, type); - return new GuardedInvocation(boundHandle, guard == null ? NashornGuards.getFunctionGuard(this) : guard); + + return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this) : guard); } /** @@ -554,13 +540,50 @@ public abstract class ScriptFunction extends ScriptObject { * These don't want a callee parameter, so bind that. Name binding is optional. */ MethodHandle getCallMethodHandle(final MethodType type, final String bindName) { - return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(getBestInvoker(type)), bindName), type); + return pairArguments(bindToNameIfNeeded(bindToCalleeIfNeeded(getBestInvoker(type, null)), bindName), type); } private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) { return bindName == null ? methodHandle : MH.insertArguments(methodHandle, 1, bindName); } + /** + * Get the guard that checks if a {@link ScriptFunction} is equal to + * a known ScriptFunction, using reference comparison + * + * @param function The ScriptFunction to check against. This will be bound to the guard method handle + * + * @return method handle for guard + */ + private static MethodHandle getFunctionGuard(final ScriptFunction function) { + assert function.data != null; + return MH.insertArguments(IS_FUNCTION_MH, 1, function.data); + } + + /** + * Get a guard that checks if a {@link ScriptFunction} is equal to + * a known ScriptFunction using reference comparison, and whether the type of + * the second argument (this-object) is not a JavaScript primitive type. + * + * @param function The ScriptFunction to check against. This will be bound to the guard method handle + * + * @return method handle for guard + */ + private static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) { + assert function.data != null; + return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.data); + } + + @SuppressWarnings("unused") + private static boolean isFunctionMH(final Object self, final ScriptFunctionData data) { + return self instanceof ScriptFunction && ((ScriptFunction)self).data == data; + } + + @SuppressWarnings("unused") + private static boolean isNonStrictFunction(final Object self, final Object arg, final ScriptFunctionData data) { + return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject; + } + 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 8f8193e4786..f83cfa2c954 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java @@ -32,227 +32,94 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.parser.Token; -import jdk.nashorn.internal.parser.TokenType; + +import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; /** * A container for data needed to instantiate a specific {@link ScriptFunction} at runtime. * Instances of this class are created during codegen and stored in script classes' * constants array to reduce function instantiation overhead during runtime. */ -public final class ScriptFunctionData { - private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class); +public abstract class ScriptFunctionData { + + /** Name of the function or "" for anonynous functions */ + protected final String name; + + /** All versions of this function that have been generated to code */ + protected final CompiledFunctions code; + + private int arity; + + private final boolean isStrict; + + private final boolean isBuiltin; + + private final boolean isConstructor; + private static final MethodHandle NEWFILTER = findOwnMH("newFilter", Object.class, Object.class, Object.class); - - // per-function object flags - private static final int IS_STRICT = 0b0000_0001; - private static final int IS_BUILTIN = 0b0000_0010; - private static final int HAS_CALLEE = 0b0000_0100; - private static final int IS_VARARGS = 0b0000_1000; - private static final int IS_CONSTRUCTOR = 0b0001_0000; - - /** Name of the function or "" */ - private final String name; - /** Source of this function, or null */ - private final Source source; - /** Map for new instance constructor */ - private PropertyMap allocatorMap; - /** Start position and length in source */ - private final long token; - /** Number of expected arguments, either taken from FunctionNode or calculated from method handle signature*/ - private int arity; - private final int flags; - - /** Reference to code for this method. */ - private MethodHandle invoker; - /** Reference to code for this method when called to create "new" object. This must always be populated with a - * result of calling {@link #composeConstructor(MethodHandle)} on the value of the {@link #invoker} field. */ - private MethodHandle constructor; - /** Constructor to create a new instance. */ - private MethodHandle allocator; - /** Generic invoker to used in {@link ScriptFunction#invoke(Object, Object...)}. */ - private MethodHandle genericInvoker; - /** Specializations - see @SpecializedFunction */ - private MethodHandle[] invokeSpecializations; - /** Specializations - see @SpecializedFunction. Same restrictions as for {@link #constructor} apply; only populate - * with method handles returned from {@link #composeConstructor(MethodHandle)}. */ - private MethodHandle[] constructSpecializations; - - /** - * Constructor - * @param fn the function node - * @param allocatorMap the allocator property map - */ - public ScriptFunctionData(final FunctionNode fn, final PropertyMap allocatorMap) { - - final long firstToken = fn.getFirstToken(); - final long lastToken = fn.getLastToken(); - final int position = Token.descPosition(firstToken); - final int length = Token.descPosition(lastToken) - position + Token.descLength(lastToken); - - this.name = fn.isAnonymous() ? "" : fn.getIdent().getName(); - this.source = fn.getSource(); - this.allocatorMap = allocatorMap; - this.token = Token.toDesc(TokenType.FUNCTION, position, length); - this.arity = fn.getParameters().size(); - this.flags = makeFlags(fn.needsCallee(), fn.isVarArg(), fn.isStrictMode(), false, true); - } + private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class); /** * Constructor * - * @param name the function name - * @param methodHandle the method handle - * @param specs array of specialized method handles - * @param strict strict flag - * @param builtin builtin flag - * @param isConstructor constructor flags + * @param name script function name + * @param arity arity + * @param isStrict is the function strict + * @param isBuiltin is the function built in + * @param isConstructor is the function a constructor */ - public ScriptFunctionData(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) { - this(name, null, 0L, methodHandle, specs, strict, builtin, isConstructor); + protected ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { + this.name = name; + this.arity = arity; + this.code = new CompiledFunctions(); + this.isStrict = isStrict; + this.isBuiltin = isBuiltin; + this.isConstructor = isConstructor; } - private ScriptFunctionData(final String name, final Source source, final long token, final MethodHandle methodHandle, final MethodHandle[] specs, final boolean strict, final boolean builtin, final boolean isConstructor) { - this.name = name; - this.source = source; - this.token = token; - - final boolean isVarArg = isVarArg(methodHandle); - final boolean needsCallee = needsCallee(methodHandle); - - this.flags = makeFlags(needsCallee, isVarArg, strict, builtin, isConstructor); - int lArity = isVarArg ? -1 : methodHandle.type().parameterCount() - 1; //drop the self param for arity - - if (needsCallee && !isVarArg) { - lArity--; - } - - if (isConstructor(methodHandle)) { - assert isConstructor; - if (!isVarArg) { - lArity--; // drop the boolean flag for arity - } - /* - * We insert a boolean argument to tell if the method was invoked as constructor or not if the method - * handle's first argument is boolean. - */ - this.invoker = MH.insertArguments(methodHandle, 0, false); - this.constructor = composeConstructor(MH.insertArguments(methodHandle, 0, true)); - - if (specs != null) { - this.invokeSpecializations = new MethodHandle[specs.length]; - this.constructSpecializations = new MethodHandle[specs.length]; - for (int i = 0; i < specs.length; i++) { - this.invokeSpecializations[i] = MH.insertArguments(specs[i], 0, false); - this.constructSpecializations[i] = composeConstructor(MH.insertArguments(specs[i], 0, true)); - } - } - } else { - this.invoker = methodHandle; - this.constructor = null; // delay composition of the constructor - this.invokeSpecializations = specs; - this.constructSpecializations = null; // delay composition of the constructors - } - this.arity = lArity; - } - - /** - * Get the arity of the function. - * @return the arity - */ - int getArity() { + final int getArity() { return arity; } /** - * Set the arity of the function. - * @param arity the arity + * Used from e.g. Native*$Constructors as an explicit call. TODO - make arity immutable and final + * @param arity new arity */ - void setArity(int arity) { + void setArity(final int arity) { this.arity = arity; } - /** - * Get the function name. - * @return function name - */ - String getName() { - return name; - } + CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) { + final MethodHandle boundInvoker = bindInvokeHandle(originalInv.getInvoker(), fn, self, args); - /** - * Get this function as a String containing its source code. If no source code - * exists in this ScriptFunction, its contents will be displayed as {@code [native code]} - * @return string representation of this function's source - */ - String toSource() { - if (source != null && token != 0) { - return source.getString(Token.descPosition(token), Token.descLength(token)); + if (isConstructor()) { + ensureConstructor(originalInv); + return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args)); } - return "function " + (name == null ? "" : name) + "() { [native code] }"; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - - sb.append(super.toString()) - .append(" [ ") - .append(invoker) - .append(", ") - .append((name == null || name.isEmpty()) ? "" : name); - - if (source != null) { - sb.append(" @ ") - .append(source.getName()) - .append(':') - .append(source.getLine(Token.descPosition(token))); - } - sb.append(" ]"); - - return sb.toString(); + return new CompiledFunction(boundInvoker); } /** - * Returns true if the function needs a callee argument. - * @return the needsCallee flag - */ - boolean needsCallee() { - return (flags & HAS_CALLEE) != 0; - } - - /** - * Returns true if this is a strict-mode function. - * @return the strict flag + * Is this a ScriptFunction generated with strict semantics? + * @return true if strict, false otherwise */ public boolean isStrict() { - return (flags & IS_STRICT) != 0; + return isStrict; } - /** - * Returns true if this is a built-in function. - * @return the built-in flag - */ - private boolean isBuiltin() { - return (flags & IS_BUILTIN) != 0; + boolean isBuiltin() { + return isBuiltin; } - /** - * Returns true if this function can be used as a constructor. - * @return the constructor flag - */ - private boolean isConstructor() { - return (flags & IS_CONSTRUCTOR) != 0; + boolean isConstructor() { + return isConstructor; } - /** - * Returns true if this is a var-arg function. - * @return the var-arg flag - */ - private boolean isVarArg() { - return (flags & IS_VARARGS) != 0; + boolean needsCallee() { + // we don't know if we need a callee or not unless we are generated + ensureCodeGenerated(); + return code.needsCallee(); } /** @@ -261,127 +128,408 @@ public final class ScriptFunctionData { * @return true if this argument must be an object */ boolean needsWrappedThis() { - return (flags & (IS_STRICT | IS_BUILTIN)) == 0; + return !isStrict && !isBuiltin; + } + + String toSource() { + return "function " + (name == null ? "" : name) + "() { [native code] }"; + } + + String getName() { + return name; } /** - * Get the method handle used to invoke this function. - * @return the invoke handle + * Get this function as a String containing its source code. If no source code + * exists in this ScriptFunction, its contents will be displayed as {@code [native code]} + * + * @return string representation of this function */ - MethodHandle getInvoker() { - return invoker; - } + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); - MethodHandle getBestInvoker(final MethodType type) { - return SpecializedMethodChooser.candidateWithLowestWeight(type, invoker, invokeSpecializations); + sb.append("name='"). + append(name.isEmpty() ? "" : name). + append("' "). + append(code.size()). + append(" invokers="). + append(code); + + return sb.toString(); } /** - * Get the method handle used to invoke this function as a constructor. - * @return the constructor handle + * Pick the best invoker, i.e. the one version of this method with as narrow and specific + * types as possible. If the call site arguments are objects, but boxed primitives we can + * also try to get a primitive version of the method and do an unboxing filter, but then + * we need to insert a guard that checks the argument is really always a boxed primitive + * and not suddenly a "real" object + * + * @param callSiteType callsite type + * @param args arguments at callsite on first trampoline invocation + * @return method handle to best invoker */ - private MethodHandle getConstructor() { - if (constructor == null) { - constructor = composeConstructor(invoker); - } - - return constructor; + MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) { + return getBest(callSiteType).getInvoker(); } - MethodHandle getBestConstructor(MethodType descType) { + MethodHandle getBestInvoker(final MethodType callSiteType) { + return getBestInvoker(callSiteType, null); + } + + MethodHandle getBestConstructor(final MethodType callSiteType, final Object[] args) { if (!isConstructor()) { throw typeError("not.a.constructor", toSource()); } - return SpecializedMethodChooser.candidateWithLowestWeight(descType, getConstructor(), getConstructSpecializations()); + ensureCodeGenerated(); + + final CompiledFunction best = getBest(callSiteType); + ensureConstructor(best); + return best.getConstructor(); } - private MethodHandle composeConstructor(MethodHandle ctor) { + MethodHandle getBestConstructor(final MethodType callSiteType) { + return getBestConstructor(callSiteType, null); + } + + /** + * Subclass responsibility. If we can have lazy code generation, this is a hook to ensure that + * code exists before performing an operation. + */ + protected void ensureCodeGenerated() { + //empty + } + + /** + * Return a generic Object/Object invoker for this method. It will ensure code + * is generated, get the most generic of all versions of this function and adapt it + * to Objects. + * + * TODO this is only public because {@link JavaAdapterFactory} can't supply us with + * a MethodType that we can use for lookup due to boostrapping problems. Can be fixed + * + * @return generic invoker of this script function + */ + public final MethodHandle getGenericInvoker() { + ensureCodeGenerated(); + return composeGenericMethod(code.mostGeneric().getInvoker()); + } + + private CompiledFunction getBest(final MethodType callSiteType) { + ensureCodeGenerated(); + return code.best(callSiteType); + } + + /** + * Allocates an object using this function's allocator. + * @return the object allocated using this function's allocator, or null if the function doesn't have an allocator. + */ + ScriptObject allocate() { + return null; + } + + /** + * This method is used to create the immutable portion of a bound function. + * See {@link ScriptFunction#makeBoundFunction(Object, Object[])} + * + * @param fn the original function being bound + * @param self this reference to bind. Can be null. + * @param args additional arguments to bind. Can be null. + */ + ScriptFunctionData makeBoundFunctionData(final ScriptFunction fn, final Object self, final Object[] args) { + ensureCodeGenerated(); + + final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args; + final int length = args == null ? 0 : args.length; + + CompiledFunctions boundList = new CompiledFunctions(); + for (final CompiledFunction inv : code) { + boundList.add(bind(inv, fn, self, allArgs)); + } + ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor()); + return boundData; + } + + /** + * Compose a constructor given a primordial constructor handle + * + * @param ctor primordial constructor handle + * @param needsCallee do we need to pass a callee + * + * @return the composed constructor + */ + protected MethodHandle composeConstructor(final MethodHandle ctor, final boolean needsCallee) { // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having // "this" in the first argument position is what allows the elegant folded composition of // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor // always returns Object. - MethodHandle composedCtor = changeReturnTypeToObject(swapCalleeAndThis(ctor)); + MethodHandle composedCtor = needsCallee ? swapCalleeAndThis(ctor) : ctor; + + composedCtor = changeReturnTypeToObject(composedCtor); final MethodType ctorType = composedCtor.type(); + // Construct a dropping type list for NEWFILTER, but don't include constructor "this" into it, so it's actually // captured as "allocation" parameter of NEWFILTER after we fold the constructor into it. // (this, [callee, ]args...) => ([callee, ]args...) final Class[] ctorArgs = ctorType.dropParameterTypes(0, 1).parameterArray(); + // Fold constructor into newFilter that replaces the return value from the constructor with the originally // allocated value when the originally allocated value is a primitive. // (result, this, [callee, ]args...) x (this, [callee, ]args...) => (this, [callee, ]args...) composedCtor = MH.foldArguments(MH.dropArguments(NEWFILTER, 2, ctorArgs), composedCtor); // allocate() takes a ScriptFunction and returns a newly allocated ScriptObject... - if (needsCallee()) { + if (needsCallee) { // ...we either fold it into the previous composition, if we need both the ScriptFunction callee object and // the newly allocated object in the arguments, so (this, callee, args...) x (callee) => (callee, args...), // or... return MH.foldArguments(composedCtor, ScriptFunction.ALLOCATE); } + // ...replace the ScriptFunction argument with the newly allocated object, if it doesn't need the callee // (this, args...) filter (callee) => (callee, args...) return MH.filterArguments(composedCtor, 0, ScriptFunction.ALLOCATE); } /** - * Get an adapted version of the invoker handle that only uses {@code Object} as parameter and return types. - * @return the generic invoke handle + * If this function's method handles need a callee parameter, swap the order of first two arguments for the passed + * method handle. If this function's method handles don't need a callee parameter, returns the original method + * handle unchanged. + * + * @param mh a method handle with order of arguments {@code (callee, this, args...)} + * + * @return a method handle with order of arguments {@code (this, callee, args...)} */ - private MethodHandle getGenericInvoker() { - if (genericInvoker == null) { - assert invoker != null : "invoker is null"; - genericInvoker = makeGenericMethod(invoker); + private static MethodHandle swapCalleeAndThis(final MethodHandle mh) { + final MethodType type = mh.type(); + assert type.parameterType(0) == ScriptFunction.class : type; + assert type.parameterType(1) == Object.class : type; + final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class); + final int[] reorder = new int[type.parameterCount()]; + reorder[0] = 1; + assert reorder[1] == 0; + for (int i = 2; i < reorder.length; ++i) { + reorder[i] = i; } - return genericInvoker; + return MethodHandles.permuteArguments(mh, newType, reorder); + } + + /** + * Convert this argument for non-strict functions according to ES 10.4.3 + * + * @param thiz the this argument + * + * @return the converted this object + */ + private Object convertThisObject(final Object thiz) { + if (!(thiz instanceof ScriptObject) && needsWrappedThis()) { + if (JSType.nullOrUndefined(thiz)) { + return Context.getGlobalTrusted(); + } + + if (isPrimitiveThis(thiz)) { + return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz); + } + } + + return thiz; + } + + static boolean isPrimitiveThis(final Object obj) { + return obj instanceof String || obj instanceof ConsString || + obj instanceof Number || obj instanceof Boolean; + } + + /** + * Creates an invoker method handle for a bound function. + * + * @param targetFn the function being bound + * @param originalInvoker an original invoker method handle for the function. This can be its generic invoker or + * any of its specializations. + * @param self the "this" value being bound + * @param args additional arguments being bound + * + * @return a bound invoker method handle that will bind the self value and the specified arguments. The resulting + * invoker never needs a callee; if the original invoker needed it, it will be bound to {@code fn}. The resulting + * invoker still takes an initial {@code this} parameter, but it is always dropped and the bound {@code self} passed + * to the original invoker on invocation. + */ + private MethodHandle bindInvokeHandle(final MethodHandle originalInvoker, final ScriptFunction targetFn, final Object self, final Object[] args) { + // Is the target already bound? If it is, we won't bother binding either callee or self as they're already bound + // in the target and will be ignored anyway. + final boolean isTargetBound = targetFn.isBoundFunction(); + + final boolean needsCallee = needsCallee(originalInvoker); + assert needsCallee == needsCallee() : "callee contract violation 2"; + assert !(isTargetBound && needsCallee); // already bound functions don't need a callee + + final Object boundSelf = isTargetBound ? null : convertThisObject(self); + final MethodHandle boundInvoker; + + if (isVarArg(originalInvoker)) { + // First, bind callee and this without arguments + final MethodHandle noArgBoundInvoker; + + if (isTargetBound) { + // Don't bind either callee or this + noArgBoundInvoker = originalInvoker; + } else if (needsCallee) { + // Bind callee and this + noArgBoundInvoker = MH.insertArguments(originalInvoker, 0, targetFn, boundSelf); + } else { + // Only bind this + noArgBoundInvoker = MH.bindTo(originalInvoker, boundSelf); + } + // Now bind arguments + if (args.length > 0) { + boundInvoker = varArgBinder(noArgBoundInvoker, args); + } else { + boundInvoker = noArgBoundInvoker; + } + } else { + final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount(), args.length + (isTargetBound ? 0 : (needsCallee ? 2 : 1)))]; + int next = 0; + if (!isTargetBound) { + if (needsCallee) { + boundArgs[next++] = targetFn; + } + boundArgs[next++] = boundSelf; + } + // If more bound args were specified than the function can take, we'll just drop those. + System.arraycopy(args, 0, boundArgs, next, boundArgs.length - next); + // If target is already bound, insert additional bound arguments after "this" argument, at position 1; + // "this" will get dropped anyway by the target invoker. We previously asserted that already bound functions + // don't take a callee parameter, so we can know that the signature is (this[, args...]) therefore args + // start at position 1. If the function is not bound, we start inserting arguments at position 0. + boundInvoker = MH.insertArguments(originalInvoker, isTargetBound ? 1 : 0, boundArgs); + } + + if (isTargetBound) { + return boundInvoker; + } + + // If the target is not already bound, add a dropArguments that'll throw away the passed this + return MH.dropArguments(boundInvoker, 0, Object.class); + } + + /** + * Creates a constructor method handle for a bound function using the passed constructor handle. + * + * @param originalConstructor the constructor handle to bind. It must be a composed constructor. + * @param fn the function being bound + * @param args arguments being bound + * + * @return a bound constructor method handle that will bind the specified arguments. The resulting constructor never + * needs a callee; if the original constructor needed it, it will be bound to {@code fn}. The resulting constructor + * still takes an initial {@code this} parameter and passes it to the underlying original constructor. Finally, if + * this script function data object has no constructor handle, null is returned. + */ + private static MethodHandle bindConstructHandle(final MethodHandle originalConstructor, final ScriptFunction fn, final Object[] args) { + assert originalConstructor != null; + + // If target function is already bound, don't bother binding the callee. + final MethodHandle calleeBoundConstructor = fn.isBoundFunction() ? originalConstructor : + MH.dropArguments(MH.bindTo(originalConstructor, fn), 0, ScriptFunction.class); + + if (args.length == 0) { + return calleeBoundConstructor; + } + + if (isVarArg(calleeBoundConstructor)) { + return varArgBinder(calleeBoundConstructor, args); + } + + final Object[] boundArgs; + + final int maxArgCount = calleeBoundConstructor.type().parameterCount() - 1; + if (args.length <= maxArgCount) { + boundArgs = args; + } else { + boundArgs = new Object[maxArgCount]; + System.arraycopy(args, 0, boundArgs, 0, maxArgCount); + } + + return MH.insertArguments(calleeBoundConstructor, 1, boundArgs); + } + + /** + * Takes a method handle, and returns a potentially different method handle that can be used in + * {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}. + * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into + * {@code Object} as well, except for the following ones: + *

    + *
  • a last parameter of type {@code Object[]} which is used for vararg functions,
  • + *
  • the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself + * (callee) as an argument.
  • + *
+ * + * @param mh the original method handle + * + * @return the new handle, conforming to the rules above. + */ + protected MethodHandle composeGenericMethod(final MethodHandle mh) { + final MethodType type = mh.type(); + MethodType newType = type.generic(); + if (isVarArg(mh)) { + newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class); + } + if (needsCallee(mh)) { + newType = newType.changeParameterType(0, ScriptFunction.class); + } + return type.equals(newType) ? mh : mh.asType(newType); } /** * Execute this script function. + * * @param self Target object. * @param arguments Call arguments. * @return ScriptFunction result. + * * @throws Throwable if there is an exception/error with the invocation or thrown from it */ Object invoke(final ScriptFunction fn, final Object self, final Object... arguments) throws Throwable { - final MethodHandle genInvoker = getGenericInvoker(); - final Object selfObj = convertThisObject(self); - final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; + final MethodHandle mh = getGenericInvoker(); - if (isVarArg()) { - if (needsCallee()) { - return genInvoker.invokeExact(fn, selfObj, args); + final Object selfObj = convertThisObject(self); + final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; + + if (isVarArg(mh)) { + if (needsCallee(mh)) { + return mh.invokeExact(fn, selfObj, args); } - return genInvoker.invokeExact(selfObj, args); + return mh.invokeExact(selfObj, args); } - final int paramCount = genInvoker.type().parameterCount(); - if (needsCallee()) { + final int paramCount = mh.type().parameterCount(); + if (needsCallee(mh)) { switch (paramCount) { case 2: - return genInvoker.invokeExact(fn, selfObj); + return mh.invokeExact(fn, selfObj); case 3: - return genInvoker.invokeExact(fn, selfObj, getArg(args, 0)); + return mh.invokeExact(fn, selfObj, getArg(args, 0)); case 4: - return genInvoker.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1)); + return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1)); case 5: - return genInvoker.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); + return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); default: - return genInvoker.invokeWithArguments(withArguments(fn, selfObj, paramCount, args)); + return mh.invokeWithArguments(withArguments(fn, selfObj, paramCount, args)); } } switch (paramCount) { case 1: - return genInvoker.invokeExact(selfObj); + return mh.invokeExact(selfObj); case 2: - return genInvoker.invokeExact(selfObj, getArg(args, 0)); + return mh.invokeExact(selfObj, getArg(args, 0)); case 3: - return genInvoker.invokeExact(selfObj, getArg(args, 0), getArg(args, 1)); + return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1)); case 4: - return genInvoker.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); + return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); default: - return genInvoker.invokeWithArguments(withArguments(null, selfObj, paramCount, args)); + return mh.invokeWithArguments(withArguments(null, selfObj, paramCount, args)); } } @@ -389,15 +537,13 @@ public final class ScriptFunctionData { return i < args.length ? args[i] : UNDEFINED; } - private Object[] withArguments(final ScriptFunction fn, final Object self, final int argCount, final Object[] args) { + private static Object[] withArguments(final ScriptFunction fn, final Object self, final int argCount, final Object[] args) { final Object[] finalArgs = new Object[argCount]; int nextArg = 0; - if (needsCallee()) { - assert fn != null; + if (fn != null) { + //needs callee finalArgs[nextArg++] = fn; - } else { - assert fn == null; } finalArgs[nextArg++] = self; @@ -413,255 +559,14 @@ public final class ScriptFunctionData { return finalArgs; } - - /** - * Get the specialized construct handles for this function. - * @return array of specialized construct handles - */ - private MethodHandle[] getConstructSpecializations() { - if(constructSpecializations == null && invokeSpecializations != null) { - final MethodHandle[] ctors = new MethodHandle[invokeSpecializations.length]; - for(int i = 0; i < ctors.length; ++i) { - ctors[i] = composeConstructor(invokeSpecializations[i]); - } - constructSpecializations = ctors; - } - return constructSpecializations; - } - - /** - * Set the method handles for this function. - * @param invoker the invoker handle - * @param allocator the allocator handle - */ - public void setMethodHandles(final MethodHandle invoker, final MethodHandle allocator) { - // We can't make method handle fields final because they're not available during codegen - // and they're set when first called, so we enforce set-once here. - if (this.invoker == null) { - this.invoker = invoker; - this.constructor = null; // delay constructor composition - this.allocator = allocator; - } - } - - /** - * Used by the trampoline. Must not be any wider than package - * private - * @param invoker new invoker - */ - void resetInvoker(final MethodHandle invoker) { - this.invoker = invoker; - this.constructor = null; //delay constructor composition - } - - /** - * Allocates an object using this function's allocator. - * @return the object allocated using this function's allocator, or null if the function doesn't have an allocator. - */ - ScriptObject allocate() { - if (allocator == null) { - return null; - } - - try { - return (ScriptObject)allocator.invokeExact(allocatorMap); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - } - - /** - * This method is used to create the immutable portion of a bound function. - * See {@link ScriptFunction#makeBoundFunction(Object, Object[])} - * - * @param fn the original function being bound - * @param self this reference to bind. Can be null. - * @param args additional arguments to bind. Can be null. - */ - ScriptFunctionData makeBoundFunctionData(final ScriptFunction fn, final Object self, final Object[] args) { - final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args; - - final boolean isConstructor = isConstructor(); - // Note that the new ScriptFunctionData's method handle will not need a callee regardless of whether the - // original did. - final ScriptFunctionData boundData = new ScriptFunctionData(name, source, token, - bindInvokeHandle(invoker, fn, self, allArgs), bindInvokeSpecializations(fn, self, allArgs), isStrict(), isBuiltin(), isConstructor); - if(isConstructor) { - // Can't just rely on bound invoke as a basis for constructor, as it ignores the passed "this" in favor of the - // bound "this"; constructor on the other hand must see the actual "this" received from the allocator. - - // Binding a function will force constructor composition in getConstructor(); not really any way around that - // as it's the composed constructor that has to be bound to the function. - boundData.constructor = bindConstructHandle(getConstructor(), fn, allArgs); - boundData.constructSpecializations = bindConstructorSpecializations(fn, allArgs); - } - assert boundData.allocator == null; - final int thisArity = getArity(); - if(thisArity != -1) { - boundData.setArity(Math.max(0, thisArity - args.length)); - } else { - assert boundData.getArity() == -1; - } - return boundData; - } - - /** - * Convert this argument for non-strict functions according to ES 10.4.3 - * - * @param thiz the this argument - * - * @return the converted this object - */ - Object convertThisObject(final Object thiz) { - if (!(thiz instanceof ScriptObject) && needsWrappedThis()) { - if (JSType.nullOrUndefined(thiz)) { - return Context.getGlobalTrusted(); - } - - if (isPrimitiveThis(thiz)) { - return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz); - } - } - - return thiz; - } - - static boolean isPrimitiveThis(Object obj) { - return obj instanceof String || obj instanceof ConsString || - obj instanceof Number || obj instanceof Boolean; - } - - /** - * Creates an invoker method handle for a bound function. - * @param targetFn the function being bound - * @param originalInvoker an original invoker method handle for the function. This can be its generic invoker or - * any of its specializations. - * @param self the "this" value being bound - * @param args additional arguments being bound - * @return a bound invoker method handle that will bind the self value and the specified arguments. The resulting - * invoker never needs a callee; if the original invoker needed it, it will be bound to {@code fn}. The resulting - * invoker still takes an initial {@code this} parameter, but it is always dropped and the bound {@code self} passed - * to the original invoker on invocation. - */ - private MethodHandle bindInvokeHandle(final MethodHandle originalInvoker, final ScriptFunction targetFn, final Object self, final Object[] args) { - // Is the target already bound? If it is, we won't bother binding either callee or self as they're already bound - // in the target and will be ignored anyway. - final boolean isTargetBound = targetFn.isBoundFunction(); - assert !(isTargetBound && needsCallee()); // already bound functions don't need a callee - final Object boundSelf = isTargetBound ? null : convertThisObject(self); - final MethodHandle boundInvoker; - if(isVarArg(originalInvoker)) { - // First, bind callee and this without arguments - final MethodHandle noArgBoundInvoker; - if(isTargetBound) { - // Don't bind either callee or this - noArgBoundInvoker = originalInvoker; - } else if(needsCallee()) { - // Bind callee and this - noArgBoundInvoker = MH.insertArguments(originalInvoker, 0, targetFn, boundSelf); - } else { - // Only bind this - noArgBoundInvoker = MH.bindTo(originalInvoker, boundSelf); - } - // Now bind arguments - if(args.length > 0) { - boundInvoker = varArgBinder(noArgBoundInvoker, args); - } else { - boundInvoker = noArgBoundInvoker; - } - } else { - final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount(), - args.length + (isTargetBound ? 0 : (needsCallee() ? 2 : 1)))]; - int next = 0; - if(!isTargetBound) { - if(needsCallee()) { - boundArgs[next++] = targetFn; - } - boundArgs[next++] = boundSelf; - } - // If more bound args were specified than the function can take, we'll just drop those. - System.arraycopy(args, 0, boundArgs, next, boundArgs.length - next); - // If target is already bound, insert additional bound arguments after "this" argument, at position 1; - // "this" will get dropped anyway by the target invoker. We previously asserted that already bound functions - // don't take a callee parameter, so we can know that the signature is (this[, args...]) therefore args - // start at position 1. If the function is not bound, we start inserting arguments at position 0. - boundInvoker = MH.insertArguments(originalInvoker, isTargetBound ? 1 : 0, boundArgs); - } - if(isTargetBound) { - return boundInvoker; - } - // If the target is not already bound, add a dropArguments that'll throw away the passed this - return MH.dropArguments(boundInvoker, 0, Object.class); - } - - private MethodHandle[] bindInvokeSpecializations(final ScriptFunction fn, final Object self, final Object[] args) { - if(invokeSpecializations == null) { - return null; - } - final MethodHandle[] boundSpecializations = new MethodHandle[invokeSpecializations.length]; - for(int i = 0; i < invokeSpecializations.length; ++i) { - boundSpecializations[i] = bindInvokeHandle(invokeSpecializations[i], fn, self, args); - } - return boundSpecializations; - } - - /** - * Creates a constructor method handle for a bound function using the passed constructor handle. - * @param originalConstructor the constructor handle to bind. It must be a composed constructor. - * @param fn the function being bound - * @param args arguments being bound - * @return a bound constructor method handle that will bind the specified arguments. The resulting constructor never - * needs a callee; if the original constructor needed it, it will be bound to {@code fn}. The resulting constructor - * still takes an initial {@code this} parameter and passes it to the underlying original constructor. Finally, if - * this script function data object has no constructor handle, null is returned. - */ - private static MethodHandle bindConstructHandle(final MethodHandle originalConstructor, final ScriptFunction fn, final Object[] args) { - if(originalConstructor == null) { - return null; - } - - // If target function is already bound, don't bother binding the callee. - final MethodHandle calleeBoundConstructor = fn.isBoundFunction() ? originalConstructor : - MH.dropArguments(MH.bindTo(originalConstructor, fn), 0, ScriptFunction.class); - if(args.length == 0) { - return calleeBoundConstructor; - } - - if(isVarArg(calleeBoundConstructor)) { - return varArgBinder(calleeBoundConstructor, args); - } - - final Object[] boundArgs; - final int maxArgCount = calleeBoundConstructor.type().parameterCount() - 1; - if (args.length <= maxArgCount) { - boundArgs = args; - } else { - boundArgs = new Object[maxArgCount]; - System.arraycopy(args, 0, boundArgs, 0, maxArgCount); - } - return MH.insertArguments(calleeBoundConstructor, 1, boundArgs); - } - - private MethodHandle[] bindConstructorSpecializations(final ScriptFunction fn, final Object[] args) { - final MethodHandle[] ctorSpecs = getConstructSpecializations(); - if(ctorSpecs == null) { - return null; - } - final MethodHandle[] boundSpecializations = new MethodHandle[ctorSpecs.length]; - for(int i = 0; i < ctorSpecs.length; ++i) { - boundSpecializations[i] = bindConstructHandle(ctorSpecs[i], fn, args); - } - return boundSpecializations; - } - /** * Takes a variable-arity method and binds a variable number of arguments in it. The returned method will filter the * vararg array and pass a different array that prepends the bound arguments in front of the arguments passed on * invocation + * * @param mh the handle * @param args the bound arguments + * * @return the bound method handle */ private static MethodHandle varArgBinder(final MethodHandle mh, final Object[] args) { @@ -670,99 +575,10 @@ public final class ScriptFunctionData { return MH.filterArguments(mh, mh.type().parameterCount() - 1, MH.bindTo(BIND_VAR_ARGS, args)); } - /** - * Convert boolean flags to int. - * @param needsCallee needs-callee flag - * @param isVarArg var-arg flag - * @param isStrict strict flag - * @param isBuiltin builtin flag - * @return int flags - */ - private static int makeFlags(final boolean needsCallee, final boolean isVarArg, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) { - int flags = 0; - if (needsCallee) { - flags |= HAS_CALLEE; - } - if (isVarArg) { - flags |= IS_VARARGS; - } - if (isStrict) { - flags |= IS_STRICT; - } - if (isBuiltin) { - flags |= IS_BUILTIN; - } - if (isConstructor) { - flags |= IS_CONSTRUCTOR; - } - - return flags; - } - - /** - * Test if a methodHandle refers to a constructor. - * @param methodHandle MethodHandle to test. - * @return True if method is a constructor. - */ - private static boolean isConstructor(final MethodHandle methodHandle) { - return methodHandle.type().parameterCount() >= 1 && methodHandle.type().parameterType(0) == boolean.class; - } - - /** - * 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 - * 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. - * @param methodHandle the examined method handle - * @return true if the method handle expects a callee, false otherwise - */ - private static boolean needsCallee(MethodHandle methodHandle) { - final MethodType type = methodHandle.type(); - final int len = type.parameterCount(); - if(len == 0) { - return false; - } - if(type.parameterType(0) == boolean.class) { - return len > 1 && type.parameterType(1) == ScriptFunction.class; - } - return type.parameterType(0) == ScriptFunction.class; - } - - private static boolean isVarArg(MethodHandle methodHandle) { - final MethodType type = methodHandle.type(); - return type.parameterType(type.parameterCount() - 1).isArray(); - } - - /** - * Takes a method handle, and returns a potentially different method handle that can be used in - * {@link ScriptFunction#invoke(Object, Object...)} or {@link ScriptFunction#construct(Object, Object...)}. - * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into - * {@code Object} as well, except for the following ones: - *
    - *
  • a last parameter of type {@code Object[]} which is used for vararg functions,
  • - *
  • the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself - * (callee) as an argument.
  • - *
- * - * @param handle the original method handle - * @return the new handle, conforming to the rules above. - */ - private MethodHandle makeGenericMethod(final MethodHandle handle) { - final MethodType type = handle.type(); - MethodType newType = type.generic(); - if (isVarArg()) { - newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class); - } - if (needsCallee()) { - newType = newType.changeParameterType(0, ScriptFunction.class); - } - return type.equals(newType) ? handle : handle.asType(newType); - } - /** * Adapts the method handle so its return type is {@code Object}. If the handle's return type is already * {@code Object}, the handle is returned unchanged. + * * @param mh the handle to adapt * @return the adapted handle */ @@ -770,45 +586,67 @@ public final class ScriptFunctionData { return MH.asType(mh, mh.type().changeReturnType(Object.class)); } + private void ensureConstructor(final CompiledFunction inv) { + if (!inv.hasConstructor()) { + inv.setConstructor(composeConstructor(inv.getInvoker(), needsCallee(inv.getInvoker()))); + } + } /** - * If this function's method handles need a callee parameter, swap the order of first two arguments for the passed - * method handle. If this function's method handles don't need a callee parameter, returns the original method - * handle unchanged. - * @param mh a method handle with order of arguments {@code (callee, this, args...)} - * @return a method handle with order of arguments {@code (this, callee, args...)} + * 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 + * 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). + * + * @param mh the examined method handle + * + * @return true if the method handle expects a callee, false otherwise */ - private MethodHandle swapCalleeAndThis(final MethodHandle mh) { - if (!needsCallee()) { - return mh; + protected static boolean needsCallee(final MethodHandle mh) { + final MethodType type = mh.type(); + final int length = type.parameterCount(); + + if (length == 0) { + return false; } + + if (type.parameterType(0) == boolean.class) { + return length > 1 && type.parameterType(1) == ScriptFunction.class; + } + + return type.parameterType(0) == ScriptFunction.class; + } + + /** + * Check if a javascript function methodhandle is a vararg handle + * + * @param mh method handle to check + * + * @return true if vararg + */ + protected static boolean isVarArg(final MethodHandle mh) { final MethodType type = mh.type(); - assert type.parameterType(0) == ScriptFunction.class; - assert type.parameterType(1) == Object.class; - final MethodType newType = type.changeParameterType(0, Object.class).changeParameterType(1, ScriptFunction.class); - final int[] reorder = new int[type.parameterCount()]; - reorder[0] = 1; - assert reorder[1] == 0; - for (int i = 2; i < reorder.length; ++i) { - reorder[i] = i; - } - return MethodHandles.permuteArguments(mh, newType, reorder); + return type.parameterType(type.parameterCount() - 1).isArray(); } @SuppressWarnings("unused") private static Object[] bindVarArgs(final Object[] array1, final Object[] array2) { - if(array2 == null) { + if (array2 == null) { // Must clone it, as we can't allow the receiving method to alter the array return array1.clone(); } + final int l2 = array2.length; - if(l2 == 0) { + if (l2 == 0) { return array1.clone(); } + final int l1 = array1.length; final Object[] concat = new Object[l1 + l2]; System.arraycopy(array1, 0, concat, 0, l1); System.arraycopy(array2, 0, concat, l1, l2); + return concat; } @@ -820,5 +658,4 @@ public final class ScriptFunctionData { private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { return MH.findStatic(MethodHandles.lookup(), ScriptFunctionData.class, name, MH.type(rtype, types)); } - } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java b/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java deleted file mode 100644 index 2853cdf2464..00000000000 --- a/nashorn/src/jdk/nashorn/internal/runtime/SpecializedMethodChooser.java +++ /dev/null @@ -1,99 +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.runtime; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.runtime.options.Options; - -class SpecializedMethodChooser { - /** Should specialized function and specialized constructors for the builtin be used if available? */ - private static final boolean DISABLE_SPECIALIZATION = Options.getBooleanProperty("nashorn.scriptfunction.specialization.disable"); - - static MethodHandle candidateWithLowestWeight(final MethodType descType, final MethodHandle initialCandidate, final MethodHandle[] specs) { - if (DISABLE_SPECIALIZATION || specs == null) { - return initialCandidate; - } - - int minimumWeight = Integer.MAX_VALUE; - MethodHandle candidate = initialCandidate; - - for (final MethodHandle spec : specs) { - final MethodType specType = spec.type(); - - if (!typeCompatible(descType, specType)) { - continue; - } - - //return type is ok. we want a wider or equal one for our callsite. - final int specWeight = weigh(specType); - if (specWeight < minimumWeight) { - candidate = spec; - minimumWeight = specWeight; - } - } - - return candidate; - } - - private static boolean typeCompatible(final MethodType desc, final MethodType spec) { - //spec must fit in desc - final Class[] dparray = desc.parameterArray(); - final Class[] sparray = spec.parameterArray(); - - if (dparray.length != sparray.length) { - return false; - } - - for (int i = 0; i < dparray.length; i++) { - final Type dp = Type.typeFor(dparray[i]); - final Type sp = Type.typeFor(sparray[i]); - - if (dp.isBoolean()) { - return false; //don't specialize on booleans, we have the "true" vs int 1 ambiguity in resolution - } - - //specialization arguments must be at least as wide as dp, if not wider - if (Type.widest(dp, sp) != sp) { - //e.g. specialization takes double and callsite says "object". reject. - //but if specialization says double and callsite says "int" or "long" or "double", that's fine - return false; - } - } - - return true; // anything goes for return type, take the convenient one and it will be upcasted thru dynalink magic. - } - - private static int weigh(final MethodType t) { - int weight = Type.typeFor(t.returnType()).getWeight(); - for (final Class paramType : t.parameterArray()) { - final int pweight = Type.typeFor(paramType).getWeight(); - weight += pweight; - } - return weight; - } -} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java index 3d8363e10d9..834898afbf7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java @@ -39,7 +39,7 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; /** - * Utility class shared by {@link NashornLinker} and {@code NashornPrimitiveLinker} for converting JS values to Java + * Utility class shared by {@code NashornLinker} and {@code NashornPrimitiveLinker} for converting JS values to Java * types. */ public class JavaArgumentConverters { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java index ed152485376..a8e79184d85 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java @@ -40,8 +40,6 @@ public final class NashornGuards { private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class); private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class); private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class); - private static final MethodHandle IS_FUNCTION_MH = findOwnMH("isFunctionMH", boolean.class, Object.class, MethodHandle.class); - private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, MethodHandle.class); private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class); // don't create me! @@ -87,33 +85,6 @@ public final class NashornGuards { return MH.insertArguments(IS_INSTANCEOF_2, 1, class1, class2); } - /** - * Get the guard that checks if a {@link ScriptFunction} is equal to - * a known ScriptFunction, using reference comparison - * - * @param function The ScriptFunction to check against. This will be bound to the guard method handle - * - * @return method handle for guard - */ - public static MethodHandle getFunctionGuard(final ScriptFunction function) { - assert function.getInvokeHandle() != null; - return MH.insertArguments(IS_FUNCTION_MH, 1, function.getInvokeHandle()); - } - - /** - * Get a guard that checks if a {@link ScriptFunction} is equal to - * a known ScriptFunction using reference comparison, and whether the type of - * the second argument (this-object) is not a JavaScript primitive type. - * - * @param function The ScriptFunction to check against. This will be bound to the guard method handle - * - * @return method handle for guard - */ - public static MethodHandle getNonStrictFunctionGuard(final ScriptFunction function) { - assert function.getInvokeHandle() != null; - return MH.insertArguments(IS_NONSTRICT_FUNCTION, 2, function.getInvokeHandle()); - } - @SuppressWarnings("unused") private static boolean isScriptObject(final Object self) { return self instanceof ScriptObject; @@ -129,16 +100,6 @@ public final class NashornGuards { return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map; } - @SuppressWarnings("unused") - private static boolean isFunctionMH(final Object self, final MethodHandle mh) { - return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh; - } - - @SuppressWarnings("unused") - private static boolean isNonStrictFunction(final Object self, final Object arg, final MethodHandle mh) { - return self instanceof ScriptFunction && ((ScriptFunction)self).getInvokeHandle() == mh && arg instanceof ScriptObject; - } - @SuppressWarnings("unused") private static boolean isInstanceOf2(final Object self, final Class class1, final Class class2) { return class1.isInstance(self) || class2.isInstance(self); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java index 82b6edbc600..16ff04eaa41 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java @@ -278,7 +278,7 @@ public class OptionTemplate implements Comparable { this.valueNextArg = Boolean.parseBoolean(arg); break; default: - throw new IllegalArgumentException(); + throw new IllegalArgumentException(keyToken); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties index 534eb1778e6..e63f7a3769d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties @@ -165,6 +165,12 @@ nashorn.option.debug.locals = { \ desc="Generate local variable table in .class files." \ } +nashorn.option.lazy.compilation = { \ + name="--lazy-compilation", \ + is_undocumented=true, \ + desc="EXPERIMENTAL: Use lazy code generation strategies - do not compile the entire script at once." \ +} + nashorn.option.loader.per.compile = { \ name="--loader-per-compile", \ is_undocumented=true, \ diff --git a/nashorn/test/script/currently-failing/JDK-8006529.js b/nashorn/test/script/currently-failing/JDK-8006529.js index da08d2b516b..ca21f0b9c48 100644 --- a/nashorn/test/script/currently-failing/JDK-8006529.js +++ b/nashorn/test/script/currently-failing/JDK-8006529.js @@ -39,12 +39,13 @@ * and FunctionNode because of package-access check and so reflective calls. */ -var Parser = Java.type("jdk.nashorn.internal.parser.Parser") -var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") -var Context = Java.type("jdk.nashorn.internal.runtime.Context") +var Parser = Java.type("jdk.nashorn.internal.parser.Parser") +var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") +var Context = Java.type("jdk.nashorn.internal.runtime.Context") var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment") -var Source = Java.type("jdk.nashorn.internal.runtime.Source") -var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode") +var Source = Java.type("jdk.nashorn.internal.runtime.Source") +var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode") +var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager"); // Compiler class methods and fields var parseMethod = Parser.class.getMethod("parse"); @@ -90,7 +91,7 @@ function getFirstFunction(functionNode) { // representing it. function compile(source) { var source = new Source("", source); - var parser = new Parser(Context.getContext().getEnv(), source, null); + var parser = new Parser(Context.getContext().getEnv(), source, new ThrowErrorManager()); var func = parseMethod.invoke(parser); var compiler = new Compiler(Context.getContext().getEnv(), func); diff --git a/nashorn/test/script/currently-failing/clone_ir.js b/nashorn/test/script/currently-failing/clone_ir.js new file mode 100644 index 00000000000..3c1eccf2bc3 --- /dev/null +++ b/nashorn/test/script/currently-failing/clone_ir.js @@ -0,0 +1,100 @@ +/* + * 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. + */ + +/** + * clone_ir : Check that functionNode.clone copies all nodes and that they + * are not the same references + * + * @test + * @run + */ + +var js1 = "var tuple = { func : function f(x) { if (x) { print('true'); { print('block_under-true'); } } else { print('false'); } } }"; + +var Parser = Java.type("jdk.nashorn.internal.parser.Parser"); +var ASTWriter = Java.type("jdk.nashorn.internal.ir.debug.ASTWriter"); +var Context = Java.type("jdk.nashorn.internal.runtime.Context"); +var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment"); +var Source = Java.type("jdk.nashorn.internal.runtime.Source"); +var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode"); +var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager"); +var System = Java.type("java.lang.System"); + +var toArrayMethod = ASTWriter.class.getMethod("toArray"); +var parseMethod = Parser.class.getMethod("parse"); + +function toString(obj) { + var output = "{ "; + for (property in obj) { + output += property + ': ' + obj[property]+'; '; + } + return output + '}' +} + +function flatten(func) { + var writer = new ASTWriter(func); + var funcList = toArrayMethod.invoke(writer); + + var res = []; + for each (x in funcList) { + res.push({ name: x.getClass().getName(), id: System.identityHashCode(x) }); + } + return res; +} + +function check(contents) { + return check_src(new Source("", contents)); +} + +function check_src(src) { + var parser = new Parser(Context.getContext().getEnv(), src, new ThrowErrorManager()); + + var func = parseMethod.invoke(parser); + print(func); + var func2 = func.clone(); + + var f1 = flatten(func); + var f2 = flatten(func2); + + print(f1.map(toString)); + print(f2.map(toString)); + + if (f1.length != f2.length) { + print("length difference between original and clone " + f1.length + " != " + f2.length); + return false; + } + + for (var i = 0; i < f1.length; i++) { + if (f1[i].name !== f2[i].name) { + print("name conflict at " + i + " " + f1[i].name + " != " + f2[i].name); + return false; + } else if (f1[i].id === f2[i].id) { + print("id problem at " + i + " " + toString(f1[i]) + " was not deep copied to " + toString(f2[i]) + " became " + f1[i].id + " != " + f2[i].id); + return false; + } + } + + return true; +} + +print(check(js1)); From d671cda73c206159122d02664cc301d32e0681d2 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 12 Mar 2013 21:17:47 +0530 Subject: [PATCH 005/137] 8009868: For loop with "true" as condition results in AssertionError in codegen Reviewed-by: jlaskey, hannesw, lagergren --- .../jdk/nashorn/internal/codegen/Lower.java | 1 + nashorn/test/script/basic/JDK-8009868.js | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8009868.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index 4be28193cc7..5baa7af535e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -237,6 +237,7 @@ final class Lower extends NodeOperatorVisitor { if (!forNode.isForIn() && conservativeAlwaysTrue(test)) { forNode.setTest(null); + setHasGoto(forNode); setTerminal(forNode, !escapes); } diff --git a/nashorn/test/script/basic/JDK-8009868.js b/nashorn/test/script/basic/JDK-8009868.js new file mode 100644 index 00000000000..ffbc8c21871 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8009868.js @@ -0,0 +1,35 @@ +/* + * 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-8009868: For loop with "true" as condition results in AssertionError in codegen + * + * @test + * @run + */ + +// This used to crash with AssertionError in codegen +for(; true;) { + break; +} From b8b487dd5f53c28816aff386e2ffad7125d41b76 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Wed, 13 Mar 2013 13:22:02 +0400 Subject: [PATCH 006/137] 7190897: (fs) Files.isWritable method returns false when the path is writable (win) The [GetEffectiveRightsFromAcl] based implementation was changed to the [AccessCheck] based. Reviewed-by: alanb --- .../classes/sun/nio/fs/WindowsConstants.java | 5 ++ .../sun/nio/fs/WindowsFileSystemProvider.java | 76 +++++-------------- .../sun/nio/fs/WindowsNativeDispatcher.java | 39 +++++----- .../classes/sun/nio/fs/WindowsSecurity.java | 45 ++++++++--- .../sun/nio/fs/WindowsNativeDispatcher.c | 56 +++++++------- 5 files changed, 104 insertions(+), 117 deletions(-) diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java index 83becb4653b..eefd501f3bb 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsConstants.java @@ -181,6 +181,11 @@ class WindowsConstants { public static final int FILE_READ_ATTRIBUTES = 0x0080; public static final int FILE_WRITE_ATTRIBUTES = 0x0100; + public static final int FILE_GENERIC_READ = 0x00120089; + public static final int FILE_GENERIC_WRITE = 0x00120116; + public static final int FILE_GENERIC_EXECUTE = 0x001200a0; + public static final int FILE_ALL_ACCESS = 0x001f01ff; + // operating system security public static final int TOKEN_DUPLICATE = 0x0002; public static final int TOKEN_IMPERSONATE = 0x0004; diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java index 70a37309e9e..31b7c0f3674 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java @@ -38,6 +38,7 @@ import sun.nio.ch.ThreadPool; import sun.security.util.SecurityConstants; import static sun.nio.fs.WindowsNativeDispatcher.*; +import static sun.nio.fs.WindowsSecurity.*; import static sun.nio.fs.WindowsConstants.*; public class WindowsFileSystemProvider @@ -289,67 +290,29 @@ public class WindowsFileSystemProvider } /** - * Returns buffer with SID_AND_ATTRIBUTES structure representing the user - * associated with the current thread access token. - * FIXME - this should be cached. + * Checks the file security against desired access. */ - private static NativeBuffer getUserInfo(WindowsPath file) throws IOException { - try { - long hToken = WindowsSecurity.processTokenWithQueryAccess; - int size = GetTokenInformation(hToken, TokenUser, 0L, 0); - assert size > 0; - - NativeBuffer buffer = NativeBuffers.getNativeBuffer(size); - try { - int newsize = GetTokenInformation(hToken, TokenUser, - buffer.address(), size); - if (newsize != size) - throw new AssertionError(); - return buffer; - } catch (WindowsException x) { - buffer.release(); - throw x; - } - } catch (WindowsException x) { - throw new IOException(x.getMessage()); - } - } - - /** - * Reads the file ACL and return the effective access as ACCESS_MASK - */ - private static int getEffectiveAccess(WindowsPath file) throws IOException { - // read security descriptor continaing ACL (symlinks are followed) + private static boolean hasDesiredAccess(WindowsPath file, int rights) throws IOException { + // read security descriptor containing ACL (symlinks are followed) + boolean hasRights = false; String target = WindowsLinkSupport.getFinalPath(file, true); NativeBuffer aclBuffer = WindowsAclFileAttributeView - .getFileSecurity(target, DACL_SECURITY_INFORMATION); - - // retrieves DACL from security descriptor - long pAcl = GetSecurityDescriptorDacl(aclBuffer.address()); - - // Use GetEffectiveRightsFromAcl to get effective access to file + .getFileSecurity(target, + DACL_SECURITY_INFORMATION + | OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION); try { - NativeBuffer userBuffer = getUserInfo(file); - try { - try { - // SID_AND_ATTRIBUTES->pSid - long pSid = unsafe.getAddress(userBuffer.address()); - long pTrustee = BuildTrusteeWithSid(pSid); - try { - return GetEffectiveRightsFromAcl(pAcl, pTrustee); - } finally { - LocalFree(pTrustee); - } - } catch (WindowsException x) { - throw new IOException("Unable to get effective rights from ACL: " + - x.getMessage()); - } - } finally { - userBuffer.release(); - } + hasRights = checkAccessMask(aclBuffer.address(), rights, + FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS); + } catch (WindowsException exc) { + exc.rethrowAsIOException(file); } finally { aclBuffer.release(); } + return hasRights; } /** @@ -416,10 +379,10 @@ public class WindowsFileSystemProvider mask |= FILE_EXECUTE; } - if ((getEffectiveAccess(file) & mask) == 0) + if (!hasDesiredAccess(file, mask)) throw new AccessDeniedException( file.getPathForExceptionMessage(), null, - "Effective permissions does not allow requested access"); + "Permissions does not allow requested access"); // for write access we neeed to check if the DOS readonly attribute // and if the volume is read-only @@ -438,7 +401,6 @@ public class WindowsFileSystemProvider throw new AccessDeniedException( file.getPathForExceptionMessage(), null, "Read-only file system"); } - return; } } diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java index 3d9f4973063..b0af243723a 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java @@ -844,6 +844,23 @@ class WindowsNativeDispatcher { static native void AdjustTokenPrivileges(long token, long luid, int attributes) throws WindowsException; + + /** + * AccessCheck( + * PSECURITY_DESCRIPTOR pSecurityDescriptor, + * HANDLE ClientToken, + * DWORD DesiredAccess, + * PGENERIC_MAPPING GenericMapping, + * PPRIVILEGE_SET PrivilegeSet, + * LPDWORD PrivilegeSetLength, + * LPDWORD GrantedAccess, + * LPBOOL AccessStatus + * ) + */ + static native boolean AccessCheck(long token, long securityInfo, int accessMask, + int genericRead, int genericWrite, int genericExecute, int genericAll) + throws WindowsException; + /** */ static long LookupPrivilegeValue(String name) throws WindowsException { @@ -857,28 +874,6 @@ class WindowsNativeDispatcher { private static native long LookupPrivilegeValue0(long lpName) throws WindowsException; - /** - * BuildTrusteeWithSid( - * PTRUSTEE pTrustee, - * PSID pSid - * ) - * - * @return pTrustee - */ - static native long BuildTrusteeWithSid(long pSid); - - /** - * GetEffectiveRightsFromAcl( - * PACL pacl, - * PTRUSTEE pTrustee, - * PACCESS_MASK pAccessRights - * ) - * - * @return AccessRights - */ - static native int GetEffectiveRightsFromAcl(long pAcl, long pTrustee) - throws WindowsException; - /** * CreateSymbolicLink( * LPCWSTR lpSymlinkFileName, diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java index 06351db05bf..ef9982e5d38 100644 --- a/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java +++ b/jdk/src/windows/classes/sun/nio/fs/WindowsSecurity.java @@ -105,19 +105,46 @@ class WindowsSecurity { return new Privilege() { @Override public void drop() { - try { - if (stopImpersontating) { - SetThreadToken(0L, 0L); - } else { - if (needToRevert) { + if (token != 0L) { + try { + if (stopImpersontating) + SetThreadToken(0L, 0L); + else if (needToRevert) AdjustTokenPrivileges(token, pLuid, 0); - } + } catch (WindowsException x) { + // should not happen + throw new AssertionError(x); + } finally { + CloseHandle(token); } - } catch (WindowsException x) { - // should not happen - throw new AssertionError(x); } } }; } + + /** + * Check the access right against the securityInfo in the current thread. + */ + static boolean checkAccessMask(long securityInfo, int accessMask, + int genericRead, int genericWrite, int genericExecute, int genericAll) + throws WindowsException + { + int privilegies = TOKEN_QUERY; + long hToken = OpenThreadToken(GetCurrentThread(), privilegies, false); + if (hToken == 0L && processTokenWithDuplicateAccess != 0L) + hToken = DuplicateTokenEx(processTokenWithDuplicateAccess, + privilegies); + + boolean hasRight = false; + if (hToken != 0L) { + try { + hasRight = AccessCheck(hToken, securityInfo, accessMask, + genericRead, genericWrite, genericExecute, genericAll); + } finally { + CloseHandle(hToken); + } + } + return hasRight; + } + } diff --git a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c index 5faf34d2458..9672b8525ad 100644 --- a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c +++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c @@ -1021,6 +1021,33 @@ Java_sun_nio_fs_WindowsNativeDispatcher_AdjustTokenPrivileges(JNIEnv* env, throwWindowsException(env, GetLastError()); } +JNIEXPORT jboolean JNICALL +Java_sun_nio_fs_WindowsNativeDispatcher_AccessCheck(JNIEnv* env, + jclass this, jlong token, jlong securityInfo, jint accessMask, + jint genericRead, jint genericWrite, jint genericExecute, jint genericAll) +{ + HANDLE hImpersonatedToken = (HANDLE)jlong_to_ptr(token); + PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)jlong_to_ptr(securityInfo); + DWORD checkAccessRights = (DWORD)accessMask; + GENERIC_MAPPING mapping = { + genericRead, + genericWrite, + genericExecute, + genericAll}; + PRIVILEGE_SET privileges = {0}; + DWORD privilegesLength = sizeof(privileges); + DWORD grantedAccess = 0; + BOOL result = FALSE; + + /* checkAccessRights is in-out parameter */ + MapGenericMask(&checkAccessRights, &mapping); + if (AccessCheck(security, hImpersonatedToken, checkAccessRights, + &mapping, &privileges, &privilegesLength, &grantedAccess, &result) == 0) + throwWindowsException(env, GetLastError()); + + return (result == FALSE) ? JNI_FALSE : JNI_TRUE; +} + JNIEXPORT jlong JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv* env, jclass this, jlong name) @@ -1037,35 +1064,6 @@ Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv* env, return ptr_to_jlong(pLuid); } -JNIEXPORT jlong JNICALL -Java_sun_nio_fs_WindowsNativeDispatcher_BuildTrusteeWithSid(JNIEnv* env, - jclass this, jlong sid) -{ - PSID pSid = (HANDLE)jlong_to_ptr(sid); - PTRUSTEE_W pTrustee = LocalAlloc(0, sizeof(TRUSTEE_W)); - - if (pTrustee == NULL) { - JNU_ThrowInternalError(env, "Unable to allocate TRUSTEE_W structure"); - } else { - BuildTrusteeWithSidW(pTrustee, pSid); - } - return ptr_to_jlong(pTrustee); -} - -JNIEXPORT jint JNICALL -Java_sun_nio_fs_WindowsNativeDispatcher_GetEffectiveRightsFromAcl(JNIEnv* env, - jclass this, jlong acl, jlong trustee) -{ - ACCESS_MASK access; - PACL pAcl = (PACL)jlong_to_ptr(acl); - PTRUSTEE pTrustee = (PTRUSTEE)jlong_to_ptr(trustee); - - if (GetEffectiveRightsFromAcl(pAcl, pTrustee, &access) != ERROR_SUCCESS) { - throwWindowsException(env, GetLastError()); - } - return (jint)access; -} - JNIEXPORT void JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env, jclass this, jlong linkAddress, jlong targetAddress, jint flags) From 0bcb468549cfaca5f12f9f0b1c7bd96b59552fe3 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Wed, 13 Mar 2013 17:58:45 +0000 Subject: [PATCH 007/137] 8009751: (se) Selector spin when select, close and interestOps(0) invoked at same time (lnx) Reviewed-by: zhouyx, chegar, robm --- .../classes/sun/nio/ch/EPollArrayWrapper.java | 275 ++++++++++-------- .../classes/sun/nio/ch/EPollSelectorImpl.java | 23 +- 2 files changed, 164 insertions(+), 134 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java index dc08340e46f..3b59a06ac03 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java @@ -26,9 +26,9 @@ package sun.nio.ch; import java.io.IOException; -import java.util.LinkedList; -import java.util.HashSet; -import java.util.Iterator; +import java.util.BitSet; +import java.util.HashMap; +import java.util.Map; /** * Manipulates a native array of epoll_event structs on Linux: @@ -52,37 +52,78 @@ import java.util.Iterator; * this implementation we set data.fd to be the file descriptor that we * register. That way, we have the file descriptor available when we * process the events. - * - * All file descriptors registered with epoll have the POLLHUP and POLLERR - * events enabled even when registered with an event set of 0. To ensure - * that epoll_wait doesn't poll an idle file descriptor when the underlying - * connection is closed or reset then its registration is deleted from - * epoll (it will be re-added again if the event set is changed) */ class EPollArrayWrapper { // EPOLL_EVENTS - static final int EPOLLIN = 0x001; + private static final int EPOLLIN = 0x001; // opcodes - static final int EPOLL_CTL_ADD = 1; - static final int EPOLL_CTL_DEL = 2; - static final int EPOLL_CTL_MOD = 3; + private static final int EPOLL_CTL_ADD = 1; + private static final int EPOLL_CTL_DEL = 2; + private static final int EPOLL_CTL_MOD = 3; // Miscellaneous constants - static final int SIZE_EPOLLEVENT = sizeofEPollEvent(); - static final int EVENT_OFFSET = 0; - static final int DATA_OFFSET = offsetofData(); - static final int FD_OFFSET = DATA_OFFSET; - static final int NUM_EPOLLEVENTS = Math.min(IOUtil.fdLimit(), 8192); + private static final int SIZE_EPOLLEVENT = sizeofEPollEvent(); + private static final int EVENT_OFFSET = 0; + private static final int DATA_OFFSET = offsetofData(); + private static final int FD_OFFSET = DATA_OFFSET; + private static final int OPEN_MAX = IOUtil.fdLimit(); + private static final int NUM_EPOLLEVENTS = Math.min(OPEN_MAX, 8192); - // Base address of the native pollArray + // Special value to indicate that an update should be ignored + private static final byte KILLED = (byte)-1; + + // Initial size of arrays for fd registration changes + private static final int INITIAL_PENDING_UPDATE_SIZE = 64; + + // maximum size of updatesLow + private static final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + + + // The fd of the epoll driver + private final int epfd; + + // The epoll_event array for results from epoll_wait + private final AllocatedNativeObject pollArray; + + // Base address of the epoll_event array private final long pollArrayAddress; - // Set of "idle" channels - private final HashSet idleSet; + // The fd of the interrupt line going out + private int outgoingInterruptFD; - EPollArrayWrapper() { + // The fd of the interrupt line coming in + private int incomingInterruptFD; + + // The index of the interrupt FD + private int interruptedIndex; + + // Number of updated pollfd entries + int updated; + + // object to synchronize fd registration changes + private final Object updateLock = new Object(); + + // number of file descriptors with registration changes pending + private int updateCount; + + // file descriptors with registration changes pending + private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE]; + + // events for file descriptors with registration changes pending, indexed + // by file descriptor and stored as bytes for efficiency reasons. For + // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at + // least) then the update is stored in a map. + private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE]; + private Map eventsHigh; + + // Used by release and updateRegistrations to track whether a file + // descriptor is registered with epoll. + private final BitSet registered = new BitSet(); + + + EPollArrayWrapper() throws IOException { // creates the epoll file descriptor epfd = epollCreate(); @@ -91,50 +132,11 @@ class EPollArrayWrapper { pollArray = new AllocatedNativeObject(allocationSize, true); pollArrayAddress = pollArray.address(); - for (int i=0; i(); + // eventHigh needed when using file descriptors > 64k + if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE) + eventsHigh = new HashMap<>(); } - // Used to update file description registrations - private static class Updator { - SelChImpl channel; - int opcode; - int events; - Updator(SelChImpl channel, int opcode, int events) { - this.channel = channel; - this.opcode = opcode; - this.events = events; - } - Updator(SelChImpl channel, int opcode) { - this(channel, opcode, 0); - } - } - - private LinkedList updateList = new LinkedList(); - - // The epoll_event array for results from epoll_wait - private AllocatedNativeObject pollArray; - - // The fd of the epoll driver - final int epfd; - - // The fd of the interrupt line going out - int outgoingInterruptFD; - - // The fd of the interrupt line coming in - int incomingInterruptFD; - - // The index of the interrupt FD - int interruptedIndex; - - // Number of updated pollfd entries - int updated; - void initInterrupt(int fd0, int fd1) { outgoingInterruptFD = fd1; incomingInterruptFD = fd0; @@ -146,11 +148,6 @@ class EPollArrayWrapper { pollArray.putInt(offset, event); } - void putData(int i, long value) { - int offset = SIZE_EPOLLEVENT * i + DATA_OFFSET; - pollArray.putLong(offset, value); - } - void putDescriptor(int i, int fd) { int offset = SIZE_EPOLLEVENT * i + FD_OFFSET; pollArray.putInt(offset, fd); @@ -167,51 +164,83 @@ class EPollArrayWrapper { } /** - * Update the events for a given channel. + * Sets the pending update events for the given file descriptor. This + * method has no effect if the update events is already set to KILLED, + * unless {@code force} is {@code true}. */ - void setInterest(SelChImpl channel, int mask) { - synchronized (updateList) { - // if the previous pending operation is to add this file descriptor - // to epoll then update its event set - if (updateList.size() > 0) { - Updator last = updateList.getLast(); - if (last.channel == channel && last.opcode == EPOLL_CTL_ADD) { - last.events = mask; - return; - } + private void setUpdateEvents(int fd, byte events, boolean force) { + if (fd < MAX_UPDATE_ARRAY_SIZE) { + if ((eventsLow[fd] != KILLED) || force) { + eventsLow[fd] = events; + } + } else { + Integer key = Integer.valueOf(fd); + if ((eventsHigh.get(key) != KILLED) || force) { + eventsHigh.put(key, Byte.valueOf(events)); } - - // update existing registration - updateList.add(new Updator(channel, EPOLL_CTL_MOD, mask)); } } /** - * Add a channel's file descriptor to epoll + * Returns the pending update events for the given file descriptor. */ - void add(SelChImpl channel) { - synchronized (updateList) { - updateList.add(new Updator(channel, EPOLL_CTL_ADD)); + private byte getUpdateEvents(int fd) { + if (fd < MAX_UPDATE_ARRAY_SIZE) { + return eventsLow[fd]; + } else { + Byte result = eventsHigh.get(Integer.valueOf(fd)); + // result should never be null + return result.byteValue(); } } /** - * Remove a channel's file descriptor from epoll + * Update the events for a given file descriptor */ - void release(SelChImpl channel) { - synchronized (updateList) { - // flush any pending updates - for (Iterator it = updateList.iterator(); it.hasNext();) { - if (it.next().channel == channel) { - it.remove(); - } + void setInterest(int fd, int mask) { + synchronized (updateLock) { + // record the file descriptor and events + int oldCapacity = updateDescriptors.length; + if (updateCount == oldCapacity) { + int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE; + int[] newDescriptors = new int[newCapacity]; + System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity); + updateDescriptors = newDescriptors; } + updateDescriptors[updateCount++] = fd; - // remove from the idle set (if present) - idleSet.remove(channel); + // events are stored as bytes for efficiency reasons + byte b = (byte)mask; + assert (b == mask) && (b != KILLED); + setUpdateEvents(fd, b, false); + } + } - // remove from epoll (if registered) - epollCtl(epfd, EPOLL_CTL_DEL, channel.getFDVal(), 0); + /** + * Add a file descriptor + */ + void add(int fd) { + // force the initial update events to 0 as it may be KILLED by a + // previous registration. + synchronized (updateLock) { + assert !registered.get(fd); + setUpdateEvents(fd, (byte)0, true); + } + } + + /** + * Remove a file descriptor + */ + void remove(int fd) { + synchronized (updateLock) { + // kill pending and future update for this file descriptor + setUpdateEvents(fd, KILLED, false); + + // remove from epoll + if (registered.get(fd)) { + epollCtl(epfd, EPOLL_CTL_DEL, fd, 0); + registered.clear(fd); + } } } @@ -239,36 +268,38 @@ class EPollArrayWrapper { /** * Update the pending registrations. */ - void updateRegistrations() { - synchronized (updateList) { - Updator u = null; - while ((u = updateList.poll()) != null) { - SelChImpl ch = u.channel; - if (!ch.isOpen()) - continue; + private void updateRegistrations() { + synchronized (updateLock) { + int j = 0; + while (j < updateCount) { + int fd = updateDescriptors[j]; + short events = getUpdateEvents(fd); + boolean isRegistered = registered.get(fd); + int opcode = 0; - // if the events are 0 then file descriptor is put into "idle - // set" to prevent it being polled - if (u.events == 0) { - boolean added = idleSet.add(u.channel); - // if added to idle set then remove from epoll if registered - if (added && (u.opcode == EPOLL_CTL_MOD)) - epollCtl(epfd, EPOLL_CTL_DEL, ch.getFDVal(), 0); - } else { - // events are specified. If file descriptor was in idle set - // it must be re-registered (by converting opcode to ADD) - boolean idle = false; - if (!idleSet.isEmpty()) - idle = idleSet.remove(u.channel); - int opcode = (idle) ? EPOLL_CTL_ADD : u.opcode; - epollCtl(epfd, opcode, ch.getFDVal(), u.events); + if (events != KILLED) { + if (isRegistered) { + opcode = (events != 0) ? EPOLL_CTL_MOD : EPOLL_CTL_DEL; + } else { + opcode = (events != 0) ? EPOLL_CTL_ADD : 0; + } + if (opcode != 0) { + epollCtl(epfd, opcode, fd, events); + if (opcode == EPOLL_CTL_ADD) { + registered.set(fd); + } else if (opcode == EPOLL_CTL_DEL) { + registered.clear(fd); + } + } } + j++; } + updateCount = 0; } } // interrupt support - boolean interrupted = false; + private boolean interrupted = false; public void interrupt() { interrupt(outgoingInterruptFD); diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java index 5fa2b324fc5..c8bdab4c7be 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java @@ -53,26 +53,24 @@ class EPollSelectorImpl private volatile boolean closed = false; // Lock for interrupt triggering and clearing - private Object interruptLock = new Object(); + private final Object interruptLock = new Object(); private boolean interruptTriggered = false; /** * Package private constructor called by factory method in * the abstract superclass Selector. */ - EPollSelectorImpl(SelectorProvider sp) { + EPollSelectorImpl(SelectorProvider sp) throws IOException { super(sp); long pipeFds = IOUtil.makePipe(false); fd0 = (int) (pipeFds >>> 32); fd1 = (int) pipeFds; pollWrapper = new EPollArrayWrapper(); pollWrapper.initInterrupt(fd0, fd1); - fdToKey = new HashMap(); + fdToKey = new HashMap<>(); } - protected int doSelect(long timeout) - throws IOException - { + protected int doSelect(long timeout) throws IOException { if (closed) throw new ClosedSelectorException(); processDeregisterQueue(); @@ -161,8 +159,9 @@ class EPollSelectorImpl if (closed) throw new ClosedSelectorException(); SelChImpl ch = ski.channel; - fdToKey.put(Integer.valueOf(ch.getFDVal()), ski); - pollWrapper.add(ch); + int fd = Integer.valueOf(ch.getFDVal()); + fdToKey.put(fd, ski); + pollWrapper.add(fd); keys.add(ski); } @@ -171,7 +170,7 @@ class EPollSelectorImpl SelChImpl ch = ski.channel; int fd = ch.getFDVal(); fdToKey.remove(Integer.valueOf(fd)); - pollWrapper.release(ch); + pollWrapper.remove(fd); ski.setIndex(-1); keys.remove(ski); selectedKeys.remove(ski); @@ -181,10 +180,11 @@ class EPollSelectorImpl ((SelChImpl)selch).kill(); } - public void putEventOps(SelectionKeyImpl sk, int ops) { + public void putEventOps(SelectionKeyImpl ski, int ops) { if (closed) throw new ClosedSelectorException(); - pollWrapper.setInterest(sk.channel, ops); + SelChImpl ch = ski.channel; + pollWrapper.setInterest(ch.getFDVal(), ops); } public Selector wakeup() { @@ -200,5 +200,4 @@ class EPollSelectorImpl static { Util.load(); } - } From 709f67b8f99e877482f7956962d53d89e62ab702 Mon Sep 17 00:00:00 2001 From: Jim Gish Date: Wed, 13 Mar 2013 11:24:48 -0400 Subject: [PATCH 008/137] 8002070: Remove the stack search for a resource bundle for Logger to use The fragile, vulnerable, stack crawling has been eliminated from findResourceBundle(String) Reviewed-by: mchung, alanb --- .../classes/java/util/logging/Logger.java | 95 ++++++------------- .../logging/LoggerResourceBundleRace.java | 9 +- 2 files changed, 34 insertions(+), 70 deletions(-) diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java index 4e52c235c0c..8968aed335d 100644 --- a/jdk/src/share/classes/java/util/logging/Logger.java +++ b/jdk/src/share/classes/java/util/logging/Logger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,10 +26,13 @@ package java.util.logging; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.security.*; import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Supplier; /** @@ -104,7 +107,7 @@ import java.util.function.Supplier; * unnecessary message construction. For example, if the developer wants to * log system health status for diagnosis, with the String-accepting version, * the code would look like: -
+ 

 
    class DiagnosisMessages {
      static String systemHealthStatus() {
@@ -114,26 +117,20 @@ import java.util.function.Supplier;
    }
    ...
    logger.log(Level.FINER, DiagnosisMessages.systemHealthStatus());
- 
+
* With the above code, the health status is collected unnecessarily even when * the log level FINER is disabled. With the Supplier-accepting version as * below, the status will only be collected when the log level FINER is * enabled. -
+ 

 
    logger.log(Level.FINER, DiagnosisMessages::systemHealthStatus);
- 
+
*

* When mapping ResourceBundle names to ResourceBundles, the Logger * will first try to use the Thread's ContextClassLoader. If that - * is null it will try the SystemClassLoader instead. As a temporary - * transition feature in the initial implementation, if the Logger is - * unable to locate a ResourceBundle from the ContextClassLoader or - * SystemClassLoader the Logger will also search up the class stack - * and use successive calling ClassLoaders to try to locate a ResourceBundle. - * (This call stack search is to allow containers to transition to - * using ContextClassLoaders and is likely to be removed in future - * versions.) + * is null it will try the + * {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader} instead. *

* Formatting (including localization) is the responsibility of * the output Handler, which will typically call a Formatter. @@ -1541,12 +1538,16 @@ public class Logger { return useParentHandlers; } - // Private utility method to map a resource bundle name to an - // actual resource bundle, using a simple one-entry cache. - // Returns null for a null name. - // May also return null if we can't find the resource bundle and - // there is no suitable previous cached value. - + /** + * Private utility method to map a resource bundle name to an + * actual resource bundle, using a simple one-entry cache. + * Returns null for a null name. + * May also return null if we can't find the resource bundle and + * there is no suitable previous cached value. + * + * @param name the ResourceBundle to locate + * @return ResourceBundle specified by name or null if not found + */ private synchronized ResourceBundle findResourceBundle(String name) { // Return a null bundle for a null name. if (name == null) { @@ -1556,13 +1557,13 @@ public class Logger { Locale currentLocale = Locale.getDefault(); // Normally we should hit on our simple one entry cache. - if (catalog != null && currentLocale == catalogLocale - && name == catalogName) { + if (catalog != null && currentLocale.equals(catalogLocale) + && name.equals(catalogName)) { return catalog; } - // Use the thread's context ClassLoader. If there isn't one, - // use the SystemClassloader. + // Use the thread's context ClassLoader. If there isn't one, use the + // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}. ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) { cl = ClassLoader.getSystemClassLoader(); @@ -1573,45 +1574,8 @@ public class Logger { catalogLocale = currentLocale; return catalog; } catch (MissingResourceException ex) { - // Woops. We can't find the ResourceBundle in the default - // ClassLoader. Drop through. + return null; } - - - // Fall back to searching up the call stack and trying each - // calling ClassLoader. - for (int ix = 0; ; ix++) { - Class clz = sun.reflect.Reflection.getCallerClass(ix); - if (clz == null) { - break; - } - ClassLoader cl2 = clz.getClassLoader(); - if (cl2 == null) { - cl2 = ClassLoader.getSystemClassLoader(); - } - if (cl == cl2) { - // We've already checked this classloader. - continue; - } - cl = cl2; - try { - catalog = ResourceBundle.getBundle(name, currentLocale, cl); - catalogName = name; - catalogLocale = currentLocale; - return catalog; - } catch (MissingResourceException ex) { - // Ok, this one didn't work either. - // Drop through, and try the next one. - } - } - - if (name.equals(catalogName)) { - // Return the previous cached value for that name. - // This may be null. - return catalog; - } - // Sorry, we're out of luck. - return null; } // Private utility method to initialize our one entry @@ -1638,8 +1602,7 @@ public class Logger { resourceBundleName + " != " + name); } - ResourceBundle rb = findResourceBundle(name); - if (rb == null) { + if (findResourceBundle(name) == null) { // We've failed to find an expected ResourceBundle. throw new MissingResourceException("Can't find " + name + " bundle", name, ""); } diff --git a/jdk/test/java/util/logging/LoggerResourceBundleRace.java b/jdk/test/java/util/logging/LoggerResourceBundleRace.java index aabbc140f85..f9acc874162 100644 --- a/jdk/test/java/util/logging/LoggerResourceBundleRace.java +++ b/jdk/test/java/util/logging/LoggerResourceBundleRace.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 @@ -23,13 +23,14 @@ /* * @test - * @bug 7045594 + * @bug 7045594 8002070 * @summary ResourceBundle setting race in Logger.getLogger(name, rbName) * @author Daniel D. Daugherty * @build RacingThreadsTest LoggerResourceBundleRace - * @run main LoggerResourceBundleRace + * @run main/othervm LoggerResourceBundleRace + * + * (In samevm mode, the bundle classes don't end up in the classpath.) */ - import java.util.ListResourceBundle; import java.util.MissingResourceException; import java.util.concurrent.atomic.AtomicInteger; From f3e45cd062eaa8e742ad9b8cf8c941013685dead Mon Sep 17 00:00:00 2001 From: Dan Xu Date: Wed, 13 Mar 2013 14:50:40 -0700 Subject: [PATCH 009/137] 8001334: Remove use of JVM_* functions from java.io code Replace JVM_* functions with direct system calls in java io area Reviewed-by: alanb, uta, martin --- jdk/make/java/nio/Makefile | 6 +- jdk/makefiles/CompileNativeLibraries.gmk | 4 +- .../share/native/java/io/ObjectOutputStream.c | 10 +- jdk/src/share/native/java/io/io_util.c | 23 +--- jdk/src/share/native/java/io/io_util.h | 4 +- jdk/src/solaris/native/common/jdk_util_md.h | 24 +++- .../native/java/io/FileDescriptor_md.c | 9 +- .../native/java/io/UnixFileSystem_md.c | 27 ++-- jdk/src/solaris/native/java/io/io_util_md.c | 122 +++++++++++++++++- jdk/src/solaris/native/java/io/io_util_md.h | 50 +++++-- jdk/src/windows/native/common/jdk_util_md.h | 7 +- jdk/src/windows/native/java/io/io_util_md.c | 75 ++++++++--- jdk/src/windows/native/java/io/io_util_md.h | 31 +++-- 13 files changed, 290 insertions(+), 102 deletions(-) diff --git a/jdk/make/java/nio/Makefile b/jdk/make/java/nio/Makefile index 9eebd5cc4ea..c20bec9ec36 100644 --- a/jdk/make/java/nio/Makefile +++ b/jdk/make/java/nio/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 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 @@ -384,9 +384,7 @@ OTHER_INCLUDES += \ ifeq ($(PLATFORM),windows) OTHER_LDLIBS += $(JVMLIB) ws2_32.lib \ -libpath:$(LIBDIR) java.lib \ - $(OBJDIR)/../../../../sun/java.net/net/$(OBJDIRNAME)/net.lib \ - $(OBJDIR)/../../../java.lang/java/$(OBJDIRNAME)/io_util.obj \ - $(OBJDIR)/../../../java.lang/java/$(OBJDIRNAME)/FileDescriptor_md.obj + $(OBJDIR)/../../../../sun/java.net/net/$(OBJDIRNAME)/net.lib endif ifeq ($(PLATFORM), linux) OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread $(LIBDL) diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 01dbc2ba417..c6c50c61e78 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.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 @@ -1957,8 +1957,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBNIO,\ -lsendfile -ljava -lnet -lc,\ LDFLAGS_SUFFIX_windows:=jvm.lib ws2_32.lib $(WIN_JAVA_LIB) \ $(JDK_OUTPUTDIR)/objs/libnet/net.lib \ - $(JDK_OUTPUTDIR)/objs/libjava/io_util.obj \ - $(JDK_OUTPUTDIR)/objs/libjava/FileDescriptor_md.obj \ advapi32.lib,\ LDFLAGS_SUFFIX_macosx:=-ljava -lnet -pthread -framework CoreFoundation,\ LDFLAGS_SUFFIX:=,\ diff --git a/jdk/src/share/native/java/io/ObjectOutputStream.c b/jdk/src/share/native/java/io/ObjectOutputStream.c index 2bbb222048f..5db2c627780 100644 --- a/jdk/src/share/native/java/io/ObjectOutputStream.c +++ b/jdk/src/share/native/java/io/ObjectOutputStream.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2000, 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 @@ -23,10 +23,8 @@ * questions. */ -#include "jni.h" -#include "jvm.h" #include "jni_util.h" -#include "jlong.h" +#include "jdk_util.h" #include "java_lang_Float.h" #include "java_lang_Double.h" @@ -88,7 +86,7 @@ Java_java_io_ObjectOutputStream_floatsToBytes(JNIEnv *env, srcend = srcpos + nfloats; for ( ; srcpos < srcend; srcpos++) { fval = (float) floats[srcpos]; - if (JVM_IsNaN(fval)) { /* collapse NaNs */ + if (ISNANF(fval)) { /* collapse NaNs */ ival = 0x7fc00000; } else { u.f = fval; @@ -160,7 +158,7 @@ Java_java_io_ObjectOutputStream_doublesToBytes(JNIEnv *env, srcend = srcpos + ndoubles; for ( ; srcpos < srcend; srcpos++) { dval = doubles[srcpos]; - if (JVM_IsNaN((double) dval)) { /* collapse NaNs */ + if (ISNAND((double) dval)) { /* collapse NaNs */ lval = jint_to_jlong(0x7ff80000); lval = jlong_shl(lval, 32); } else { diff --git a/jdk/src/share/native/java/io/io_util.c b/jdk/src/share/native/java/io/io_util.c index 8777ff0f899..9a9ca7d292d 100644 --- a/jdk/src/share/native/java/io/io_util.c +++ b/jdk/src/share/native/java/io/io_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -47,10 +47,8 @@ readSingle(JNIEnv *env, jobject this, jfieldID fid) { nread = IO_Read(fd, &ret, 1); if (nread == 0) { /* EOF */ return -1; - } else if (nread == JVM_IO_ERR) { /* error */ + } else if (nread == -1) { /* error */ JNU_ThrowIOExceptionWithLastError(env, "Read error"); - } else if (nread == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL); } return ret & 0xFF; } @@ -111,10 +109,8 @@ readBytes(JNIEnv *env, jobject this, jbyteArray bytes, nread = IO_Read(fd, buf, len); if (nread > 0) { (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf); - } else if (nread == JVM_IO_ERR) { + } else if (nread == -1) { JNU_ThrowIOExceptionWithLastError(env, "Read error"); - } else if (nread == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL); } else { /* EOF */ nread = -1; } @@ -141,10 +137,8 @@ writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) } else { n = IO_Write(fd, &c, 1); } - if (n == JVM_IO_ERR) { + if (n == -1) { JNU_ThrowIOExceptionWithLastError(env, "Write error"); - } else if (n == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL); } } @@ -194,12 +188,9 @@ writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, } else { n = IO_Write(fd, buf+off, len); } - if (n == JVM_IO_ERR) { + if (n == -1) { JNU_ThrowIOExceptionWithLastError(env, "Write error"); break; - } else if (n == JVM_IO_INTR) { - JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL); - break; } off += n; len -= n; @@ -214,11 +205,11 @@ void throwFileNotFoundException(JNIEnv *env, jstring path) { char buf[256]; - jint n; + size_t n; jobject x; jstring why = NULL; - n = JVM_GetLastErrorString(buf, sizeof(buf)); + n = getLastErrorString(buf, sizeof(buf)); if (n > 0) { why = JNU_NewStringPlatform(env, buf); } diff --git a/jdk/src/share/native/java/io/io_util.h b/jdk/src/share/native/java/io/io_util.h index d1804e1d386..6f058ccc4b5 100644 --- a/jdk/src/share/native/java/io/io_util.h +++ b/jdk/src/share/native/java/io/io_util.h @@ -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 @@ -54,7 +54,7 @@ void writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len, jboolean append, jfieldID fid); void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); void throwFileNotFoundException(JNIEnv *env, jstring path); - +size_t getLastErrorString(char *buf, size_t len); /* * Macros for managing platform strings. The typical usage pattern is: diff --git a/jdk/src/solaris/native/common/jdk_util_md.h b/jdk/src/solaris/native/common/jdk_util_md.h index b2472b3db7e..d9fd2a2557f 100644 --- a/jdk/src/solaris/native/common/jdk_util_md.h +++ b/jdk/src/solaris/native/common/jdk_util_md.h @@ -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,4 +23,24 @@ * questions. */ -// Currently, there are no unix specific functions defined. +#ifndef JDK_UTIL_MD_H +#define JDK_UTIL_MD_H + +// checking for nanness +#ifdef __solaris__ +#include +#define ISNANF(f) isnanf(f) +#define ISNAND(d) isnand(d) +#elif defined(MACOSX) +#include +#define ISNANF(f) isnan(f) +#define ISNAND(d) isnan(d) +#elif defined(__linux__) || defined(_ALLBSD_SOURCE) +#include +#define ISNANF(f) isnanf(f) +#define ISNAND(d) isnan(d) +#else +#error "missing platform-specific definition here" +#endif + +#endif /* JDK_UTIL_MD_H */ diff --git a/jdk/src/solaris/native/java/io/FileDescriptor_md.c b/jdk/src/solaris/native/java/io/FileDescriptor_md.c index c279ca9838c..7147a14c544 100644 --- a/jdk/src/solaris/native/java/io/FileDescriptor_md.c +++ b/jdk/src/solaris/native/java/io/FileDescriptor_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 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 @@ -23,9 +23,8 @@ * questions. */ -#include "jni.h" -#include "jni_util.h" #include "jvm.h" +#include "io_util_md.h" #include "java_io_FileDescriptor.h" @@ -51,8 +50,8 @@ Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) { JNIEXPORT void JNICALL Java_java_io_FileDescriptor_sync(JNIEnv *env, jobject this) { - int fd = (*env)->GetIntField(env, this, IO_fd_fdID); - if (JVM_Sync(fd) == -1) { + FD fd = THIS_FD(this); + if (IO_Sync(fd) == -1) { JNU_ThrowByName(env, "java/io/SyncFailedException", "sync failed"); } } diff --git a/jdk/src/solaris/native/java/io/UnixFileSystem_md.c b/jdk/src/solaris/native/java/io/UnixFileSystem_md.c index 954e212cb56..5f95cd998c8 100644 --- a/jdk/src/solaris/native/java/io/UnixFileSystem_md.c +++ b/jdk/src/solaris/native/java/io/UnixFileSystem_md.c @@ -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 @@ -77,7 +77,7 @@ Java_java_io_UnixFileSystem_canonicalize0(JNIEnv *env, jobject this, WITH_PLATFORM_STRING(env, pathname, path) { char canonicalPath[JVM_MAXPATHLEN]; - if (canonicalize(JVM_NativePath((char *)path), + if (canonicalize((char *)path, canonicalPath, JVM_MAXPATHLEN) < 0) { JNU_ThrowIOExceptionWithLastError(env, "Bad pathname"); } else { @@ -241,19 +241,18 @@ Java_java_io_UnixFileSystem_createFileExclusively(JNIEnv *env, jclass cls, jboolean rv = JNI_FALSE; WITH_PLATFORM_STRING(env, pathname, path) { - int fd; - if (!strcmp (path, "/")) { - fd = JVM_EEXIST; /* The root directory always exists */ - } else { - fd = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666); - } - if (fd < 0) { - if (fd != JVM_EEXIST) { - JNU_ThrowIOExceptionWithLastError(env, path); + FD fd; + /* The root directory always exists */ + if (strcmp (path, "/")) { + fd = handleOpen(path, O_RDWR | O_CREAT | O_EXCL, 0666); + if (fd < 0) { + if (errno != EEXIST) + JNU_ThrowIOExceptionWithLastError(env, path); + } else { + if (close(fd) == -1) + JNU_ThrowIOExceptionWithLastError(env, path); + rv = JNI_TRUE; } - } else { - JVM_Close(fd); - rv = JNI_TRUE; } } END_PLATFORM_STRING(env, path); return rv; diff --git a/jdk/src/solaris/native/java/io/io_util_md.c b/jdk/src/solaris/native/java/io/io_util_md.c index 61ceda9e1e6..a1acbe5d409 100644 --- a/jdk/src/solaris/native/java/io/io_util_md.c +++ b/jdk/src/solaris/native/java/io/io_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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,6 +29,15 @@ #include "io_util.h" #include "io_util_md.h" #include +#include + +#ifdef __solaris__ +#include +#endif + +#if defined(__linux__) || defined(_ALLBSD_SOURCE) +#include +#endif #ifdef MACOSX @@ -62,6 +71,28 @@ jstring newStringPlatform(JNIEnv *env, const char* str) } #endif +FD +handleOpen(const char *path, int oflag, int mode) { + FD fd; + RESTARTABLE(open64(path, oflag, mode), fd); + if (fd != -1) { + struct stat64 buf64; + int result; + RESTARTABLE(fstat64(fd, &buf64), result); + if (result != -1) { + if (S_ISDIR(buf64.st_mode)) { + close(fd); + errno = EISDIR; + fd = -1; + } + } else { + close(fd); + fd = -1; + } + } + return fd; +} + void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { @@ -74,8 +105,8 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) while ((p > ps) && (*p == '/')) *p-- = '\0'; #endif - fd = JVM_Open(ps, flags, 0666); - if (fd >= 0) { + fd = handleOpen(ps, flags, 0666); + if (fd != -1) { SET_FD(this, fd, fid); } else { throwFileNotFoundException(env, path); @@ -83,7 +114,6 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) } END_PLATFORM_STRING(env, ps); } - void fileClose(JNIEnv *env, jobject this, jfieldID fid) { @@ -114,7 +144,89 @@ fileClose(JNIEnv *env, jobject this, jfieldID fid) dup2(devnull, fd); close(devnull); } - } else if (JVM_Close(fd) == -1) { + } else if (close(fd) == -1) { JNU_ThrowIOExceptionWithLastError(env, "close failed"); } } + +ssize_t +handleRead(FD fd, void *buf, jint len) +{ + ssize_t result; + RESTARTABLE(read(fd, buf, len), result); + return result; +} + +ssize_t +handleWrite(FD fd, const void *buf, jint len) +{ + ssize_t result; + RESTARTABLE(write(fd, buf, len), result); + return result; +} + +jint +handleAvailable(FD fd, jlong *pbytes) +{ + int mode; + struct stat64 buf64; + jlong size = -1, current = -1; + + int result; + RESTARTABLE(fstat64(fd, &buf64), result); + if (result != -1) { + mode = buf64.st_mode; + if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { + int n; + int result; + RESTARTABLE(ioctl(fd, FIONREAD, &n), result); + if (result >= 0) { + *pbytes = n; + return 1; + } + } else if (S_ISREG(mode)) { + size = buf64.st_size; + } + } + + if ((current = lseek64(fd, 0, SEEK_CUR)) == -1) { + return 0; + } + + if (size < current) { + if ((size = lseek64(fd, 0, SEEK_END)) == -1) + return 0; + else if (lseek64(fd, current, SEEK_SET) == -1) + return 0; + } + + if (size >= current) { + *pbytes = size - current; + return 1; + } else { + return 0; + } +} + +jint +handleSetLength(FD fd, jlong length) +{ + int result; + RESTARTABLE(ftruncate64(fd, length), result); + return result; +} + +size_t +getLastErrorString(char *buf, size_t len) +{ + if (errno == 0 || len < 1) return 0; + + const char *err = strerror(errno); + size_t n = strlen(err); + if (n >= len) + n = len - 1; + + strncpy(buf, err, n); + buf[n] = '\0'; + return n; +} diff --git a/jdk/src/solaris/native/java/io/io_util_md.h b/jdk/src/solaris/native/java/io/io_util_md.h index fe1b7e1ad56..b7b2573a02e 100644 --- a/jdk/src/solaris/native/java/io/io_util_md.h +++ b/jdk/src/solaris/native/java/io/io_util_md.h @@ -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 @@ -23,7 +23,6 @@ * questions. */ -#include "jni.h" #include "jni_util.h" /* @@ -31,6 +30,18 @@ */ #define FD jint +/* + * Prototypes for functions in io_util_md.c called from io_util.c, + * FileDescriptor.c, FileInputStream.c, FileOutputStream.c, + * UnixFileSystem_md.c + */ +ssize_t handleWrite(FD fd, const void *buf, jint len); +ssize_t handleRead(FD fd, void *buf, jint len); +jint handleAvailable(FD fd, jlong *pbytes); +jint handleSetLength(FD fd, jlong length); + +FD handleOpen(const char *path, int oflag, int mode); + /* * Macros to set/get fd from the java.io.FileDescriptor. These * macros rely on having an appropriately defined 'this' object @@ -53,21 +64,40 @@ #define THIS_FD(obj) (*env)->GetIntField(env, obj, IO_fd_fdID) /* - * Route the routines through VM + * Route the routines */ -#define IO_Append JVM_Write -#define IO_Write JVM_Write -#define IO_Sync JVM_Sync -#define IO_Read JVM_Read -#define IO_Lseek JVM_Lseek -#define IO_Available JVM_Available -#define IO_SetLength JVM_SetLength +#define IO_Sync fsync +#define IO_Read handleRead +#define IO_Write handleWrite +#define IO_Append handleWrite +#define IO_Available handleAvailable +#define IO_SetLength handleSetLength + +#ifdef _ALLBSD_SOURCE +#define open64 open +#define fstat64 fstat +#define stat64 stat +#define lseek64 lseek +#define ftruncate64 ftruncate +#define IO_Lseek lseek +#else +#define IO_Lseek lseek64 +#endif /* * On Solaris, the handle field is unused */ #define SET_HANDLE(fd) return (jlong)-1 +/* + * Retry the operation if it is interrupted + */ +#define RESTARTABLE(_cmd, _result) do { \ + do { \ + _result = _cmd; \ + } while((_result == -1) && (errno == EINTR)); \ +} while(0) + /* * IO helper function(s) */ diff --git a/jdk/src/windows/native/common/jdk_util_md.h b/jdk/src/windows/native/common/jdk_util_md.h index 67c45a286cd..7611c550ff6 100644 --- a/jdk/src/windows/native/common/jdk_util_md.h +++ b/jdk/src/windows/native/common/jdk_util_md.h @@ -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 @@ -28,6 +28,11 @@ #define JDK_UTIL_MD_H #include "jni.h" +#include + +// checking for nanness +#define ISNANF(f) _isnan(f) +#define ISNAND(d) _isnan(d) #ifdef __cplusplus extern "C" { diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index 2f0e74fc171..3e9aef352f7 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -208,7 +208,7 @@ pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) { return pathbuf; } -jlong +FD winFileHandleOpen(JNIEnv *env, jstring path, int flags) { const DWORD access = @@ -264,7 +264,7 @@ winFileHandleOpen(JNIEnv *env, jstring path, int flags) void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { - jlong h = winFileHandleOpen(env, path, flags); + FD h = winFileHandleOpen(env, path, flags); if (h >= 0) { SET_FD(this, h, fid); } @@ -274,12 +274,12 @@ fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) old C style int fd as is used in HPI layer */ static int -handleNonSeekAvailable(jlong, long *); +handleNonSeekAvailable(FD, long *); static int -handleStdinAvailable(jlong, long *); +handleStdinAvailable(FD, long *); int -handleAvailable(jlong fd, jlong *pbytes) { +handleAvailable(FD fd, jlong *pbytes) { HANDLE h = (HANDLE)fd; DWORD type = 0; @@ -317,7 +317,7 @@ handleAvailable(jlong fd, jlong *pbytes) { } static int -handleNonSeekAvailable(jlong fd, long *pbytes) { +handleNonSeekAvailable(FD fd, long *pbytes) { /* This is used for available on non-seekable devices * (like both named and anonymous pipes, such as pipes * connected to an exec'd process). @@ -346,7 +346,7 @@ handleNonSeekAvailable(jlong fd, long *pbytes) { } static int -handleStdinAvailable(jlong fd, long *pbytes) { +handleStdinAvailable(FD fd, long *pbytes) { HANDLE han; DWORD numEventsRead = 0; /* Number of events read from buffer */ DWORD numEvents = 0; /* Number of events in buffer */ @@ -412,8 +412,8 @@ handleStdinAvailable(jlong fd, long *pbytes) { * denied". */ -JNIEXPORT int -handleSync(jlong fd) { +int +handleSync(FD fd) { /* * From the documentation: * @@ -443,7 +443,7 @@ handleSync(jlong fd) { int -handleSetLength(jlong fd, jlong length) { +handleSetLength(FD fd, jlong length) { HANDLE h = (HANDLE)fd; long high = (long)(length >> 32); DWORD ret; @@ -459,7 +459,7 @@ handleSetLength(jlong fd, jlong length) { JNIEXPORT jint -handleRead(jlong fd, void *buf, jint len) +handleRead(FD fd, void *buf, jint len) { DWORD read = 0; BOOL result = 0; @@ -482,7 +482,7 @@ handleRead(jlong fd, void *buf, jint len) return (jint)read; } -static jint writeInternal(jlong fd, const void *buf, jint len, jboolean append) +static jint writeInternal(FD fd, const void *buf, jint len, jboolean append) { BOOL result = 0; DWORD written = 0; @@ -510,13 +510,11 @@ static jint writeInternal(jlong fd, const void *buf, jint len, jboolean append) return (jint)written; } -JNIEXPORT -jint handleWrite(jlong fd, const void *buf, jint len) { +jint handleWrite(FD fd, const void *buf, jint len) { return writeInternal(fd, buf, len, JNI_FALSE); } -JNIEXPORT -jint handleAppend(jlong fd, const void *buf, jint len) { +jint handleAppend(FD fd, const void *buf, jint len) { return writeInternal(fd, buf, len, JNI_TRUE); } @@ -545,7 +543,7 @@ handleClose(JNIEnv *env, jobject this, jfieldID fid) } jlong -handleLseek(jlong fd, jlong offset, jint whence) +handleLseek(FD fd, jlong offset, jint whence) { LARGE_INTEGER pos, distance; DWORD lowPos = 0; @@ -569,3 +567,44 @@ handleLseek(jlong fd, jlong offset, jint whence) } return long_to_jlong(pos.QuadPart); } + +size_t +getLastErrorString(char *buf, size_t len) +{ + DWORD errval; + if (len > 0) { + if ((errval = GetLastError()) != 0) { + // DOS error + size_t n = (size_t)FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errval, + 0, + buf, + (DWORD)len, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (buf[n - 1] == '\n') n--; + if (buf[n - 1] == '\r') n--; + if (buf[n - 1] == '.') n--; + buf[n] = '\0'; + } + return n; + } + + if (errno != 0) { + // C runtime error that has no corresponding DOS error code + const char *err = strerror(errno); + size_t n = strlen(err); + if (n >= len) + n = len - 1; + + strncpy(buf, err, n); + buf[n] = '\0'; + return n; + } + } + + return 0; +} diff --git a/jdk/src/windows/native/java/io/io_util_md.h b/jdk/src/windows/native/java/io/io_util_md.h index 34036d47262..cf925078e94 100644 --- a/jdk/src/windows/native/java/io/io_util_md.h +++ b/jdk/src/windows/native/java/io/io_util_md.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -27,7 +27,12 @@ #include "jni_util.h" /* - * Prototypes for functions in io_util_md.c called from io_util, + * Macros to use the right data type for file descriptors + */ +#define FD jlong + +/* + * Prototypes for functions in io_util_md.c called from io_util.c, * FileDescriptor.c, FileInputStream.c, FileOutputStream.c */ WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE); @@ -35,26 +40,20 @@ WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id); WCHAR* getPrefixed(const WCHAR* path, int pathlen); WCHAR* currentDir(int di); int currentDirLength(const WCHAR* path, int pathlen); -void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); -int handleAvailable(jlong fd, jlong *pbytes); -JNIEXPORT int handleSync(jlong fd); -int handleSetLength(jlong fd, jlong length); -JNIEXPORT jint handleRead(jlong fd, void *buf, jint len); -JNIEXPORT jint handleWrite(jlong fd, const void *buf, jint len); -JNIEXPORT jint handleAppend(jlong fd, const void *buf, jint len); +int handleAvailable(FD fd, jlong *pbytes); +int handleSync(FD fd); +int handleSetLength(FD fd, jlong length); +JNIEXPORT jint handleRead(FD fd, void *buf, jint len); +jint handleWrite(FD fd, const void *buf, jint len); +jint handleAppend(FD fd, const void *buf, jint len); jint handleClose(JNIEnv *env, jobject this, jfieldID fid); -jlong handleLseek(jlong fd, jlong offset, jint whence); +jlong handleLseek(FD fd, jlong offset, jint whence); /* * Returns an opaque handle to file named by "path". If an error occurs, * returns -1 and an exception is pending. */ -jlong winFileHandleOpen(JNIEnv *env, jstring path, int flags); - -/* - * Macros to use the right data type for file descriptors - */ -#define FD jlong +FD winFileHandleOpen(JNIEnv *env, jstring path, int flags); /* * Macros to set/get fd from the java.io.FileDescriptor. From bafe2383ad0b91e80165e9925495110c0ee7d961 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Thu, 14 Mar 2013 00:21:34 +0000 Subject: [PATCH 010/137] 8009650: HttpClient available() check throws SocketException when connection has been closed Reviewed-by: chegar, khazra, dsamersoff --- .../classes/sun/net/www/http/HttpClient.java | 67 ++++++++++-------- .../net/www/http/HttpClient/IsAvailable.java | 68 +++++++++++++++++++ 2 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 jdk/test/sun/net/www/http/HttpClient/IsAvailable.java diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java index cfbc9329387..aeb74fa6938 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -121,7 +121,14 @@ public class HttpClient extends NetworkClient { public boolean reuse = false; // Traffic capture tool, if configured. See HttpCapture class for info - private HttpCapture capture = null; + private HttpCapture capture = null; + + private static final PlatformLogger logger = HttpURLConnection.getHttpLogger(); + private static void logFinest(String msg) { + if (logger.isLoggable(PlatformLogger.FINEST)) { + logger.finest(msg); + } + } /** * A NOP method kept for backwards binary compatibility @@ -266,8 +273,11 @@ public class HttpClient extends NetworkClient { if (ret != null && httpuc != null && httpuc.streaming() && httpuc.getRequestMethod() == "POST") { - if (!ret.available()) + if (!ret.available()) { + ret.inCache = false; + ret.closeServer(); ret = null; + } } if (ret != null) { @@ -279,10 +289,7 @@ public class HttpClient extends NetworkClient { ret.inCache = false; if (httpuc != null && ret.needsTunneling()) httpuc.setTunnelState(TUNNELING); - PlatformLogger logger = HttpURLConnection.getHttpLogger(); - if (logger.isLoggable(PlatformLogger.FINEST)) { - logger.finest("KeepAlive stream retrieved from the cache, " + ret); - } + logFinest("KeepAlive stream retrieved from the cache, " + ret); } } else { // We cannot return this connection to the cache as it's @@ -360,30 +367,33 @@ public class HttpClient extends NetworkClient { } } - protected synchronized boolean available() throws IOException { + protected synchronized boolean available() { boolean available = true; - int old = serverSocket.getSoTimeout(); - serverSocket.setSoTimeout(1); - BufferedInputStream tmpbuf = - new BufferedInputStream(serverSocket.getInputStream()); + int old = -1; - PlatformLogger logger = HttpURLConnection.getHttpLogger(); try { - int r = tmpbuf.read(); - if (r == -1) { - if (logger.isLoggable(PlatformLogger.FINEST)) { - logger.finest("HttpClient.available(): " + - "read returned -1: not available"); + try { + old = serverSocket.getSoTimeout(); + serverSocket.setSoTimeout(1); + BufferedInputStream tmpbuf = + new BufferedInputStream(serverSocket.getInputStream()); + int r = tmpbuf.read(); + if (r == -1) { + logFinest("HttpClient.available(): " + + "read returned -1: not available"); + available = false; } - available = false; + } catch (SocketTimeoutException e) { + logFinest("HttpClient.available(): " + + "SocketTimeout: its available"); + } finally { + if (old != -1) + serverSocket.setSoTimeout(old); } - } catch (SocketTimeoutException e) { - if (logger.isLoggable(PlatformLogger.FINEST)) { - logger.finest("HttpClient.available(): " + - "SocketTimeout: its available"); - } - } finally { - serverSocket.setSoTimeout(old); + } catch (IOException e) { + logFinest("HttpClient.available(): " + + "SocketException: not available"); + available = false; } return available; } @@ -865,10 +875,7 @@ public class HttpClient extends NetworkClient { if (isKeepingAlive()) { // Wrap KeepAliveStream if keep alive is enabled. - PlatformLogger logger = HttpURLConnection.getHttpLogger(); - if (logger.isLoggable(PlatformLogger.FINEST)) { - logger.finest("KeepAlive stream used: " + url); - } + logFinest("KeepAlive stream used: " + url); serverInput = new KeepAliveStream(serverInput, pi, cl, this); failedOnce = false; } diff --git a/jdk/test/sun/net/www/http/HttpClient/IsAvailable.java b/jdk/test/sun/net/www/http/HttpClient/IsAvailable.java new file mode 100644 index 00000000000..d6012a40b3b --- /dev/null +++ b/jdk/test/sun/net/www/http/HttpClient/IsAvailable.java @@ -0,0 +1,68 @@ +/* + * 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 8009650 + * @summary HttpClient available() check throws SocketException when connection + * has been closed + */ + +import java.net.URL; +import java.net.ServerSocket; +import sun.net.www.http.HttpClient; +import java.security.*; +import java.lang.reflect.Method; + +public class IsAvailable { + + public static void main(String[] args) throws Exception { + int readTimeout = 20; + ServerSocket ss = new ServerSocket(0); + + URL url1 = new URL("http://localhost:" + ss.getLocalPort()); + HttpClient c1 = HttpClient.New(url1); + + Method available = HttpClient.class. + getDeclaredMethod("available", null); + available.setAccessible(true); + + c1.setReadTimeout(readTimeout); + boolean a = (boolean) available.invoke(c1); + if (!a) { + throw new RuntimeException("connection should be available"); + } + if (c1.getReadTimeout() != readTimeout) { + throw new RuntimeException("read timeout has been altered"); + } + + c1.closeServer(); + + a = (boolean) available.invoke(c1); + if (a) { + throw new RuntimeException("connection shouldn't be available"); + } + + ss.close(); + } +} From d1bf476e1d92f17f2622b2328dcbe2bb570e4246 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 14 Mar 2013 01:41:20 -0400 Subject: [PATCH 011/137] 8009428: Revert changes to $ substitution performed as part of nashorn integration Reviewed-by: alanb, erikj --- common/makefiles/MakeBase.gmk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/makefiles/MakeBase.gmk b/common/makefiles/MakeBase.gmk index 4c1ecc8c8b7..708cbada085 100644 --- a/common/makefiles/MakeBase.gmk +++ b/common/makefiles/MakeBase.gmk @@ -51,9 +51,8 @@ decompress_paths=$(SED) -f $(SRC_ROOT)/common/makefiles/support/ListPathsSafely- -e 's|X98|$(OUTPUT_ROOT)|g' -e 's|X97|$(SRC_ROOT)|g' \ -e 's|X00|X|g' | tr '\n' '$2' -# Subst in an extra $ to prevent it from disappearing. define ListPathsSafely_If - $(if $(word $3,$($1)),$(eval $1_LPS$3:=$(call compress_paths,$(subst $$,$$$$,$(wordlist $3,$4,$($1)))))) + $(if $(word $3,$($1)),$(eval $1_LPS$3:=$(call compress_paths,$(wordlist $3,$4,$($1))))) endef define ListPathsSafely_Printf From 8f4f6fa24a3d01f3af232c16df226f942c32fec7 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 14 Mar 2013 01:47:59 -0400 Subject: [PATCH 012/137] 8009429: Miscellaneous profiles cleanup 8009428: Revert changes to $ substitution performed as part of nashorn integration Reviewed-by: alanb, erikj --- jdk/makefiles/CreateJars.gmk | 47 +- jdk/makefiles/ProfileNames.gmk | 5 +- jdk/makefiles/Profiles.gmk | 42 +- jdk/makefiles/profile-includes.txt | 8 +- jdk/makefiles/profile-rtjar-includes.txt | 799 ++--------------------- 5 files changed, 118 insertions(+), 783 deletions(-) diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 82b85dc97f3..685215ae24b 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -213,28 +213,28 @@ RT_JAR_EXCLUDES += \ org/relaxng/datatype \ sun/awt/HKSCS.class \ sun/awt/motif/X11GB2312.class \ - sun/awt/motif/X11GB2312\$$Decoder.class \ - sun/awt/motif/X11GB2312\$$Encoder.class \ + sun/awt/motif/X11GB2312\$$$$Decoder.class \ + sun/awt/motif/X11GB2312\$$$$Encoder.class \ sun/awt/motif/X11GBK.class \ - sun/awt/motif/X11GBK\$$Encoder.class \ + sun/awt/motif/X11GBK\$$$$Encoder.class \ sun/awt/motif/X11KSC5601.class \ - sun/awt/motif/X11KSC5601\$$Decoder.class \ - sun/awt/motif/X11KSC5601\$$Encoder.class \ + sun/awt/motif/X11KSC5601\$$$$Decoder.class \ + sun/awt/motif/X11KSC5601\$$$$Encoder.class \ sun/jvmstat \ sun/net/spi/nameservice/dns \ sun/nio/cs/ext \ sun/rmi/rmic \ sun/security/ec/ECDHKeyAgreement.class \ sun/security/ec/ECDSASignature.class \ - sun/security/ec/ECDSASignature\$$Raw.class \ - sun/security/ec/ECDSASignature\$$SHA1.class \ - sun/security/ec/ECDSASignature\$$SHA224.class \ - sun/security/ec/ECDSASignature\$$SHA256.class \ - sun/security/ec/ECDSASignature\$$SHA384.class \ - sun/security/ec/ECDSASignature\$$SHA512.class \ + sun/security/ec/ECDSASignature\$$$$Raw.class \ + sun/security/ec/ECDSASignature\$$$$SHA1.class \ + sun/security/ec/ECDSASignature\$$$$SHA224.class \ + sun/security/ec/ECDSASignature\$$$$SHA256.class \ + sun/security/ec/ECDSASignature\$$$$SHA384.class \ + sun/security/ec/ECDSASignature\$$$$SHA512.class \ sun/security/ec/ECKeyFactory.class \ sun/security/ec/ECKeyPairGenerator.class \ - sun/security/ec/SunEC\$$1.class \ + sun/security/ec/SunEC\$$$$1.class \ sun/security/ec/SunEC.class \ sun/security/ec/SunECEntries.class \ sun/security/internal \ @@ -357,23 +357,25 @@ $(PROFILE_VERSION_CLASS_TARGETS) : $(PROFILE_VERSION_JAVA_TARGETS) # Support for removing the addPropertyChangeListener and removePropertyChangeListener -# methods from classes that only go into the profile builds. For now the Pack200.Packer -# and Packer200.Unpacker classes have special handling because of the $ in the file -# name. +# methods from classes that only go into the profile builds. BEANLESS_CLASSES = $(IMAGES_OUTPUTDIR)/beanless +# When there are $ characters in filenames we have some very subtle interactions between +# make expansion and shell expansion. In this particular case $< will contain a single $ while +# $@ will contain \$. So we have to pass $< in single-quotes to avoid shell expansion $(BEANLESS_CLASSES)/%: $(JDK_OUTPUTDIR)/classes/% $(MKDIR) -p $(@D) - $(TOOL_REMOVEMETHODS) $< $@ addPropertyChangeListener removePropertyChangeListener + $(TOOL_REMOVEMETHODS) '$<' $@ addPropertyChangeListener removePropertyChangeListener CLASSES_TO_DEBEAN = \ java/util/logging/LogManager.class \ + java/util/jar/Pack200\$$Packer.class \ + java/util/jar/Pack200\$$Unpacker.class \ com/sun/java/util/jar/pack/PackerImpl.class \ - com/sun/java/util/jar/pack/UnpackerImpl.class + com/sun/java/util/jar/pack/UnpackerImpl.class -BEANLESS_CLASSES_TARGETS = ifneq ($(PROFILE),) - BEANLESS_CLASSES_TARGETS := $(foreach c, $(CLASSES_TO_DEBEAN), $(BEANLESS_CLASSES)/$c) + BEANLESS_CLASSES_TARGETS := $(addprefix $(BEANLESS_CLASSES)/, $(CLASSES_TO_DEBEAN)) endif @@ -400,13 +402,8 @@ $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/rt.jar: $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_the $(ECHO) Updating rt.jar $(PROFILE) && \ $(CD) $(patsubst %$(VERSION_CLASS_PATH),%,$(CLASS_FILE)) && \ $(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(VERSION_CLASS_PATH); \ - $(MKDIR) -p $(BEANLESS_CLASSES)/java/util/jar; \ - $(TOOL_REMOVEMETHODS) $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200\$$Packer.class \ - $(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Packer.class addPropertyChangeListener removePropertyChangeListener; \ - $(TOOL_REMOVEMETHODS) $(JDK_OUTPUTDIR)/classes/java/util/jar/Pack200\$$Unpacker.class \ - $(BEANLESS_CLASSES)/java/util/jar/Pack200\$$Unpacker.class addPropertyChangeListener removePropertyChangeListener; \ $(CD) $(BEANLESS_CLASSES) && \ - $(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(CLASSES_TO_DEBEAN) java/util/jar/* ; \ + $(JAR) $(RT_JAR_UPDATE_OPTIONS) $@.tmp $(CLASSES_TO_DEBEAN); \ fi $(MV) $@.tmp $@ diff --git a/jdk/makefiles/ProfileNames.gmk b/jdk/makefiles/ProfileNames.gmk index 2e8640a7d32..b16e9153f06 100644 --- a/jdk/makefiles/ProfileNames.gmk +++ b/jdk/makefiles/ProfileNames.gmk @@ -30,9 +30,8 @@ PROFILE_NAMES := compact1 compact2 compact3 -# The include files use 1,2,3,4 for simplicity and conciseness. Internally we -# use profile_1, profile_2 and profile_3. Note that profile_4 is a full JRE so -# we never have to use it directly. +# The include files use 1,2,3 for simplicity and conciseness. Internally we +# use profile_1, profile_2 and profile_3. ALL_PROFILES := profile_1 profile_2 profile_3 diff --git a/jdk/makefiles/Profiles.gmk b/jdk/makefiles/Profiles.gmk index 864d98b855c..b4fb673ddf3 100644 --- a/jdk/makefiles/Profiles.gmk +++ b/jdk/makefiles/Profiles.gmk @@ -74,11 +74,11 @@ PROFILE_3_JARS := \ $(PROFILE_2_JARS) ifdef OPENJDK - PROFILE_4_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(PROFILE_4_JRE_JAR_FILES)) + FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES)) endif -PROFILE_4_JARS := \ - $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_4_JRE_JAR_FILES)) \ +FULL_JRE_JARS := \ + $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \ $(PROFILE_3_JARS) # The full set of "jar" files needed for a complete JDK (ct.sym and src.zip @@ -86,7 +86,7 @@ PROFILE_4_JARS := \ # Note we need to add back the regular form of all the custom profile jars e.g. # rt.jar and resources.jar -ALL_JARS := $(PROFILE_4_JARS) \ +ALL_JARS := $(FULL_JRE_JARS) \ $(IMAGES_OUTPUTDIR)/lib/rt.jar \ $(IMAGES_OUTPUTDIR)/lib/resources.jar \ $(IMAGES_OUTPUTDIR)/lib/jconsole.jar \ @@ -140,7 +140,7 @@ ALL_JRE_BIN_FILES := \ $(PROFILE_1_JRE_BIN_FILES) \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(PROFILE_4_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) NOT_JRE_BIN_FILES := $(filter-out $(ALL_JRE_BIN_FILES), $(NEW_ALL_BIN_LIST)) @@ -149,18 +149,18 @@ ifeq ($(PROFILE), profile_1) NOT_JRE_BIN_FILES += \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(PROFILE_4_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_BIN_FILES += \ $(PROFILE_3_JRE_BIN_FILES) \ - $(PROFILE_4_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_BIN_FILES += \ - $(PROFILE_4_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif NOT_JRE_BIN_FILES := $(addprefix $(JDK_OUTPUTDIR)/bin/, $(NOT_JRE_BIN_FILES)) @@ -173,7 +173,7 @@ ALL_JRE_LIB_FILES := \ $(PROFILE_1_JRE_LIB_FILES) \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(PROFILE_4_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) NOT_JRE_LIB_FILES := $(filter-out $(ALL_JRE_LIB_FILES), $(NEW_ALL_LIB_LIST)) @@ -189,18 +189,18 @@ ifeq ($(PROFILE), profile_1) NOT_JRE_LIB_FILES += \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(PROFILE_4_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_LIB_FILES += \ $(PROFILE_3_JRE_LIB_FILES) \ - $(PROFILE_4_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_LIB_FILES += \ - $(PROFILE_4_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif # Exclude the custom jar files as these will be added back via a special rule @@ -279,13 +279,13 @@ class_list = $(patsubst $(JDK_OUTPUTDIR)/classes/%,%,\ ifeq ($(PROFILE), profile_1) RT_JAR_EXCLUDES += \ - $(PROFILE_1_RTJAR_EXCLUDE_TYPES) \ + $(call class_list, $(PROFILE_1_RTJAR_EXCLUDE_TYPES)) \ $(PROFILE_2_RTJAR_INCLUDE_PACKAGES) \ $(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES)) \ $(PROFILE_3_RTJAR_INCLUDE_PACKAGES) \ $(call class_list, $(PROFILE_3_RTJAR_INCLUDE_TYPES)) \ - $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \ - $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES)) + $(FULL_JRE_RTJAR_INCLUDE_PACKAGES) \ + $(call class_list, $(FULL_JRE_RTJAR_INCLUDE_TYPES)) RT_JAR_INCLUDE_TYPES := \ $(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES)) PROFILE_INCLUDE_METAINF_SERVICES := \ @@ -293,11 +293,11 @@ ifeq ($(PROFILE), profile_1) endif ifeq ($(PROFILE), profile_2) RT_JAR_EXCLUDES += \ - $(PROFILE_2_RTJAR_EXCLUDE_TYPES) \ + $(call class_list, $(PROFILE_2_RTJAR_EXCLUDE_TYPES)) \ $(PROFILE_3_RTJAR_INCLUDE_PACKAGES) \ $(call class_list, $(PROFILE_3_RTJAR_INCLUDE_TYPES)) \ - $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \ - $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES)) + $(FULL_JRE_RTJAR_INCLUDE_PACKAGES) \ + $(call class_list, $(FULL_JRE_RTJAR_INCLUDE_TYPES)) RT_JAR_INCLUDE_TYPES := \ $(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES)) \ $(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES)) @@ -307,9 +307,9 @@ ifeq ($(PROFILE), profile_2) endif ifeq ($(PROFILE), profile_3) RT_JAR_EXCLUDES += \ - $(PROFILE_3_RTJAR_EXCLUDE_TYPES) \ - $(PROFILE_4_RTJAR_INCLUDE_PACKAGES) \ - $(call class_list, $(PROFILE_4_RTJAR_INCLUDE_TYPES)) + $(call class_list, $(PROFILE_3_RTJAR_EXCLUDE_TYPES)) \ + $(FULL_JRE_RTJAR_INCLUDE_PACKAGES) \ + $(call class_list, $(FULL_JRE_RTJAR_INCLUDE_TYPES)) RT_JAR_INCLUDE_TYPES := \ $(call class_list, $(PROFILE_1_RTJAR_INCLUDE_TYPES)) \ $(call class_list, $(PROFILE_2_RTJAR_INCLUDE_TYPES)) \ diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index 2472baeaa2f..de506edfd0a 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -142,7 +142,7 @@ PROFILE_3_JRE_JAR_FILES := \ management-agent.jar -PROFILE_4_JRE_BIN_FILES := \ +FULL_JRE_BIN_FILES := \ orbd$(EXE_SUFFIX) \ pack200$(EXE_SUFFIX) \ policytool$(EXE_SUFFIX) \ @@ -150,7 +150,7 @@ PROFILE_4_JRE_BIN_FILES := \ tnameserv$(EXE_SUFFIX) \ unpack200$(EXE_SUFFIX) -PROFILE_4_JRE_LIB_FILES := \ +FULL_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)awt_xawt$(SHARED_LIBRARY_SUFFIX) \ @@ -222,7 +222,7 @@ PROFILE_4_JRE_LIB_FILES := \ servicetag/jdk_header.png \ sound.properties -PROFILE_4_JRE_OTHER_FILES := \ +FULL_JRE_OTHER_FILES := \ man/ja_JP.UTF-8/man1/java.1 \ man/ja_JP.UTF-8/man1/javaws.1 \ man/ja_JP.UTF-8/man1/keytool.1 \ @@ -246,7 +246,7 @@ PROFILE_4_JRE_OTHER_FILES := \ man/man1/tnameserv.1 \ man/man1/unpack200.1 -PROFILE_4_JRE_JAR_FILES := \ +FULL_JRE_JAR_FILES := \ alt-rt.jar \ charsets.jar \ ext/cldrdata.jar \ diff --git a/jdk/makefiles/profile-rtjar-includes.txt b/jdk/makefiles/profile-rtjar-includes.txt index 4cc528e67d5..f7251d94147 100644 --- a/jdk/makefiles/profile-rtjar-includes.txt +++ b/jdk/makefiles/profile-rtjar-includes.txt @@ -22,119 +22,55 @@ # or visit www.oracle.com if you need additional information or have any # questions. # + +# Included or excluded types must take one of two forms +# - *.class to indicate all classes; or else +# - a full single type name e.g. +# com/sun/security/auth/callback/DialogCallbackHandler$$1.class +# You can not use arbitrary wildcards like DialogCallbackHandler*.class. +# +# Notes: +# - Nested types must use $$ in place of $ as $ is the make meta-character +# - If a package is not listed in any profile's inclusion list then it will +# not appear in any profile. But if a package is also missing from the +# full JRE's inclusion list then it will still be part of the full JRE. +# This is because the full JRE's inclusion lists are only used to define +# the exclusion lists for profiles; they are not used to define the full +# JRE contents - that is still done with the pre-profile legacy mechanism +# (all packagesthat can be found, less those not intended for rt.jar). +# This was done to minimize the impact of profiles on the regular +# non-profile build. +# PROFILE_1_RTJAR_INCLUDE_PACKAGES := \ com/sun/demo/jvmti/hprof \ com/sun/java/util/jar/pack \ com/sun/net/ssl \ - com/sun/net/ssl/internal/www/protocol/https \ com/sun/nio/file \ com/sun/security/cert/internal/x509 \ java/io \ java/lang \ - java/lang/annotation \ - java/lang/invoke \ - java/lang/ref \ - java/lang/reflect \ java/math \ java/net \ java/nio \ - java/nio/channels \ - java/nio/channels/spi \ - java/nio/charset \ - java/nio/charset/spi \ - java/nio/file \ - java/nio/file/attribute \ - java/nio/file/spi \ java/security \ - java/security/cert \ - java/security/interfaces \ - java/security/spec \ java/text \ - java/text/spi \ java/time \ java/util \ - java/util/concurrent \ - java/util/concurrent/atomic \ - java/util/concurrent/locks \ - java/util/function \ - java/util/jar \ - java/util/logging \ - java/util/regex \ - java/util/spi \ - java/util/zip \ javax/net \ - javax/net/ssl \ - javax/security/auth \ - javax/security/auth/callback \ - javax/security/auth/login \ - javax/security/auth/spi \ - javax/security/auth/x500 \ - javax/security/cert \ - jdk/internal \ + javax/security \ + jdk \ sun/invoke \ - sun/invoke/anon \ - sun/invoke/empty \ - sun/invoke/util \ sun/launcher \ - sun/launcher/resources \ sun/misc \ - sun/misc/resources \ sun/net/ \ - sun/net/idn \ - sun/net/sdp \ - sun/net/spi \ - sun/net/spi/nameservice \ - sun/net/util \ - sun/net/www \ - sun/net/www/http \ - sun/net/www/protocol/file \ - sun/net/www/protocol/http/ \ - sun/net/www/protocol/http/logging \ - sun/net/www/protocol/https \ - sun/net/www/protocol/jar \ sun/nio \ - sun/nio/ch \ - sun/nio/cs \ - sun/nio/fs \ sun/reflect \ - sun/reflect/annotation \ - sun/reflect/generics/factory \ - sun/reflect/generics/parser \ - sun/reflect/generics/reflectiveObjects \ - sun/reflect/generics/repository \ - sun/reflect/generics/scope \ - sun/reflect/generics/tree \ - sun/reflect/generics/visitor \ - sun/reflect/misc \ - sun/security/action \ - sun/security/ec \ - sun/security/jca \ - sun/security/pkcs \ - sun/security/pkcs10 \ - sun/security/pkcs12 \ - sun/security/provider \ - sun/security/provider/certpath \ - sun/security/provider/certpath/ssl \ - sun/security/rsa \ - sun/security/timestamp \ - sun/security/tools \ - sun/security/tools/keytool \ - sun/security/util \ - sun/security/validator \ - sun/security/x509 \ + sun/security \ sun/text \ - sun/text/bidi \ - sun/text/normalizer \ - sun/text/resources \ sun/usagetracker \ - sun/util \ - sun/util/calendar \ - sun/util/locale \ - sun/util/logging \ - sun/util/logging/resources \ - sun/util/resources + sun/util -PROFILE_1_RTJAR_INCLUDE_TYPES := +PROFILE_1_RTJAR_INCLUDE_TYPES := PROFILE_1_RTJAR_EXCLUDE_TYPES := @@ -144,139 +80,19 @@ PROFILE_1_INCLUDE_METAINF_SERVICES := PROFILE_2_RTJAR_INCLUDE_PACKAGES := \ com/sun/java_cup/internal/runtime \ com/sun/net/httpserver \ - com/sun/net/httpserver/spi \ - com/sun/org/apache/bcel/internal \ - com/sun/org/apache/bcel/internal/classfile \ - com/sun/org/apache/bcel/internal/generic \ - com/sun/org/apache/bcel/internal/util \ - com/sun/org/apache/regexp/internal \ - com/sun/org/apache/xalan/internal \ - com/sun/org/apache/xalan/internal/extensions \ - com/sun/org/apache/xalan/internal/lib \ - com/sun/org/apache/xalan/internal/res \ - com/sun/org/apache/xalan/internal/templates \ - com/sun/org/apache/xalan/internal/utils \ - com/sun/org/apache/xalan/internal/xslt \ - com/sun/org/apache/xalan/internal/xsltc \ - com/sun/org/apache/xalan/internal/xsltc/cmdline \ - com/sun/org/apache/xalan/internal/xsltc/cmdline/getopt \ - com/sun/org/apache/xalan/internal/xsltc/compiler \ - com/sun/org/apache/xalan/internal/xsltc/compiler/util \ - com/sun/org/apache/xalan/internal/xsltc/dom \ - com/sun/org/apache/xalan/internal/xsltc/runtime \ - com/sun/org/apache/xalan/internal/xsltc/runtime/output \ - com/sun/org/apache/xalan/internal/xsltc/trax \ - com/sun/org/apache/xalan/internal/xsltc/util \ - com/sun/org/apache/xerces/internal/dom \ - com/sun/org/apache/xerces/internal/dom/events \ - com/sun/org/apache/xerces/internal/impl \ - com/sun/org/apache/xerces/internal/impl/dtd \ - com/sun/org/apache/xerces/internal/impl/dtd/models \ - com/sun/org/apache/xerces/internal/impl/dv \ - com/sun/org/apache/xerces/internal/impl/dv/dtd \ - com/sun/org/apache/xerces/internal/impl/dv/util \ - com/sun/org/apache/xerces/internal/impl/dv/xs \ - com/sun/org/apache/xerces/internal/impl/io \ - com/sun/org/apache/xerces/internal/impl/msg \ - com/sun/org/apache/xerces/internal/impl/validation \ - com/sun/org/apache/xerces/internal/impl/xpath \ - com/sun/org/apache/xerces/internal/impl/xpath/regex \ - com/sun/org/apache/xerces/internal/impl/xs \ - com/sun/org/apache/xerces/internal/impl/xs/identity \ - com/sun/org/apache/xerces/internal/impl/xs/models \ - com/sun/org/apache/xerces/internal/impl/xs/opti \ - com/sun/org/apache/xerces/internal/impl/xs/traversers \ - com/sun/org/apache/xerces/internal/impl/xs/util \ - com/sun/org/apache/xerces/internal/jaxp \ - com/sun/org/apache/xerces/internal/jaxp/datatype \ - com/sun/org/apache/xerces/internal/jaxp/validation \ - com/sun/org/apache/xerces/internal/parsers \ - com/sun/org/apache/xerces/internal/util \ - com/sun/org/apache/xerces/internal/utils \ - com/sun/org/apache/xerces/internal/xinclude \ - com/sun/org/apache/xerces/internal/xni \ - com/sun/org/apache/xerces/internal/xni/grammars \ - com/sun/org/apache/xerces/internal/xni/parser \ - com/sun/org/apache/xerces/internal/xpointer \ - com/sun/org/apache/xerces/internal/xs \ - com/sun/org/apache/xerces/internal/xs/datatypes \ - com/sun/org/apache/xml/internal/dtm \ - com/sun/org/apache/xml/internal/dtm/ref \ - com/sun/org/apache/xml/internal/dtm/ref/dom2dtm \ - com/sun/org/apache/xml/internal/dtm/ref/sax2dtm \ - com/sun/org/apache/xml/internal/res \ - com/sun/org/apache/xml/internal/resolver \ - com/sun/org/apache/xml/internal/resolver/helpers \ - com/sun/org/apache/xml/internal/resolver/readers \ - com/sun/org/apache/xml/internal/resolver/tools \ - com/sun/org/apache/xml/internal/serialize \ - com/sun/org/apache/xml/internal/serializer \ - com/sun/org/apache/xml/internal/serializer/utils \ - com/sun/org/apache/xml/internal/utils \ - com/sun/org/apache/xml/internal/utils/res \ - com/sun/org/apache/xpath/internal \ - com/sun/org/apache/xpath/internal/axes \ - com/sun/org/apache/xpath/internal/compiler \ - com/sun/org/apache/xpath/internal/domapi \ - com/sun/org/apache/xpath/internal/functions \ - com/sun/org/apache/xpath/internal/jaxp \ - com/sun/org/apache/xpath/internal/objects \ - com/sun/org/apache/xpath/internal/operations \ - com/sun/org/apache/xpath/internal/patterns \ - com/sun/org/apache/xpath/internal/res \ + com/sun/org/apache \ com/sun/rmi/rmid \ - com/sun/xml/internal/stream/ \ - com/sun/xml/internal/stream/dtd \ - com/sun/xml/internal/stream/dtd/nonvalidating \ - com/sun/xml/internal/stream/events \ - com/sun/xml/internal/stream/util \ - com/sun/xml/internal/stream/writers \ + com/sun/xml/internal/stream \ java/rmi \ - java/rmi/activation \ - java/rmi/dgc \ - java/rmi/registry \ - java/rmi/server \ java/sql \ javax/rmi/ssl \ javax/sql \ javax/transaction \ - javax/transaction/xa \ javax/xml \ - javax/xml/datatype \ - javax/xml/namespace \ - javax/xml/parsers \ - javax/xml/stream \ - javax/xml/stream/events \ - javax/xml/stream/util \ - javax/xml/transform \ - javax/xml/transform/dom \ - javax/xml/transform/sax \ - javax/xml/transform/stax \ - javax/xml/transform/stream \ - javax/xml/validation \ - javax/xml/xpath \ - org/w3c/dom \ - org/w3c/dom/bootstrap \ - org/w3c/dom/css \ - org/w3c/dom/events \ - org/w3c/dom/html \ - org/w3c/dom/ls \ - org/w3c/dom/ranges \ - org/w3c/dom/stylesheets \ - org/w3c/dom/traversal \ - org/w3c/dom/views \ - org/w3c/dom/xpath \ + org/w3c \ org/xml/sax \ - org/xml/sax/ext \ - org/xml/sax/helpers \ sun/net/httpserver \ - sun/rmi/log \ - sun/rmi/registry \ - sun/rmi/runtime \ - sun/rmi/server \ - sun/rmi/transport \ - sun/rmi/transport/proxy \ - sun/rmi/transport/tcp \ + sun/rmi \ sun/util/xml PROFILE_2_RTJAR_INCLUDE_TYPES := @@ -284,287 +100,83 @@ PROFILE_2_RTJAR_INCLUDE_TYPES := PROFILE_2_RTJAR_EXCLUDE_TYPES := PROFILE_2_INCLUDE_METAINF_SERVICES := \ - META-INF/services/sun.util.spi.XmlPropertiesProvider + META-INF/services/sun.util.spi.XmlPropertiesProvider PROFILE_3_RTJAR_INCLUDE_PACKAGES := \ - com/sun/jmx/defaults \ - com/sun/jmx/interceptor \ - com/sun/jmx/mbeanserver \ - com/sun/jmx/remote/internal \ - com/sun/jmx/remote/protocol/rmi \ - com/sun/jmx/remote/security \ - com/sun/jmx/remote/util \ - com/sun/jmx/snmp \ - com/sun/jmx/snmp/IPAcl \ - com/sun/jmx/snmp/agent \ - com/sun/jmx/snmp/daemon \ - com/sun/jmx/snmp/defaults \ - com/sun/jmx/snmp/internal \ - com/sun/jmx/snmp/mpm \ - com/sun/jmx/snmp/tasks \ - com/sun/jmx/trace \ - com/sun/jndi/dns \ - com/sun/jndi/ldap \ - com/sun/jndi/ldap/ext \ - com/sun/jndi/ldap/pool \ - com/sun/jndi/ldap/sasl \ - com/sun/jndi/rmi/registry \ - com/sun/jndi/toolkit/ctx \ - com/sun/jndi/toolkit/dir \ - com/sun/jndi/toolkit/url \ - com/sun/jndi/url/dns \ - com/sun/jndi/url/ldap \ - com/sun/jndi/url/ldaps \ - com/sun/jndi/url/rmi \ + com/sun/jmx \ + com/sun/jndi \ com/sun/management \ - com/sun/management/jmx \ com/sun/naming/internal \ com/sun/nio/sctp \ com/sun/org/apache/xml/internal/security \ - com/sun/org/apache/xml/internal/security/algorithms \ - com/sun/org/apache/xml/internal/security/algorithms/implementations \ - com/sun/org/apache/xml/internal/security/c14n \ - com/sun/org/apache/xml/internal/security/c14n/helper \ - com/sun/org/apache/xml/internal/security/c14n/implementations \ - com/sun/org/apache/xml/internal/security/encryption \ - com/sun/org/apache/xml/internal/security/exceptions \ - com/sun/org/apache/xml/internal/security/keys \ - com/sun/org/apache/xml/internal/security/keys/content \ - com/sun/org/apache/xml/internal/security/keys/content/keyvalues \ - com/sun/org/apache/xml/internal/security/keys/content/x509 \ - com/sun/org/apache/xml/internal/security/keys/keyresolver \ - com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations \ - com/sun/org/apache/xml/internal/security/keys/storage \ - com/sun/org/apache/xml/internal/security/keys/storage/implementations \ - com/sun/org/apache/xml/internal/security/signature \ - com/sun/org/apache/xml/internal/security/transforms \ - com/sun/org/apache/xml/internal/security/transforms/implementations \ - com/sun/org/apache/xml/internal/security/transforms/params \ - com/sun/org/apache/xml/internal/security/utils \ - com/sun/org/apache/xml/internal/security/utils/resolver \ - com/sun/org/apache/xml/internal/security/utils/resolver/implementations \ com/sun/rowset \ - com/sun/rowset/internal \ - com/sun/rowset/providers \ - com/sun/script/javascript \ - com/sun/script/util \ + com/sun/script \ com/sun/security/auth \ - com/sun/security/auth/callback \ - com/sun/security/auth/login \ - com/sun/security/auth/module \ com/sun/security/jgss \ com/sun/security/ntlm \ com/sun/security/sasl \ - com/sun/security/sasl/digest \ - com/sun/security/sasl/gsskerb \ - com/sun/security/sasl/ntlm \ - com/sun/security/sasl/util \ com/sun/tracing \ - com/sun/tracing/dtrace \ java/lang/instrument \ java/lang/management \ java/security/acl \ java/util/prefs \ javax/annotation/processing \ javax/lang/model \ - javax/lang/model/element \ - javax/lang/model/type \ - javax/lang/model/util \ javax/management \ - javax/management/loading \ - javax/management/modelmbean \ - javax/management/monitor \ - javax/management/openmbean \ - javax/management/relation \ - javax/management/remote \ - javax/management/remote/rmi \ - javax/management/timer \ javax/naming \ - javax/naming/directory \ - javax/naming/event \ - javax/naming/ldap \ - javax/naming/spi \ javax/script \ javax/security/auth/kerberos \ javax/security/sasl \ javax/smartcardio \ javax/sql/rowset \ - javax/sql/rowset/serial \ - javax/sql/rowset/spi \ javax/tools \ - javax/tools/annotation \ javax/xml/crypto \ - javax/xml/crypto/dom \ - javax/xml/crypto/dsig \ - javax/xml/crypto/dsig/dom \ - javax/xml/crypto/dsig/keyinfo \ - javax/xml/crypto/dsig/spec \ org/ietf/jgss \ - org/jcp/xml/dsig/internal \ - org/jcp/xml/dsig/internal/dom \ + org/jcp/xml \ sun/instrument \ sun/management \ - sun/management/counter \ - sun/management/counter/perf \ - sun/management/jmxremote \ - sun/management/resources \ - sun/management/snmp \ - sun/management/snmp/jvminstr \ - sun/management/snmp/jvmmib \ - sun/management/snmp/util \ sun/net/dns \ sun/net/www/protocol/http/ntlm \ sun/net/www/protocol/http/spnego \ sun/nio/ch/sctp \ - sun/org/mozilla/classfile/internal \ - sun/org/mozilla/javascript/internal \ - sun/org/mozilla/javascript/internal/annotations \ - sun/org/mozilla/javascript/internal/ast \ - sun/org/mozilla/javascript/internal/debug \ - sun/org/mozilla/javascript/internal/jdk13 \ - sun/org/mozilla/javascript/internal/jdk15 \ - sun/org/mozilla/javascript/internal/json \ - sun/org/mozilla/javascript/internal/optimizer \ - sun/org/mozilla/javascript/internal/regexp \ - sun/org/mozilla/javascript/internal/serialize \ - sun/org/mozilla/javascript/internal/xml \ - sun/org/mozilla/javascript/internal/xmlimpl \ + sun/org/mozilla \ sun/security/acl \ sun/security/jgss \ - sun/security/jgss/krb5 \ - sun/security/jgss/spi \ - sun/security/jgss/spnego \ - sun/security/jgss/wrapper \ sun/security/krb5 \ - sun/security/krb5/internal \ - sun/security/krb5/internal/ccache \ - sun/security/krb5/internal/crypto \ - sun/security/krb5/internal/crypto/dk \ - sun/security/krb5/internal/ktab \ - sun/security/krb5/internal/rcache \ - sun/security/krb5/internal/util \ sun/security/provider/certpath/ldap \ sun/security/smartcardio \ - sun/tracing \ - sun/tracing/dtrace + sun/tracing -PROFILE_3_RTJAR_INCLUDE_TYPES := +PROFILE_3_RTJAR_INCLUDE_TYPES := PROFILE_3_RTJAR_EXCLUDE_TYPES := \ + com/sun/security/auth/callback/DialogCallbackHandler$$1.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$2.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$Action.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$ConfirmationInfo.class \ + com/sun/security/auth/callback/DialogCallbackHandler.class \ javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \ javax/management/remote/rmi/_RMIConnection_Stub.class \ javax/management/remote/rmi/_RMIServerImpl_Tie.class \ - javax/management/remote/rmi/_RMIServer_Stub.class \ - com/sun/security/auth/callback/DialogCallbackHandler.class \ - com/sun/security/auth/callback/DialogCallbackHandler\$$1.class \ - com/sun/security/auth/callback/DialogCallbackHandler\$$2.class \ - com/sun/security/auth/callback/DialogCallbackHandler\$$Action.class \ - com/sun/security/auth/callback/DialogCallbackHandler\$$ConfirmationInfo.class + javax/management/remote/rmi/_RMIServer_Stub.class PROFILE_3_INCLUDE_METAINF_SERVICES := \ META-INF/services/javax.script.ScriptEngineFactory -PROFILE_4_RTJAR_INCLUDE_PACKAGES := \ - com/oracle/net \ - com/oracle/nio \ - com/oracle/util \ +FULL_JRE_RTJAR_INCLUDE_PACKAGES := \ + com/oracle \ com/sun/accessibility/internal/resources \ com/sun/activation/registries \ com/sun/awt \ com/sun/beans \ - com/sun/beans/decoder \ - com/sun/beans/finder \ - com/sun/corba/se/impl/activation \ - com/sun/corba/se/impl/copyobject \ - com/sun/corba/se/impl/corba \ - com/sun/corba/se/impl/dynamicany \ - com/sun/corba/se/impl/encoding \ - com/sun/corba/se/impl/interceptors \ - com/sun/corba/se/impl/io \ - com/sun/corba/se/impl/ior \ - com/sun/corba/se/impl/ior/iiop \ - com/sun/corba/se/impl/javax/rmi \ - com/sun/corba/se/impl/javax/rmi/CORBA \ - com/sun/corba/se/impl/legacy/connection \ - com/sun/corba/se/impl/logging \ - com/sun/corba/se/impl/monitoring \ - com/sun/corba/se/impl/naming/cosnaming \ - com/sun/corba/se/impl/naming/namingutil \ - com/sun/corba/se/impl/naming/pcosnaming \ - com/sun/corba/se/impl/oa \ - com/sun/corba/se/impl/oa/poa \ - com/sun/corba/se/impl/oa/toa \ - com/sun/corba/se/impl/orb \ - com/sun/corba/se/impl/orbutil \ - com/sun/corba/se/impl/orbutil/closure \ - com/sun/corba/se/impl/orbutil/concurrent \ - com/sun/corba/se/impl/orbutil/fsm \ - com/sun/corba/se/impl/orbutil/graph \ - com/sun/corba/se/impl/orbutil/threadpool \ - com/sun/corba/se/impl/presentation/rmi \ - com/sun/corba/se/impl/protocol \ - com/sun/corba/se/impl/protocol/giopmsgheaders \ - com/sun/corba/se/impl/resolver \ - com/sun/corba/se/impl/transport \ - com/sun/corba/se/impl/util \ - com/sun/corba/se/internal/CosNaming \ - com/sun/corba/se/internal/Interceptors \ - com/sun/corba/se/internal/POA \ - com/sun/corba/se/internal/corba \ - com/sun/corba/se/internal/iiop \ - com/sun/corba/se/org/omg/CORBA \ - com/sun/corba/se/pept/broker \ - com/sun/corba/se/pept/encoding \ - com/sun/corba/se/pept/protocol \ - com/sun/corba/se/pept/transport \ - com/sun/corba/se/spi/activation \ - com/sun/corba/se/spi/activation/InitialNameServicePackage \ - com/sun/corba/se/spi/activation/LocatorPackage \ - com/sun/corba/se/spi/activation/RepositoryPackage \ - com/sun/corba/se/spi/copyobject \ - com/sun/corba/se/spi/encoding \ - com/sun/corba/se/spi/extension \ - com/sun/corba/se/spi/ior \ - com/sun/corba/se/spi/ior/iiop \ - com/sun/corba/se/spi/legacy/connection \ - com/sun/corba/se/spi/legacy/interceptor \ - com/sun/corba/se/spi/logging \ - com/sun/corba/se/spi/monitoring \ - com/sun/corba/se/spi/oa \ - com/sun/corba/se/spi/orb \ - com/sun/corba/se/spi/orbutil/closure \ - com/sun/corba/se/spi/orbutil/fsm \ - com/sun/corba/se/spi/orbutil/proxy \ - com/sun/corba/se/spi/orbutil/threadpool \ - com/sun/corba/se/spi/presentation/rmi \ - com/sun/corba/se/spi/protocol \ - com/sun/corba/se/spi/resolver \ - com/sun/corba/se/spi/servicecontext \ - com/sun/corba/se/spi/transport \ + com/sun/corba \ com/sun/image/codec/jpeg \ - com/sun/imageio/plugins/bmp \ - com/sun/imageio/plugins/common \ - com/sun/imageio/plugins/gif \ - com/sun/imageio/plugins/jpeg \ - com/sun/imageio/plugins/png \ - com/sun/imageio/plugins/wbmp \ - com/sun/imageio/spi \ - com/sun/imageio/stream \ - com/sun/istack/internal \ - com/sun/istack/internal/localization \ - com/sun/istack/internal/logging \ - com/sun/java/browser/dom \ - com/sun/java/browser/net \ + com/sun/imageio \ + com/sun/istack \ + com/sun/java/browser \ com/sun/java/swing \ - com/sun/java/swing/plaf/gtk \ - com/sun/java/swing/plaf/gtk/resources \ - com/sun/java/swing/plaf/motif \ - com/sun/java/swing/plaf/motif/resources \ - com/sun/java/swing/plaf/nimbus \ - com/sun/java/swing/plaf/windows \ - com/sun/java/swing/plaf/windows/resources \ com/sun/jmx/remote/protocol/iiop \ com/sun/jndi/cosnaming \ com/sun/jndi/toolkit/corba \ @@ -572,313 +184,41 @@ PROFILE_4_RTJAR_INCLUDE_PACKAGES := \ com/sun/jndi/url/iiop \ com/sun/jndi/url/iiopname \ com/sun/media/sound \ - com/sun/org/glassfish/external/amx \ - com/sun/org/glassfish/external/arc \ - com/sun/org/glassfish/external/probe/provider \ - com/sun/org/glassfish/external/probe/provider/annotations \ - com/sun/org/glassfish/external/statistics \ - com/sun/org/glassfish/external/statistics/annotations \ - com/sun/org/glassfish/external/statistics/impl \ - com/sun/org/glassfish/gmbal \ - com/sun/org/glassfish/gmbal/util \ - com/sun/org/omg/CORBA \ - com/sun/org/omg/CORBA/ValueDefPackage \ - com/sun/org/omg/CORBA/portable \ - com/sun/org/omg/SendingContext \ - com/sun/org/omg/SendingContext/CodeBasePackage \ + com/sun/org/glassfish \ + com/sun/org/omg \ com/sun/servicetag \ - com/sun/swing/internal/plaf/basic/resources \ - com/sun/swing/internal/plaf/metal/resources \ - com/sun/swing/internal/plaf/synth/resources \ + com/sun/swing \ com/sun/xml/internal/bind \ - com/sun/xml/internal/bind/annotation \ - com/sun/xml/internal/bind/api \ - com/sun/xml/internal/bind/api/impl \ - com/sun/xml/internal/bind/marshaller \ - com/sun/xml/internal/bind/unmarshaller \ - com/sun/xml/internal/bind/util \ - com/sun/xml/internal/bind/v2 \ - com/sun/xml/internal/bind/v2/bytecode \ - com/sun/xml/internal/bind/v2/model/annotation \ - com/sun/xml/internal/bind/v2/model/core \ - com/sun/xml/internal/bind/v2/model/impl \ - com/sun/xml/internal/bind/v2/model/nav \ - com/sun/xml/internal/bind/v2/model/runtime \ - com/sun/xml/internal/bind/v2/runtime \ - com/sun/xml/internal/bind/v2/runtime/output \ - com/sun/xml/internal/bind/v2/runtime/property \ - com/sun/xml/internal/bind/v2/runtime/reflect \ - com/sun/xml/internal/bind/v2/runtime/reflect/opt \ - com/sun/xml/internal/bind/v2/runtime/unmarshaller \ - com/sun/xml/internal/bind/v2/schemagen \ - com/sun/xml/internal/bind/v2/schemagen/episode \ - com/sun/xml/internal/bind/v2/schemagen/xmlschema \ - com/sun/xml/internal/bind/v2/util \ com/sun/xml/internal/fastinfoset \ - com/sun/xml/internal/fastinfoset/algorithm \ - com/sun/xml/internal/fastinfoset/alphabet \ - com/sun/xml/internal/fastinfoset/dom \ - com/sun/xml/internal/fastinfoset/org/apache/xerces/util \ - com/sun/xml/internal/fastinfoset/sax \ - com/sun/xml/internal/fastinfoset/stax \ - com/sun/xml/internal/fastinfoset/stax/events \ - com/sun/xml/internal/fastinfoset/stax/factory \ - com/sun/xml/internal/fastinfoset/stax/util \ - com/sun/xml/internal/fastinfoset/tools \ - com/sun/xml/internal/fastinfoset/util \ - com/sun/xml/internal/fastinfoset/vocab \ - com/sun/xml/internal/messaging/saaj \ - com/sun/xml/internal/messaging/saaj/client/p2p \ - com/sun/xml/internal/messaging/saaj/packaging/mime \ - com/sun/xml/internal/messaging/saaj/packaging/mime/internet \ - com/sun/xml/internal/messaging/saaj/packaging/mime/util \ - com/sun/xml/internal/messaging/saaj/soap \ - com/sun/xml/internal/messaging/saaj/soap/dynamic \ - com/sun/xml/internal/messaging/saaj/soap/impl \ - com/sun/xml/internal/messaging/saaj/soap/name \ - com/sun/xml/internal/messaging/saaj/soap/ver1_1 \ - com/sun/xml/internal/messaging/saaj/soap/ver1_2 \ - com/sun/xml/internal/messaging/saaj/util \ - com/sun/xml/internal/messaging/saaj/util/transform \ - com/sun/xml/internal/org/jvnet/fastinfoset \ - com/sun/xml/internal/org/jvnet/fastinfoset/sax \ - com/sun/xml/internal/org/jvnet/fastinfoset/sax/helpers \ - com/sun/xml/internal/org/jvnet/fastinfoset/stax \ - com/sun/xml/internal/org/jvnet/mimepull \ - com/sun/xml/internal/org/jvnet/staxex \ - com/sun/xml/internal/org/jvnet/ws \ - com/sun/xml/internal/org/jvnet/ws/databinding \ - com/sun/xml/internal/org/jvnet/ws/message \ + com/sun/xml/internal/messaging \ + com/sun/xml/internal/org \ com/sun/xml/internal/stream/buffer \ - com/sun/xml/internal/stream/buffer/sax \ - com/sun/xml/internal/stream/buffer/stax \ com/sun/xml/internal/txw2 \ - com/sun/xml/internal/txw2/annotation \ - com/sun/xml/internal/txw2/output \ - com/sun/xml/internal/ws/addressing \ - com/sun/xml/internal/ws/addressing/model \ - com/sun/xml/internal/ws/addressing/policy \ - com/sun/xml/internal/ws/addressing/v200408 \ - com/sun/xml/internal/ws/api \ - com/sun/xml/internal/ws/api/addressing \ - com/sun/xml/internal/ws/api/client \ - com/sun/xml/internal/ws/api/config/management \ - com/sun/xml/internal/ws/api/config/management/policy \ - com/sun/xml/internal/ws/api/databinding \ - com/sun/xml/internal/ws/api/fastinfoset \ - com/sun/xml/internal/ws/api/ha \ - com/sun/xml/internal/ws/api/handler \ - com/sun/xml/internal/ws/api/message \ - com/sun/xml/internal/ws/api/message/saaj \ - com/sun/xml/internal/ws/api/message/stream \ - com/sun/xml/internal/ws/api/model \ - com/sun/xml/internal/ws/api/model/soap \ - com/sun/xml/internal/ws/api/model/wsdl \ - com/sun/xml/internal/ws/api/pipe \ - com/sun/xml/internal/ws/api/pipe/helper \ - com/sun/xml/internal/ws/api/policy \ - com/sun/xml/internal/ws/api/policy/subject \ - com/sun/xml/internal/ws/api/server \ - com/sun/xml/internal/ws/api/streaming \ - com/sun/xml/internal/ws/api/wsdl/parser \ - com/sun/xml/internal/ws/api/wsdl/writer \ - com/sun/xml/internal/ws/binding \ - com/sun/xml/internal/ws/client \ - com/sun/xml/internal/ws/client/dispatch \ - com/sun/xml/internal/ws/client/sei \ - com/sun/xml/internal/ws/config/management/policy \ - com/sun/xml/internal/ws/db \ - com/sun/xml/internal/ws/db/glassfish \ - com/sun/xml/internal/ws/developer \ - com/sun/xml/internal/ws/encoding \ - com/sun/xml/internal/ws/encoding/fastinfoset \ - com/sun/xml/internal/ws/encoding/policy \ - com/sun/xml/internal/ws/encoding/soap \ - com/sun/xml/internal/ws/encoding/soap/streaming \ - com/sun/xml/internal/ws/encoding/xml \ - com/sun/xml/internal/ws/fault \ - com/sun/xml/internal/ws/handler \ - com/sun/xml/internal/ws/message \ - com/sun/xml/internal/ws/message/jaxb \ - com/sun/xml/internal/ws/message/saaj \ - com/sun/xml/internal/ws/message/source \ - com/sun/xml/internal/ws/message/stream \ - com/sun/xml/internal/ws/model \ - com/sun/xml/internal/ws/model/soap \ - com/sun/xml/internal/ws/model/wsdl \ - com/sun/xml/internal/ws/org/objectweb/asm \ - com/sun/xml/internal/ws/policy \ - com/sun/xml/internal/ws/policy/jaxws \ - com/sun/xml/internal/ws/policy/jaxws/spi \ - com/sun/xml/internal/ws/policy/privateutil \ - com/sun/xml/internal/ws/policy/sourcemodel \ - com/sun/xml/internal/ws/policy/sourcemodel/attach \ - com/sun/xml/internal/ws/policy/sourcemodel/wspolicy \ - com/sun/xml/internal/ws/policy/spi \ - com/sun/xml/internal/ws/policy/subject \ - com/sun/xml/internal/ws/protocol/soap \ - com/sun/xml/internal/ws/protocol/xml \ - com/sun/xml/internal/ws/resources \ - com/sun/xml/internal/ws/server \ - com/sun/xml/internal/ws/server/provider \ - com/sun/xml/internal/ws/server/sei \ - com/sun/xml/internal/ws/spi \ - com/sun/xml/internal/ws/spi/db \ - com/sun/xml/internal/ws/streaming \ - com/sun/xml/internal/ws/transport \ - com/sun/xml/internal/ws/transport/http \ - com/sun/xml/internal/ws/transport/http/client \ - com/sun/xml/internal/ws/transport/http/server \ - com/sun/xml/internal/ws/util \ - com/sun/xml/internal/ws/util/exception \ - com/sun/xml/internal/ws/util/localization \ - com/sun/xml/internal/ws/util/pipe \ - com/sun/xml/internal/ws/util/xml \ - com/sun/xml/internal/ws/wsdl \ - com/sun/xml/internal/ws/wsdl/parser \ - com/sun/xml/internal/ws/wsdl/writer \ - com/sun/xml/internal/ws/wsdl/writer/document \ - com/sun/xml/internal/ws/wsdl/writer/document/http \ - com/sun/xml/internal/ws/wsdl/writer/document/soap \ - com/sun/xml/internal/ws/wsdl/writer/document/soap12 \ - com/sun/xml/internal/ws/wsdl/writer/document/xsd \ + com/sun/xml/internal/ws \ java/applet \ java/awt \ - java/awt/color \ - java/awt/datatransfer \ - java/awt/dnd \ - java/awt/dnd/peer \ - java/awt/event \ - java/awt/font \ - java/awt/geom \ - java/awt/im \ - java/awt/im/spi \ - java/awt/image \ - java/awt/image/renderable \ - java/awt/peer \ - java/awt/print \ java/beans \ javax/accessibility \ javax/activation \ javax/activity \ javax/imageio \ - javax/imageio/event \ - javax/imageio/metadata \ - javax/imageio/plugins/bmp \ - javax/imageio/plugins/jpeg \ - javax/imageio/spi \ - javax/imageio/stream \ javax/jws \ - javax/jws/soap \ javax/print \ - javax/print/attribute \ - javax/print/attribute/standard \ - javax/print/event \ javax/rmi/CORBA \ - javax/sound/midi \ - javax/sound/midi/spi \ - javax/sound/sampled \ - javax/sound/sampled/spi \ + javax/sound \ javax/swing \ - javax/swing/border \ - javax/swing/colorchooser \ - javax/swing/event \ - javax/swing/filechooser \ - javax/swing/plaf \ - javax/swing/plaf/basic \ - javax/swing/plaf/metal \ - javax/swing/plaf/multi \ - javax/swing/plaf/nimbus \ - javax/swing/plaf/synth \ - javax/swing/table \ - javax/swing/text \ - javax/swing/text/html \ - javax/swing/text/html/parser \ - javax/swing/text/rtf \ - javax/swing/tree \ - javax/swing/undo \ javax/xml/bind \ - javax/xml/bind/annotation \ - javax/xml/bind/annotation/adapters \ - javax/xml/bind/attachment \ - javax/xml/bind/helpers \ - javax/xml/bind/util \ javax/xml/soap \ javax/xml/ws \ - javax/xml/ws/handler \ - javax/xml/ws/handler/soap \ - javax/xml/ws/http \ - javax/xml/ws/soap \ - javax/xml/ws/spi \ - javax/xml/ws/spi/http \ - javax/xml/ws/wsaddressing \ - org/omg/CORBA \ - org/omg/CORBA/DynAnyPackage \ - org/omg/CORBA/ORBPackage \ - org/omg/CORBA/TypeCodePackage \ - org/omg/CORBA/portable \ - org/omg/CORBA_2_3 \ - org/omg/CORBA_2_3/portable \ - org/omg/CosNaming \ - org/omg/CosNaming/NamingContextExtPackage \ - org/omg/CosNaming/NamingContextPackage \ - org/omg/Dynamic \ - org/omg/DynamicAny \ - org/omg/DynamicAny/DynAnyFactoryPackage \ - org/omg/DynamicAny/DynAnyPackage \ - org/omg/IOP \ - org/omg/IOP/CodecFactoryPackage \ - org/omg/IOP/CodecPackage \ - org/omg/Messaging \ - org/omg/PortableInterceptor \ - org/omg/PortableInterceptor/ORBInitInfoPackage \ - org/omg/PortableServer \ - org/omg/PortableServer/CurrentPackage \ - org/omg/PortableServer/POAManagerPackage \ - org/omg/PortableServer/POAPackage \ - org/omg/PortableServer/ServantLocatorPackage \ - org/omg/PortableServer/portable \ - org/omg/SendingContext \ - org/omg/stub/java/rmi \ - org/omg/stub/javax/management/remote/rmi \ + org/omg \ sun/applet \ - sun/applet/resources \ sun/audio \ sun/awt \ - sun/awt/X11 \ - sun/awt/datatransfer \ - sun/awt/dnd \ - sun/awt/event \ - sun/awt/geom \ - sun/awt/im \ - sun/awt/image \ - sun/awt/image/codec \ - sun/awt/motif \ - sun/awt/resources \ - sun/awt/shell \ - sun/awt/util \ - sun/awt/windows \ - sun/beans/editors \ - sun/beans/infos \ sun/corba \ sun/dc \ - sun/dc/path \ - sun/dc/pr \ sun/font \ sun/java2d \ - sun/java2d/cmm \ - sun/java2d/cmm/kcms \ - sun/java2d/cmm/lcms \ - sun/java2d/jules \ - sun/java2d/loops \ - sun/java2d/opengl \ - sun/java2d/pipe \ - sun/java2d/pipe/hw \ - sun/java2d/pisces \ - sun/java2d/x11 \ - sun/java2d/xr \ sun/net/ftp \ - sun/net/ftp/impl \ sun/net/smtp \ sun/net/www/content/audio \ sun/net/www/content/image \ @@ -887,27 +227,26 @@ PROFILE_4_RTJAR_INCLUDE_PACKAGES := \ sun/net/www/protocol/mailto \ sun/net/www/protocol/netdoc \ sun/print \ - sun/print/resources \ sun/security/tools/policytool \ sun/swing \ - sun/swing/icon \ - sun/swing/plaf \ - sun/swing/plaf/synth \ - sun/swing/plaf/windows \ - sun/swing/table \ - sun/swing/text \ - sun/swing/text/html \ - sun/tools/jar \ - sun/tools/jar/resources + sun/tools/jar -PROFILE_4_RTJAR_INCLUDE_TYPES := \ - com/sun/xml/internal/ws/*.class \ +FULL_JRE_RTJAR_INCLUDE_TYPES := \ + com/sun/security/auth/callback/DialogCallbackHandler$$1.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$2.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$Action.class \ + com/sun/security/auth/callback/DialogCallbackHandler$$ConfirmationInfo.class \ + com/sun/security/auth/callback/DialogCallbackHandler.class \ javax/annotation/*.class \ + javax/management/remote/rmi/_RMIConnectionImpl_Tie.class \ + javax/management/remote/rmi/_RMIConnection_Stub.class \ + javax/management/remote/rmi/_RMIServerImpl_Tie.class \ + javax/management/remote/rmi/_RMIServer_Stub.class \ javax/rmi/*.class -PROFILE_4_RTJAR_EXCLUDE_TYPES := +FULL_JRE_RTJAR_EXCLUDE_TYPES := -PROFILE_4_INCLUDE_METAINF_SERVICES := \ +FULL_JRE_INCLUDE_METAINF_SERVICES := \ META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \ META-INF/services/com.sun.tools.internal.xjc.Plugin \ META-INF/services/javax.print.PrintServiceLookup \ From be1b5fc17eacfd197c8e0d1d2e8de9d997cdbbec Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Thu, 14 Mar 2013 00:33:08 -0700 Subject: [PATCH 013/137] 8003348: SA can not read core file on OS Macosx uses Mach-O file format for binary files, not ELF format. Currently SA works on core files on other platforms, t his change enables SA work on core file generated on Darwin. Reviewed-by: sla, sspitsyn --- .../agent/src/os/bsd/MacosxDebuggerLocal.m | 691 +++++---- hotspot/agent/src/os/bsd/Makefile | 53 +- hotspot/agent/src/os/bsd/libproc.h | 49 +- hotspot/agent/src/os/bsd/libproc_impl.c | 474 +++--- hotspot/agent/src/os/bsd/libproc_impl.h | 111 +- hotspot/agent/src/os/bsd/ps_core.c | 1380 +++++++++++------ hotspot/agent/src/os/bsd/symtab.c | 201 ++- hotspot/agent/src/os/bsd/symtab.h | 6 +- .../sun/jvm/hotspot/BsdVtblAccess.java | 17 +- .../sun/jvm/hotspot/CommandProcessor.java | 4 +- .../classes/sun/jvm/hotspot/HotSpotAgent.java | 33 +- .../debugger/bsd/BsdDebuggerLocal.java | 52 +- .../jvm/hotspot/debugger/bsd/BsdThread.java | 12 +- .../sun/jvm/hotspot/runtime/JavaThread.java | 6 +- .../sun/jvm/hotspot/runtime/Threads.java | 12 +- .../classes/sun/jvm/hotspot/tools/PStack.java | 8 +- .../jvm/hotspot/utilities/PlatformInfo.java | 6 +- hotspot/agent/src/share/native/sadis.c | 12 +- hotspot/make/bsd/makefiles/saproc.make | 18 +- 19 files changed, 2097 insertions(+), 1048 deletions(-) diff --git a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m index c14c6b7bc4b..d5c23a012df 100644 --- a/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m +++ b/hotspot/agent/src/os/bsd/MacosxDebuggerLocal.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -40,12 +40,34 @@ #import #import #import +#include "libproc_impl.h" -jboolean debug = JNI_FALSE; +#define UNSUPPORTED_ARCH "Unsupported architecture!" + +#if defined(x86_64) && !defined(amd64) +#define amd64 1 +#endif + +#if amd64 +#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" +#else +#error UNSUPPORTED_ARCH +#endif static jfieldID symbolicatorID = 0; // set in _init0 static jfieldID taskID = 0; // set in _init0 +static jfieldID p_ps_prochandle_ID = 0; +static jfieldID loadObjectList_ID = 0; +static jmethodID listAdd_ID = 0; + +static jmethodID createClosestSymbol_ID = 0; +static jmethodID createLoadObject_ID = 0; +static jmethodID getJavaThreadsInfo_ID = 0; + +// indicator if thread id (lwpid_t) was set +static bool _threads_filled = false; + static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) { (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator); } @@ -76,6 +98,11 @@ static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg); } +static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) { + jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID); + return (struct ps_prochandle*)(intptr_t)ptr; +} + #if defined(__i386__) #define hsdb_thread_state_t x86_thread_state32_t #define hsdb_float_state_t x86_float_state32_t @@ -91,7 +118,7 @@ static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT #else - #error "Unsupported architecture" + #error UNSUPPORTED_ARCH #endif /* @@ -104,6 +131,66 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); taskID = (*env)->GetFieldID(env, cls, "task", "J"); CHECK_EXCEPTION; + + // for core file + p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J"); + CHECK_EXCEPTION; + loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;"); + CHECK_EXCEPTION; + + // methods we use + createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol", + "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); + CHECK_EXCEPTION; + createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject", + "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;"); + CHECK_EXCEPTION; + + // java.util.List method we call + jclass listClass = (*env)->FindClass(env, "java/util/List"); + CHECK_EXCEPTION; + listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); + CHECK_EXCEPTION; + getJavaThreadsInfo_ID = (*env)->GetMethodID(env, cls, "getJavaThreadsInfo", + "()[J"); + CHECK_EXCEPTION; + + init_libproc(getenv("LIBSAPROC_DEBUG") != NULL); +} + +JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize + (JNIEnv *env, jclass cls) +{ +#ifdef _LP64 + return 8; +#else + #error UNSUPPORTED_ARCH +#endif +} + +/** called by Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0 */ +jlong lookupByNameIncore( + JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jstring objectName, jstring symbolName) +{ + const char *objectName_cstr, *symbolName_cstr; + jlong addr; + jboolean isCopy; + objectName_cstr = NULL; + if (objectName != NULL) { + objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy); + CHECK_EXCEPTION_(0); + } + symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy); + CHECK_EXCEPTION_(0); + + print_debug("look for %s \n", symbolName_cstr); + addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr); + + if (objectName_cstr != NULL) { + (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); + } + (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr); + return addr; } /* @@ -116,14 +203,17 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0( JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) { + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + if (ph->core != NULL) { + return lookupByNameIncore(env, ph, this_obj, objectName, symbolName); + } + jlong address = 0; JNF_COCOA_ENTER(env); NSString *symbolNameString = JNFJavaToNSString(env, symbolName); - if (debug) { - printf("lookupInProcess called for %s\n", [symbolNameString UTF8String]); - } + print_debug("lookupInProcess called for %s\n", [symbolNameString UTF8String]); id symbolicator = getSymbolicator(env, this_obj); if (symbolicator != nil) { @@ -131,14 +221,48 @@ JNF_COCOA_ENTER(env); address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString); } - if (debug) { - printf("address of symbol %s = %llx\n", [symbolNameString UTF8String], address); - } + print_debug("address of symbol %s = %llx\n", [symbolNameString UTF8String], address); JNF_COCOA_EXIT(env); return address; } +/* + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal + * Method: lookupByAddress0 + * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; + */ +JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0 + (JNIEnv *env, jobject this_obj, jlong addr) { + uintptr_t offset; + const char* sym = NULL; + + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + sym = symbol_for_pc(ph, (uintptr_t) addr, &offset); + if (sym == NULL) return 0; + return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, + (*env)->NewStringUTF(env, sym), (jlong)offset); +} + +/** called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0 */ +jbyteArray readBytesFromCore( + JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jlong addr, jlong numBytes) +{ + jboolean isCopy; + jbyteArray array; + jbyte *bufPtr; + ps_err_e err; + + array = (*env)->NewByteArray(env, numBytes); + CHECK_EXCEPTION_(0); + bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy); + CHECK_EXCEPTION_(0); + + err = ps_pread(ph, (psaddr_t) (uintptr_t)addr, bufPtr, numBytes); + (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0); + return (err == PS_OK)? array : 0; +} + /* * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal * Method: readBytesFromProcess0 @@ -149,12 +273,15 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) { - if (debug) printf("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); + print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); // must allocate storage instead of using former parameter buf - jboolean isCopy; jbyteArray array; - jbyte *bufPtr; + + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + if (ph->core != NULL) { + return readBytesFromCore(env, ph, this_obj, addr, numBytes); + } array = (*env)->NewByteArray(env, numBytes); CHECK_EXCEPTION_(0); @@ -189,7 +316,7 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( // assume all failures are unmapped pages } - if (debug) fprintf(stderr, "%ld pages\n", pageCount); + print_debug("%ld pages\n", pageCount); remaining = numBytes; @@ -207,7 +334,7 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( } if (mapped[i]) { - if (debug) fprintf(stderr, "page %d mapped (len %ld start %ld)\n", i, len, start); + print_debug("page %d mapped (len %ld start %ld)\n", i, len, start); (*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start)); vm_deallocate(mach_task_self(), pages[i], vm_page_size); } @@ -220,6 +347,115 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( return array; } +/** Only used for core file reading, set thread_id for threads which is got after core file parsed. + * Thread context is available in Mach-O core file but thread id is not. We can get thread id + * from Threads which store all java threads information when they are created. Here we can identify + * them as java threads by checking if a thread's rsp or rbp within a java thread's stack. + * Note Macosx uses unique_thread_id which is different from other platforms though printed ids + * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long + * integers to host all java threads' id, stack_start, stack_end as: + * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...] + * + * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet). + * This function should be called only once if succeeded + */ +bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { + int n = 0, i = 0, j; + struct reg regs; + + jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID); + CHECK_EXCEPTION_(false); + int len = (int)(*env)->GetArrayLength(env, thrinfos); + uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL); + CHECK_EXCEPTION_(false); + n = get_num_threads(ph); + print_debug("fill_java_threads called, num_of_thread = %d\n", n); + for (i = 0; i < n; i++) { + if (!get_nth_lwp_regs(ph, i, ®s)) { + print_debug("Could not get regs of thread %d, already set!\n", i); + return false; + } + for (j = 0; j < len; j += 3) { + lwpid_t uid = cinfos[j]; + uint64_t beg = cinfos[j + 1]; + uint64_t end = cinfos[j + 2]; + if ((regs.r_rsp < end && regs.r_rsp >= beg) || + (regs.r_rbp < end && regs.r_rbp >= beg)) { + set_lwp_id(ph, i, uid); + break; + } + } + } + (*env)->ReleaseLongArrayElements(env, thrinfos, (jlong*)cinfos, 0); + CHECK_EXCEPTION_(false); + return true; +} + +/* For core file only, called from + * Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0 + */ +jlongArray getThreadIntegerRegisterSetFromCore(JNIEnv *env, jobject this_obj, long lwp_id) { + if (!_threads_filled) { + if (!fill_java_threads(env, this_obj, get_proc_handle(env, this_obj))) { + throw_new_debugger_exception(env, "Failed to fill in threads"); + return 0; + } else { + _threads_filled = true; + } + } + + struct reg gregs; + jboolean isCopy; + jlongArray array; + jlong *regs; + + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + if (get_lwp_regs(ph, lwp_id, &gregs) != true) { + THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0); + } + +#undef NPRGREG +#undef REG_INDEX +#if amd64 +#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg + + array = (*env)->NewLongArray(env, NPRGREG); + CHECK_EXCEPTION_(0); + regs = (*env)->GetLongArrayElements(env, array, &isCopy); + + regs[REG_INDEX(R15)] = gregs.r_r15; + regs[REG_INDEX(R14)] = gregs.r_r14; + regs[REG_INDEX(R13)] = gregs.r_r13; + regs[REG_INDEX(R12)] = gregs.r_r12; + regs[REG_INDEX(RBP)] = gregs.r_rbp; + regs[REG_INDEX(RBX)] = gregs.r_rbx; + regs[REG_INDEX(R11)] = gregs.r_r11; + regs[REG_INDEX(R10)] = gregs.r_r10; + regs[REG_INDEX(R9)] = gregs.r_r9; + regs[REG_INDEX(R8)] = gregs.r_r8; + regs[REG_INDEX(RAX)] = gregs.r_rax; + regs[REG_INDEX(RCX)] = gregs.r_rcx; + regs[REG_INDEX(RDX)] = gregs.r_rdx; + regs[REG_INDEX(RSI)] = gregs.r_rsi; + regs[REG_INDEX(RDI)] = gregs.r_rdi; + regs[REG_INDEX(RIP)] = gregs.r_rip; + regs[REG_INDEX(CS)] = gregs.r_cs; + regs[REG_INDEX(RSP)] = gregs.r_rsp; + regs[REG_INDEX(SS)] = gregs.r_ss; + regs[REG_INDEX(FSBASE)] = 0; + regs[REG_INDEX(GSBASE)] = 0; + regs[REG_INDEX(DS)] = gregs.r_ds; + regs[REG_INDEX(ES)] = gregs.r_es; + regs[REG_INDEX(FS)] = gregs.r_fs; + regs[REG_INDEX(GS)] = gregs.r_gs; + regs[REG_INDEX(TRAPNO)] = gregs.r_trapno; + regs[REG_INDEX(RFL)] = gregs.r_rflags; + +#endif /* amd64 */ + (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); + return array; +} /* * Lookup the thread_t that corresponds to the given thread_id. @@ -232,9 +468,7 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( */ thread_t lookupThreadFromThreadId(task_t task, jlong thread_id) { - if (debug) { - printf("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); - } + print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); thread_array_t thread_list = NULL; mach_msg_type_number_t thread_list_count = 0; @@ -244,9 +478,7 @@ lookupThreadFromThreadId(task_t task, jlong thread_id) { // get the list of all the send rights kern_return_t result = task_threads(task, &thread_list, &thread_list_count); if (result != KERN_SUCCESS) { - if (debug) { - printf("task_threads returned 0x%x\n", result); - } + print_debug("task_threads returned 0x%x\n", result); return 0; } @@ -257,9 +489,7 @@ lookupThreadFromThreadId(task_t task, jlong thread_id) { // get the THREAD_IDENTIFIER_INFO for the send right result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count); if (result != KERN_SUCCESS) { - if (debug) { - printf("thread_info returned 0x%x\n", result); - } + print_debug("thread_info returned 0x%x\n", result); break; } @@ -288,15 +518,17 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( JNIEnv *env, jobject this_obj, jlong thread_id) { - if (debug) - printf("getThreadRegisterSet0 called\n"); + print_debug("getThreadRegisterSet0 called\n"); + + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + if (ph->core != NULL) { + return getThreadIntegerRegisterSetFromCore(env, this_obj, thread_id); + } kern_return_t result; thread_t tid; mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT; hsdb_thread_state_t state; - unsigned int *r; - int i; jlongArray registerArray; jlong *primitiveArray; task_t gTask = getTask(env, this_obj); @@ -306,97 +538,56 @@ Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); if (result != KERN_SUCCESS) { - if (debug) - printf("getregs: thread_get_state(%d) failed (%d)\n", tid, result); + print_error("getregs: thread_get_state(%d) failed (%d)\n", tid, result); return NULL; } - // 40 32-bit registers on ppc, 16 on x86. - // Output order is the same as the order in the ppc_thread_state/i386_thread_state struct. -#if defined(__i386__) - r = (unsigned int *)&state; - registerArray = (*env)->NewLongArray(env, 8); - primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); - primitiveArray[0] = r[0]; // eax - primitiveArray[1] = r[2]; // ecx - primitiveArray[2] = r[3]; // edx - primitiveArray[3] = r[1]; // ebx - primitiveArray[4] = r[7]; // esp - primitiveArray[5] = r[6]; // ebp - primitiveArray[6] = r[5]; // esi - primitiveArray[7] = r[4]; // edi - (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); -#elif defined(__x86_64__) - /* From AMD64ThreadContext.java - public static final int R15 = 0; - public static final int R14 = 1; - public static final int R13 = 2; - public static final int R12 = 3; - public static final int R11 = 4; - public static final int R10 = 5; - public static final int R9 = 6; - public static final int R8 = 7; - public static final int RDI = 8; - public static final int RSI = 9; - public static final int RBP = 10; - public static final int RBX = 11; - public static final int RDX = 12; - public static final int RCX = 13; - public static final int RAX = 14; - public static final int TRAPNO = 15; - public static final int ERR = 16; - public static final int RIP = 17; - public static final int CS = 18; - public static final int RFL = 19; - public static final int RSP = 20; - public static final int SS = 21; - public static final int FS = 22; - public static final int GS = 23; - public static final int ES = 24; - public static final int DS = 25; - public static final int FSBASE = 26; - public static final int GSBASE = 27; - */ - // 64 bit - if (debug) printf("Getting threads for a 64-bit process\n"); - registerArray = (*env)->NewLongArray(env, 28); - primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); +#if amd64 +#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG +#undef REG_INDEX +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg - primitiveArray[0] = state.__r15; - primitiveArray[1] = state.__r14; - primitiveArray[2] = state.__r13; - primitiveArray[3] = state.__r12; - primitiveArray[4] = state.__r11; - primitiveArray[5] = state.__r10; - primitiveArray[6] = state.__r9; - primitiveArray[7] = state.__r8; - primitiveArray[8] = state.__rdi; - primitiveArray[9] = state.__rsi; - primitiveArray[10] = state.__rbp; - primitiveArray[11] = state.__rbx; - primitiveArray[12] = state.__rdx; - primitiveArray[13] = state.__rcx; - primitiveArray[14] = state.__rax; - primitiveArray[15] = 0; // trapno ? - primitiveArray[16] = 0; // err ? - primitiveArray[17] = state.__rip; - primitiveArray[18] = state.__cs; - primitiveArray[19] = state.__rflags; - primitiveArray[20] = state.__rsp; - primitiveArray[21] = 0; // We don't have SS - primitiveArray[22] = state.__fs; - primitiveArray[23] = state.__gs; - primitiveArray[24] = 0; - primitiveArray[25] = 0; - primitiveArray[26] = 0; - primitiveArray[27] = 0; + // 64 bit + print_debug("Getting threads for a 64-bit process\n"); + registerArray = (*env)->NewLongArray(env, NPRGREG); + CHECK_EXCEPTION_(0); + primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); - if (debug) printf("set registers\n"); + primitiveArray[REG_INDEX(R15)] = state.__r15; + primitiveArray[REG_INDEX(R14)] = state.__r14; + primitiveArray[REG_INDEX(R13)] = state.__r13; + primitiveArray[REG_INDEX(R12)] = state.__r12; + primitiveArray[REG_INDEX(R11)] = state.__r11; + primitiveArray[REG_INDEX(R10)] = state.__r10; + primitiveArray[REG_INDEX(R9)] = state.__r9; + primitiveArray[REG_INDEX(R8)] = state.__r8; + primitiveArray[REG_INDEX(RDI)] = state.__rdi; + primitiveArray[REG_INDEX(RSI)] = state.__rsi; + primitiveArray[REG_INDEX(RBP)] = state.__rbp; + primitiveArray[REG_INDEX(RBX)] = state.__rbx; + primitiveArray[REG_INDEX(RDX)] = state.__rdx; + primitiveArray[REG_INDEX(RCX)] = state.__rcx; + primitiveArray[REG_INDEX(RAX)] = state.__rax; + primitiveArray[REG_INDEX(TRAPNO)] = 0; // trapno, not used + primitiveArray[REG_INDEX(ERR)] = 0; // err, not used + primitiveArray[REG_INDEX(RIP)] = state.__rip; + primitiveArray[REG_INDEX(CS)] = state.__cs; + primitiveArray[REG_INDEX(RFL)] = state.__rflags; + primitiveArray[REG_INDEX(RSP)] = state.__rsp; + primitiveArray[REG_INDEX(SS)] = 0; // We don't have SS + primitiveArray[REG_INDEX(FS)] = state.__fs; + primitiveArray[REG_INDEX(GS)] = state.__gs; + primitiveArray[REG_INDEX(ES)] = 0; + primitiveArray[REG_INDEX(DS)] = 0; + primitiveArray[REG_INDEX(FSBASE)] = 0; + primitiveArray[REG_INDEX(GSBASE)] = 0; + print_debug("set registers\n"); + + (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); - (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); #else -#error Unsupported architecture -#endif +#error UNSUPPORTED_ARCH +#endif /* amd64 */ return registerArray; } @@ -410,8 +601,7 @@ JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( JNIEnv *env, jobject this_obj, jint tid) { - if (debug) - printf("translateTID0 called on tid = 0x%x\n", (int)tid); + print_debug("translateTID0 called on tid = 0x%x\n", (int)tid); kern_return_t result; thread_t foreign_tid, usable_tid; @@ -426,8 +616,7 @@ Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( if (result != KERN_SUCCESS) return -1; - if (debug) - printf("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid); + print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid); return (jint) usable_tid; } @@ -437,7 +626,7 @@ static bool ptrace_continue(pid_t pid, int signal) { // pass the signal to the process so we don't swallow it int res; if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) { - fprintf(stderr, "attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res); + print_error("attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res); return false; } return true; @@ -461,11 +650,11 @@ static bool ptrace_waitpid(pid_t pid) { return true; } if (!ptrace_continue(pid, WSTOPSIG(status))) { - fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status)); + print_error("attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status)); return false; } } else { - fprintf(stderr, "attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status); + print_error("attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status); return false; } } else { @@ -474,13 +663,13 @@ static bool ptrace_waitpid(pid_t pid) { continue; break; case ECHILD: - fprintf(stderr, "attach: waitpid() failed. Child process pid (%d) does not exist \n", pid); + print_error("attach: waitpid() failed. Child process pid (%d) does not exist \n", pid); break; case EINVAL: - fprintf(stderr, "attach: waitpid() failed. Invalid options argument.\n"); + print_error("attach: waitpid() failed. Invalid options argument.\n"); break; default: - fprintf(stderr, "attach: waitpid() failed. Unexpected error %d\n",errno); + print_error("attach: waitpid() failed. Unexpected error %d\n",errno); break; } return false; @@ -492,7 +681,7 @@ static bool ptrace_waitpid(pid_t pid) { static bool ptrace_attach(pid_t pid) { int res; if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) { - fprintf(stderr, "ptrace(PT_ATTACH, %d) failed with %d\n", pid, res); + print_error("ptrace(PT_ATTACH, %d) failed with %d\n", pid, res); return false; } else { return ptrace_waitpid(pid); @@ -504,23 +693,19 @@ static bool ptrace_attach(pid_t pid) { * Method: attach0 * Signature: (I)V */ -JNIEXPORT void JNICALL +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( - JNIEnv *env, jobject this_obj, jint jpid) + JNIEnv *env, jobject this_obj, jint jpid) { + print_debug("attach0 called for jpid=%d\n", (int)jpid); + JNF_COCOA_ENTER(env); - if (getenv("JAVA_SAPROC_DEBUG") != NULL) - debug = JNI_TRUE; - else - debug = JNI_FALSE; - if (debug) printf("attach0 called for jpid=%d\n", (int)jpid); - - // get the task from the pid + kern_return_t result; task_t gTask = 0; result = task_for_pid(mach_task_self(), jpid, &gTask); if (result != KERN_SUCCESS) { - fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result); + print_error("attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result); THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process"); } putTask(env, this_obj, gTask); @@ -550,18 +735,79 @@ JNF_COCOA_ENTER(env); JNF_COCOA_EXIT(env); } +/** For core file, + called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */ +static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { + int n = 0, i = 0; + + // add load objects + n = get_num_libs(ph); + for (i = 0; i < n; i++) { + uintptr_t base; + const char* name; + jobject loadObject; + jobject loadObjectList; + + base = get_lib_base(ph, i); + name = get_lib_name(ph, i); + loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, + (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base); + CHECK_EXCEPTION; + loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID); + CHECK_EXCEPTION; + (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject); + CHECK_EXCEPTION; + } +} + +/* + * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal + * Method: attach0 + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2( + JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) +{ + const char *execName_cstr; + const char *coreName_cstr; + jboolean isCopy; + struct ps_prochandle* ph; + + execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy); + CHECK_EXCEPTION; + coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy); + CHECK_EXCEPTION; + + print_debug("attach: %s %s\n", execName_cstr, coreName_cstr); + + if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) { + (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); + (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); + THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file"); + } + (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph); + (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); + (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); + fillLoadObjects(env, this_obj, ph); +} + /* * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal * Method: detach0 * Signature: ()V */ -JNIEXPORT void JNICALL +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( - JNIEnv *env, jobject this_obj) + JNIEnv *env, jobject this_obj) { + print_debug("detach0 called\n"); + struct ps_prochandle* ph = get_proc_handle(env, this_obj); + if (ph != NULL && ph->core != NULL) { + Prelease(ph); + return; + } JNF_COCOA_ENTER(env); - if (debug) printf("detach0 called\n"); - task_t gTask = getTask(env, this_obj); // detach from the ptraced process causing it to resume execution @@ -569,15 +815,15 @@ JNF_COCOA_ENTER(env); kern_return_t k_res; k_res = pid_for_task(gTask, &pid); if (k_res != KERN_SUCCESS) { - fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res); + print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res); } else { int res = ptrace(PT_DETACH, pid, 0, 0); if (res < 0) { - fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res); + print_error("detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res); } } - + mach_port_deallocate(mach_task_self(), gTask); id symbolicator = getSymbolicator(env, this_obj); if (symbolicator != nil) { @@ -585,170 +831,3 @@ JNF_COCOA_ENTER(env); } JNF_COCOA_EXIT(env); } - -/* - * Class: sun_jvm_hotspot_asm_Disassembler - * Method: load_library - * Signature: (Ljava/lang/String;)L - */ -JNIEXPORT jlong JNICALL -Java_sun_jvm_hotspot_asm_Disassembler_load_1library( - JNIEnv * env, - jclass disclass, - jstring jrepath_s, - jstring libname_s) -{ - uintptr_t func = 0; - const char* error_message = NULL; - const char* java_home; - jboolean isCopy; - uintptr_t *handle = NULL; - - const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/ - const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy); - char buffer[128]; - - /* Load the hsdis library */ - void* hsdis_handle; - hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL); - if (hsdis_handle == NULL) { - snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname); - hsdis_handle = dlopen(buffer, RTLD_LAZY | RTLD_GLOBAL); - } - if (hsdis_handle != NULL) { - func = (uintptr_t)dlsym(hsdis_handle, "decode_instructions_virtual"); - } - if (func == 0) { - error_message = dlerror(); - fprintf(stderr, "%s\n", error_message); - } - - (*env)->ReleaseStringUTFChars(env, libname_s, libname); - (*env)->ReleaseStringUTFChars(env, jrepath_s, jrepath); - - if (func == 0) { - /* Couldn't find entry point. error_message should contain some - * platform dependent error message. - */ - THROW_NEW_DEBUGGER_EXCEPTION_(error_message, (jlong)func); - } - return (jlong)func; -} - -/* signature of decode_instructions_virtual from hsdis.h */ -typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va, - unsigned char* start, uintptr_t length, - void* (*event_callback)(void*, const char*, void*), - void* event_stream, - int (*printf_callback)(void*, const char*, ...), - void* printf_stream, - const char* options); - -/* container for call back state when decoding instructions */ -typedef struct { - JNIEnv* env; - jobject dis; - jobject visitor; - jmethodID handle_event; - jmethodID raw_print; - char buffer[4096]; -} decode_env; - - -/* event callback binding to Disassembler.handleEvent */ -static void* event_to_env(void* env_pv, const char* event, void* arg) { - decode_env* denv = (decode_env*)env_pv; - JNIEnv* env = denv->env; - jstring event_string = (*env)->NewStringUTF(env, event); - jlong result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor, - event_string, (jlong) (uintptr_t)arg); - /* ignore exceptions for now */ - CHECK_EXCEPTION_CLEAR_((void *)0); - return (void*)(uintptr_t)result; -} - -/* printing callback binding to Disassembler.rawPrint */ -static int printf_to_env(void* env_pv, const char* format, ...) { - jstring output; - va_list ap; - int cnt; - decode_env* denv = (decode_env*)env_pv; - JNIEnv* env = denv->env; - size_t flen = strlen(format); - const char* raw = NULL; - - if (flen == 0) return 0; - if (flen < 2 || - strchr(format, '%') == NULL) { - raw = format; - } else if (format[0] == '%' && format[1] == '%' && - strchr(format+2, '%') == NULL) { - // happens a lot on machines with names like %foo - flen--; - raw = format+1; - } - if (raw != NULL) { - jstring output = (*env)->NewStringUTF(env, raw); - (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); - CHECK_EXCEPTION_CLEAR; - return (int) flen; - } - va_start(ap, format); - cnt = vsnprintf(denv->buffer, sizeof(denv->buffer), format, ap); - va_end(ap); - - output = (*env)->NewStringUTF(env, denv->buffer); - (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); - CHECK_EXCEPTION_CLEAR; - return cnt; -} - -/* - * Class: sun_jvm_hotspot_asm_Disassembler - * Method: decode - * Signature: (Lsun/jvm/hotspot/asm/InstructionVisitor;J[BLjava/lang/String;J)V - */ -JNIEXPORT void JNICALL -Java_sun_jvm_hotspot_asm_Disassembler_decode( - JNIEnv * env, - jobject dis, - jobject visitor, - jlong startPc, - jbyteArray code, - jstring options_s, - jlong decode_instructions_virtual) -{ - jboolean isCopy; - jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy); - jbyte* end = start + (*env)->GetArrayLength(env, code); - const char * options = (*env)->GetStringUTFChars(env, options_s, &isCopy); - jclass disclass = (*env)->GetObjectClass(env, dis); - - decode_env denv; - denv.env = env; - denv.dis = dis; - denv.visitor = visitor; - - /* find Disassembler.handleEvent callback */ - denv.handle_event = (*env)->GetMethodID(env, disclass, "handleEvent", - "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J"); - CHECK_EXCEPTION_CLEAR_VOID - - /* find Disassembler.rawPrint callback */ - denv.raw_print = (*env)->GetMethodID(env, disclass, "rawPrint", - "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V"); - CHECK_EXCEPTION_CLEAR_VOID - - /* decode the buffer */ - (*(decode_func)(uintptr_t)decode_instructions_virtual)(startPc, - startPc + end - start, - (unsigned char*)start, - end - start, - &event_to_env, (void*) &denv, - &printf_to_env, (void*) &denv, - options); - - /* cleanup */ - (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); - (*env)->ReleaseStringUTFChars(env, options_s, options); -} diff --git a/hotspot/agent/src/os/bsd/Makefile b/hotspot/agent/src/os/bsd/Makefile index 90085c6ee9e..ce3e2c4c32c 100644 --- a/hotspot/agent/src/os/bsd/Makefile +++ b/hotspot/agent/src/os/bsd/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -22,34 +22,60 @@ # # -ARCH := $(shell if ([ `uname -m` = "ia64" ]) ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi ) +ARCH := $(shell if ([ `uname -m` = "ia64" ]) ; then echo ia64 ; elif ([ `uname -m` = "amd64" ]) ; then echo amd64; elif ([ `uname -m` = "x86_64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi ) + +OS := $(shell uname -s) + GCC = gcc JAVAH = ${JAVA_HOME}/bin/javah +ifneq ($(OS), Darwin) SOURCES = salibelf.c \ symtab.c \ libproc_impl.c \ ps_proc.c \ ps_core.c \ BsdDebuggerLocal.c - -INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") - -OBJS = $(SOURCES:.c=.o) +OBJS = $(SOURCES:.c=.o) +OBJSPLUS = $(OBJS) sadis.o +LIBSA = $(ARCH)/libsaproc.so LIBS = -lutil -lthread_db -CFLAGS = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) +else + +SOURCES = symtab.c \ + libproc_impl.c \ + ps_core.c +OBJS = $(SOURCES:.c=.o) +OBJSPLUS = MacosxDebuggerLocal.o sadis.o $(OBJS) +EXTINCLUDE = -I/System/Library/Frameworks/JavaVM.framework/Headers -I. +EXTCFLAGS = -m64 -D__APPLE__ -framework JavaNativeFoundation +FOUNDATIONFLAGS = -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation +LIBSA = $(ARCH)/libsaproc.dylib +endif # Darwin + +INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") $(EXTINCLUDE) + + + +CFLAGS = -c -fPIC -g -Wall -D_ALLBSD_SOURCE -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) $(EXTCFLAGS) + -LIBSA = $(ARCH)/libsaproc.so all: $(LIBSA) -BsdDebuggerLocal.o: BsdDebuggerLocal.c - $(JAVAH) -jni -classpath ../../../../../build/bsd-i586/hotspot/outputdir/bsd_i486_compiler2/generated/saclasses \ +MacosxDebuggerLocal.o: MacosxDebuggerLocal.m + echo "OS="$(OS) + $(JAVAH) -jni -classpath ../../../build/classes \ sun.jvm.hotspot.debugger.x86.X86ThreadContext \ sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext + $(GCC) $(CFLAGS) $(FOUNDATIONFLAGS) $< + +sadis.o: ../../share/native/sadis.c + $(JAVAH) -jni -classpath ../../../build/classes \ + sun.jvm.hotspot.asm.Disassembler $(GCC) $(CFLAGS) $< .c.obj: @@ -59,9 +85,9 @@ ifndef LDNOMAP LFLAGS_LIBSA = -Xlinker --version-script=mapfile endif -$(LIBSA): $(OBJS) mapfile +$(LIBSA): $(OBJSPLUS) mapfile if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi - $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS) + $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(FOUNDATIONFLAGS) $(OBJSPLUS) $(LIBS) $(SALIBS) test.o: $(LIBSA) test.c $(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c @@ -71,7 +97,6 @@ test: test.o clean: rm -f $(LIBSA) - rm -f $(OBJS) + rm -f *.o rm -f test.o -rmdir $(ARCH) - diff --git a/hotspot/agent/src/os/bsd/libproc.h b/hotspot/agent/src/os/bsd/libproc.h index 74bb84c1760..11e00dcb828 100644 --- a/hotspot/agent/src/os/bsd/libproc.h +++ b/hotspot/agent/src/os/bsd/libproc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, 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 @@ -27,9 +27,38 @@ #include #include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +typedef enum ps_err_e { + PS_OK, PS_ERR, PS_BADPID, PS_BADLID, + PS_BADADDR, PS_NOSYM, PS_NOFREGS +} ps_err_e; + +#ifndef psaddr_t +#define psaddr_t uintptr_t +#endif + +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif // bool + +#ifndef lwpid_t +#define lwpid_t uintptr_t +#endif + +#include +#else // __APPLE__ +#include +#include #include #include - #if defined(sparc) || defined(sparcv9) /* If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64 @@ -44,6 +73,14 @@ #endif //sparc or sparcv9 +// This C bool type must be int for compatibility with BSD calls and +// it would be a mistake to equivalence it to C++ bool on many platforms +typedef int bool; +#define true 1 +#define false 0 + +#endif // __APPLE__ + /************************************************************************************ 0. This is very minimal subset of Solaris libproc just enough for current application. @@ -72,13 +109,7 @@ combination of ptrace and /proc calls. *************************************************************************************/ -// This C bool type must be int for compatibility with BSD calls and -// it would be a mistake to equivalence it to C++ bool on many platforms - -typedef int bool; -#define true 1 -#define false 0 - +struct reg; struct ps_prochandle; // attach to a process diff --git a/hotspot/agent/src/os/bsd/libproc_impl.c b/hotspot/agent/src/os/bsd/libproc_impl.c index e9fa1b82a34..78da80617fa 100644 --- a/hotspot/agent/src/os/bsd/libproc_impl.c +++ b/hotspot/agent/src/os/bsd/libproc_impl.c @@ -21,12 +21,6 @@ * questions. * */ -#include -#include -#include -#include -#include -#include #include "libproc_impl.h" static const char* alt_root = NULL; @@ -34,61 +28,65 @@ static int alt_root_len = -1; #define SA_ALTROOT "SA_ALTROOT" +off_t ltell(int fd) { + return lseek(fd, 0, SEEK_CUR); +} + static void init_alt_root() { - if (alt_root_len == -1) { - alt_root = getenv(SA_ALTROOT); - if (alt_root) { - alt_root_len = strlen(alt_root); - } else { - alt_root_len = 0; - } - } + if (alt_root_len == -1) { + alt_root = getenv(SA_ALTROOT); + if (alt_root) { + alt_root_len = strlen(alt_root); + } else { + alt_root_len = 0; + } + } } int pathmap_open(const char* name) { - int fd; - char alt_path[PATH_MAX + 1]; + int fd; + char alt_path[PATH_MAX + 1]; - init_alt_root(); - fd = open(name, O_RDONLY); - if (fd >= 0) { + init_alt_root(); + + if (alt_root_len > 0) { + strcpy(alt_path, alt_root); + strcat(alt_path, name); + fd = open(alt_path, O_RDONLY); + if (fd >= 0) { + print_debug("path %s substituted for %s\n", alt_path, name); return fd; - } + } - if (alt_root_len > 0) { + if (strrchr(name, '/')) { strcpy(alt_path, alt_root); - strcat(alt_path, name); + strcat(alt_path, strrchr(name, '/')); fd = open(alt_path, O_RDONLY); if (fd >= 0) { - print_debug("path %s substituted for %s\n", alt_path, name); - return fd; + print_debug("path %s substituted for %s\n", alt_path, name); + return fd; } - - if (strrchr(name, '/')) { - strcpy(alt_path, alt_root); - strcat(alt_path, strrchr(name, '/')); - fd = open(alt_path, O_RDONLY); - if (fd >= 0) { - print_debug("path %s substituted for %s\n", alt_path, name); - return fd; - } - } - } - - return -1; + } + } else { + fd = open(name, O_RDONLY); + if (fd >= 0) { + return fd; + } + } + return -1; } static bool _libsaproc_debug; void print_debug(const char* format,...) { - if (_libsaproc_debug) { - va_list alist; + if (_libsaproc_debug) { + va_list alist; - va_start(alist, format); - fputs("libsaproc DEBUG: ", stderr); - vfprintf(stderr, format, alist); - va_end(alist); - } + va_start(alist, format); + fputs("libsaproc DEBUG: ", stderr); + vfprintf(stderr, format, alist); + va_end(alist); + } } void print_error(const char* format,...) { @@ -100,172 +98,235 @@ void print_error(const char* format,...) { } bool is_debug() { - return _libsaproc_debug; + return _libsaproc_debug; } +#ifdef __APPLE__ +// get arch offset in file +bool get_arch_off(int fd, cpu_type_t cputype, off_t *offset) { + struct fat_header fatheader; + struct fat_arch fatarch; + off_t img_start = 0; + + off_t pos = ltell(fd); + if (read(fd, (void *)&fatheader, sizeof(struct fat_header)) != sizeof(struct fat_header)) { + return false; + } + if (fatheader.magic == FAT_CIGAM) { + int i; + for (i = 0; i < ntohl(fatheader.nfat_arch); i++) { + if (read(fd, (void *)&fatarch, sizeof(struct fat_arch)) != sizeof(struct fat_arch)) { + return false; + } + if (ntohl(fatarch.cputype) == cputype) { + print_debug("fat offset=%x\n", ntohl(fatarch.offset)); + img_start = ntohl(fatarch.offset); + break; + } + } + if (img_start == 0) { + return false; + } + } + lseek(fd, pos, SEEK_SET); + *offset = img_start; + return true; +} + +bool is_macho_file(int fd) { + mach_header_64 fhdr; + off_t x86_64_off; + + if (fd < 0) { + print_debug("Invalid file handle passed to is_macho_file\n"); + return false; + } + + off_t pos = ltell(fd); + // check fat header + if (!get_arch_off(fd, CPU_TYPE_X86_64, &x86_64_off)) { + print_debug("failed to get fat header\n"); + return false; + } + lseek(fd, x86_64_off, SEEK_SET); + if (read(fd, (void *)&fhdr, sizeof(mach_header_64)) != sizeof(mach_header_64)) { + return false; + } + lseek(fd, pos, SEEK_SET); // restore + print_debug("fhdr.magic %x\n", fhdr.magic); + return (fhdr.magic == MH_MAGIC_64 || fhdr.magic == MH_CIGAM_64); +} + +#endif //__APPLE__ + // initialize libproc bool init_libproc(bool debug) { - // init debug mode _libsaproc_debug = debug; - +#ifndef __APPLE__ // initialize the thread_db library if (td_init() != TD_OK) { print_debug("libthread_db's td_init failed\n"); return false; } - +#endif // __APPLE__ return true; } -static void destroy_lib_info(struct ps_prochandle* ph) { - lib_info* lib = ph->libs; - while (lib) { - lib_info *next = lib->next; - if (lib->symtab) { - destroy_symtab(lib->symtab); - } - free(lib); - lib = next; - } +void destroy_lib_info(struct ps_prochandle* ph) { + lib_info* lib = ph->libs; + while (lib) { + lib_info* next = lib->next; + if (lib->symtab) { + destroy_symtab(lib->symtab); + } + free(lib); + lib = next; + } } -static void destroy_thread_info(struct ps_prochandle* ph) { - thread_info* thr = ph->threads; - while (thr) { - thread_info *next = thr->next; - free(thr); - thr = next; - } +void destroy_thread_info(struct ps_prochandle* ph) { + sa_thread_info* thr = ph->threads; + while (thr) { + sa_thread_info* n = thr->next; + free(thr); + thr = n; + } } -// ps_prochandle cleanup - // ps_prochandle cleanup void Prelease(struct ps_prochandle* ph) { - // do the "derived class" clean-up first - ph->ops->release(ph); - destroy_lib_info(ph); - destroy_thread_info(ph); - free(ph); + // do the "derived class" clean-up first + ph->ops->release(ph); + destroy_lib_info(ph); + destroy_thread_info(ph); + free(ph); } lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) { - return add_lib_info_fd(ph, libname, -1, base); + return add_lib_info_fd(ph, libname, -1, base); } lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) { lib_info* newlib; + print_debug("add_lib_info_fd %s\n", libname); - if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) { - print_debug("can't allocate memory for lib_info\n"); - return NULL; - } + if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) { + print_debug("can't allocate memory for lib_info\n"); + return NULL; + } - strncpy(newlib->name, libname, sizeof(newlib->name)); - newlib->base = base; + strncpy(newlib->name, libname, sizeof(newlib->name)); + newlib->base = base; - if (fd == -1) { - if ( (newlib->fd = pathmap_open(newlib->name)) < 0) { - print_debug("can't open shared object %s\n", newlib->name); - free(newlib); - return NULL; - } - } else { - newlib->fd = fd; - } - - // check whether we have got an ELF file. /proc//map - // gives out all file mappings and not just shared objects - if (is_elf_file(newlib->fd) == false) { - close(newlib->fd); + if (fd == -1) { + if ( (newlib->fd = pathmap_open(newlib->name)) < 0) { + print_debug("can't open shared object %s\n", newlib->name); free(newlib); return NULL; - } + } + } else { + newlib->fd = fd; + } - newlib->symtab = build_symtab(newlib->fd); - if (newlib->symtab == NULL) { - print_debug("symbol table build failed for %s\n", newlib->name); - } - else { - print_debug("built symbol table for %s\n", newlib->name); - } +#ifdef __APPLE__ + // check whether we have got an Macho file. + if (is_macho_file(newlib->fd) == false) { + close(newlib->fd); + free(newlib); + print_debug("not a mach-o file\n"); + return NULL; + } +#else + // check whether we have got an ELF file. /proc//map + // gives out all file mappings and not just shared objects + if (is_elf_file(newlib->fd) == false) { + close(newlib->fd); + free(newlib); + return NULL; + } +#endif // __APPLE__ - // even if symbol table building fails, we add the lib_info. - // This is because we may need to read from the ELF file for core file - // address read functionality. lookup_symbol checks for NULL symtab. - if (ph->libs) { - ph->lib_tail->next = newlib; - ph->lib_tail = newlib; - } else { - ph->libs = ph->lib_tail = newlib; - } - ph->num_libs++; + newlib->symtab = build_symtab(newlib->fd); + if (newlib->symtab == NULL) { + print_debug("symbol table build failed for %s\n", newlib->name); + } else { + print_debug("built symbol table for %s\n", newlib->name); + } - return newlib; + // even if symbol table building fails, we add the lib_info. + // This is because we may need to read from the ELF file or MachO file for core file + // address read functionality. lookup_symbol checks for NULL symtab. + if (ph->libs) { + ph->lib_tail->next = newlib; + ph->lib_tail = newlib; + } else { + ph->libs = ph->lib_tail = newlib; + } + ph->num_libs++; + return newlib; } // lookup for a specific symbol uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name, const char* sym_name) { - // ignore object_name. search in all libraries - // FIXME: what should we do with object_name?? The library names are obtained - // by parsing /proc//maps, which may not be the same as object_name. - // What we need is a utility to map object_name to real file name, something - // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For - // now, we just ignore object_name and do a global search for the symbol. + // ignore object_name. search in all libraries + // FIXME: what should we do with object_name?? The library names are obtained + // by parsing /proc//maps, which may not be the same as object_name. + // What we need is a utility to map object_name to real file name, something + // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For + // now, we just ignore object_name and do a global search for the symbol. - lib_info* lib = ph->libs; - while (lib) { - if (lib->symtab) { - uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL); - if (res) return res; - } - lib = lib->next; - } + lib_info* lib = ph->libs; + while (lib) { + if (lib->symtab) { + uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL); + if (res) return res; + } + lib = lib->next; + } - print_debug("lookup failed for symbol '%s' in obj '%s'\n", + print_debug("lookup failed for symbol '%s' in obj '%s'\n", sym_name, object_name); - return (uintptr_t) NULL; + return (uintptr_t) NULL; } - const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) { - const char* res = NULL; - lib_info* lib = ph->libs; - while (lib) { - if (lib->symtab && addr >= lib->base) { - res = nearest_symbol(lib->symtab, addr - lib->base, poffset); - if (res) return res; - } - lib = lib->next; - } - return NULL; + const char* res = NULL; + lib_info* lib = ph->libs; + while (lib) { + if (lib->symtab && addr >= lib->base) { + res = nearest_symbol(lib->symtab, addr - lib->base, poffset); + if (res) return res; + } + lib = lib->next; + } + return NULL; } // add a thread to ps_prochandle -thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) { - thread_info* newthr; - if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) { - print_debug("can't allocate memory for thread_info\n"); - return NULL; - } +sa_thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) { + sa_thread_info* newthr; + if ( (newthr = (sa_thread_info*) calloc(1, sizeof(sa_thread_info))) == NULL) { + print_debug("can't allocate memory for thread_info\n"); + return NULL; + } - // initialize thread info - newthr->pthread_id = pthread_id; - newthr->lwp_id = lwp_id; + // initialize thread info + newthr->pthread_id = pthread_id; + newthr->lwp_id = lwp_id; - // add new thread to the list - newthr->next = ph->threads; - ph->threads = newthr; - ph->num_threads++; - return newthr; + // add new thread to the list + newthr->next = ph->threads; + ph->threads = newthr; + ph->num_threads++; + return newthr; } - +#ifndef __APPLE__ // struct used for client data from thread_db callback struct thread_db_client_data { - struct ps_prochandle* ph; - thread_info_callback callback; + struct ps_prochandle* ph; + thread_info_callback callback; }; // callback function for libthread_db @@ -314,6 +375,7 @@ bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) { return true; } +#endif // __APPLE__ // get number of threads int get_num_threads(struct ps_prochandle* ph) { @@ -322,18 +384,54 @@ int get_num_threads(struct ps_prochandle* ph) { // get lwp_id of n'th thread lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) { - int count = 0; - thread_info* thr = ph->threads; - while (thr) { - if (count == index) { - return thr->lwp_id; - } - count++; - thr = thr->next; - } - return -1; + int count = 0; + sa_thread_info* thr = ph->threads; + while (thr) { + if (count == index) { + return thr->lwp_id; + } + count++; + thr = thr->next; + } + return 0; } +#ifdef __APPLE__ +// set lwp_id of n'th thread +bool set_lwp_id(struct ps_prochandle* ph, int index, lwpid_t lwpid) { + int count = 0; + sa_thread_info* thr = ph->threads; + while (thr) { + if (count == index) { + thr->lwp_id = lwpid; + return true; + } + count++; + thr = thr->next; + } + return false; +} + +// get regs of n-th thread, only used in fillThreads the first time called +bool get_nth_lwp_regs(struct ps_prochandle* ph, int index, struct reg* regs) { + int count = 0; + sa_thread_info* thr = ph->threads; + while (thr) { + if (count == index) { + break; + } + count++; + thr = thr->next; + } + if (thr != NULL) { + memcpy(regs, &thr->regs, sizeof(struct reg)); + return true; + } + return false; +} + +#endif // __APPLE__ + // get regs for a given lwp bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) { return ph->ops->get_lwp_regs(ph, lwp_id, regs); @@ -341,35 +439,35 @@ bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) { // get number of shared objects int get_num_libs(struct ps_prochandle* ph) { - return ph->num_libs; + return ph->num_libs; } // get name of n'th solib const char* get_lib_name(struct ps_prochandle* ph, int index) { - int count = 0; - lib_info* lib = ph->libs; - while (lib) { - if (count == index) { - return lib->name; - } - count++; - lib = lib->next; - } - return NULL; + int count = 0; + lib_info* lib = ph->libs; + while (lib) { + if (count == index) { + return lib->name; + } + count++; + lib = lib->next; + } + return NULL; } // get base address of a lib uintptr_t get_lib_base(struct ps_prochandle* ph, int index) { - int count = 0; - lib_info* lib = ph->libs; - while (lib) { - if (count == index) { - return lib->base; - } - count++; - lib = lib->next; - } - return (uintptr_t)NULL; + int count = 0; + lib_info* lib = ph->libs; + while (lib) { + if (count == index) { + return lib->base; + } + count++; + lib = lib->next; + } + return (uintptr_t)NULL; } bool find_lib(struct ps_prochandle* ph, const char *lib_name) { @@ -425,6 +523,7 @@ ps_plog (const char *format, ...) va_end(alist); } +#ifndef __APPLE__ // ------------------------------------------------------------------------ // Functions below this point are not yet implemented. They are here only // to make the linker happy. @@ -458,3 +557,4 @@ ps_err_e ps_pcontinue(struct ps_prochandle *ph) { print_debug("ps_pcontinue not implemented\n"); return PS_OK; } +#endif // __APPLE__ diff --git a/hotspot/agent/src/os/bsd/libproc_impl.h b/hotspot/agent/src/os/bsd/libproc_impl.h index 12326c17fd4..b5cec4d39cf 100644 --- a/hotspot/agent/src/os/bsd/libproc_impl.h +++ b/hotspot/agent/src/os/bsd/libproc_impl.h @@ -30,6 +30,60 @@ #include "libproc.h" #include "symtab.h" +#ifdef __APPLE__ +#include // for PRIx64, 32, ... +#include +#include +#include +#include + +#ifndef register_t +#define register_t uint64_t +#endif + +/*** registers copied from bsd/amd64 */ +typedef struct reg { + register_t r_r15; + register_t r_r14; + register_t r_r13; + register_t r_r12; + register_t r_r11; + register_t r_r10; + register_t r_r9; + register_t r_r8; + register_t r_rdi; + register_t r_rsi; + register_t r_rbp; + register_t r_rbx; + register_t r_rdx; + register_t r_rcx; + register_t r_rax; + uint32_t r_trapno; // not used + uint16_t r_fs; + uint16_t r_gs; + uint32_t r_err; // not used + uint16_t r_es; // not used + uint16_t r_ds; // not used + register_t r_rip; + register_t r_cs; + register_t r_rflags; + register_t r_rsp; + register_t r_ss; // not used +} reg; + +// convenient defs +typedef struct mach_header_64 mach_header_64; +typedef struct load_command load_command; +typedef struct segment_command_64 segment_command_64; +typedef struct thread_command thread_command; +typedef struct dylib_command dylib_command; +typedef struct symtab_command symtab_command; +typedef struct nlist_64 nlist_64; +#else +#include +#include "salibelf.h" +#endif // __APPLE__ + // data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h #define BUF_SIZE (PATH_MAX + NAME_MAX + 1) @@ -44,12 +98,12 @@ typedef struct lib_info { } lib_info; // list of threads -typedef struct thread_info { - lwpid_t lwp_id; - pthread_t pthread_id; // not used cores, always -1 +typedef struct sa_thread_info { + lwpid_t lwp_id; // same as pthread_t + pthread_t pthread_id; // struct reg regs; // not for process, core uses for caching regset - struct thread_info* next; -} thread_info; + struct sa_thread_info* next; +} sa_thread_info; // list of virtual memory maps typedef struct map_info { @@ -91,6 +145,7 @@ struct core_data { // part of the class sharing workaround map_info* class_share_maps;// class share maps in a linked list map_info** map_array; // sorted (by vaddr) array of map_info pointers + char exec_path[4096]; // file name java }; struct ps_prochandle { @@ -100,12 +155,11 @@ struct ps_prochandle { lib_info* libs; // head of lib list lib_info* lib_tail; // tail of lib list - to append at the end int num_threads; - thread_info* threads; // head of thread list + sa_thread_info* threads; // head of thread list struct core_data* core; // data only used for core dumps, NULL for process }; int pathmap_open(const char* name); - void print_debug(const char* format,...); void print_error(const char* format,...); bool is_debug(); @@ -122,10 +176,45 @@ lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base); -// adds a new thread to threads list, returns NULL on failure -thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id); - +sa_thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id); // a test for ELF signature without using libelf -bool is_elf_file(int fd); +#ifdef __APPLE__ +// a test for Mach-O signature +bool is_macho_file(int fd); +// skip fat head to get image start offset of cpu_type_t +// return false if any error happens, else value in offset. +bool get_arch_off(int fd, cpu_type_t cputype, off_t *offset); +#else +bool is_elf_file(int fd); +#endif // __APPLE__ + +lwpid_t get_lwp_id(struct ps_prochandle* ph, int index); +bool set_lwp_id(struct ps_prochandle* ph, int index, lwpid_t lwpid); +bool get_nth_lwp_regs(struct ps_prochandle* ph, int index, struct reg* regs); + +// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table +// of the load object object_name in the target process identified by ph. +// It returns the symbol's value as an address in the target process in +// *sym_addr. + +ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name, + const char *sym_name, psaddr_t *sym_addr); + +// read "size" bytes info "buf" from address "addr" +ps_err_e ps_pread(struct ps_prochandle *ph, psaddr_t addr, + void *buf, size_t size); + +// write "size" bytes of data to debuggee at address "addr" +ps_err_e ps_pwrite(struct ps_prochandle *ph, psaddr_t addr, + const void *buf, size_t size); + +// fill in ptrace_lwpinfo for lid +ps_err_e ps_linfo(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo); + +// needed for when libthread_db is compiled with TD_DEBUG defined +void ps_plog (const char *format, ...); + +// untility, tells the position in file +off_t ltell(int fd); #endif //_LIBPROC_IMPL_H_ diff --git a/hotspot/agent/src/os/bsd/ps_core.c b/hotspot/agent/src/os/bsd/ps_core.c index b00a03c5704..974e01a6ab4 100644 --- a/hotspot/agent/src/os/bsd/ps_core.c +++ b/hotspot/agent/src/os/bsd/ps_core.c @@ -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 @@ -28,10 +28,11 @@ #include #include #include -#include -#include #include "libproc_impl.h" -#include "salibelf.h" + +#ifdef __APPLE__ +#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" +#endif // This file has the libproc implementation to read core files. // For live processes, refer to ps_proc.c. Portions of this is adapted @@ -41,156 +42,158 @@ // ps_prochandle cleanup helper functions // close all file descriptors -static void close_elf_files(struct ps_prochandle* ph) { - lib_info* lib = NULL; +static void close_files(struct ps_prochandle* ph) { + lib_info* lib = NULL; + // close core file descriptor + if (ph->core->core_fd >= 0) + close(ph->core->core_fd); - // close core file descriptor - if (ph->core->core_fd >= 0) - close(ph->core->core_fd); + // close exec file descriptor + if (ph->core->exec_fd >= 0) + close(ph->core->exec_fd); - // close exec file descriptor - if (ph->core->exec_fd >= 0) - close(ph->core->exec_fd); + // close interp file descriptor + if (ph->core->interp_fd >= 0) + close(ph->core->interp_fd); - // close interp file descriptor - if (ph->core->interp_fd >= 0) - close(ph->core->interp_fd); + // close class share archive file + if (ph->core->classes_jsa_fd >= 0) + close(ph->core->classes_jsa_fd); - // close class share archive file - if (ph->core->classes_jsa_fd >= 0) - close(ph->core->classes_jsa_fd); - - // close all library file descriptors - lib = ph->libs; - while (lib) { - int fd = lib->fd; - if (fd >= 0 && fd != ph->core->exec_fd) close(fd); - lib = lib->next; - } + // close all library file descriptors + lib = ph->libs; + while (lib) { + int fd = lib->fd; + if (fd >= 0 && fd != ph->core->exec_fd) { + close(fd); + } + lib = lib->next; + } } // clean all map_info stuff static void destroy_map_info(struct ps_prochandle* ph) { map_info* map = ph->core->maps; while (map) { - map_info* next = map->next; - free(map); - map = next; + map_info* next = map->next; + free(map); + map = next; } if (ph->core->map_array) { - free(ph->core->map_array); + free(ph->core->map_array); } // Part of the class sharing workaround map = ph->core->class_share_maps; while (map) { - map_info* next = map->next; - free(map); - map = next; + map_info* next = map->next; + free(map); + map = next; } } // ps_prochandle operations static void core_release(struct ps_prochandle* ph) { - if (ph->core) { - close_elf_files(ph); - destroy_map_info(ph); - free(ph->core); - } + if (ph->core) { + close_files(ph); + destroy_map_info(ph); + free(ph->core); + } } static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) { - map_info* map; - if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) { - print_debug("can't allocate memory for map_info\n"); - return NULL; - } + map_info* map; + if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) { + print_debug("can't allocate memory for map_info\n"); + return NULL; + } - // initialize map - map->fd = fd; - map->offset = offset; - map->vaddr = vaddr; - map->memsz = memsz; - return map; + // initialize map + map->fd = fd; + map->offset = offset; + map->vaddr = vaddr; + map->memsz = memsz; + return map; } // add map info with given fd, offset, vaddr and memsz static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset, uintptr_t vaddr, size_t memsz) { - map_info* map; - if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) { - return NULL; - } + map_info* map; + if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) { + return NULL; + } - // add this to map list - map->next = ph->core->maps; - ph->core->maps = map; - ph->core->num_maps++; + // add this to map list + map->next = ph->core->maps; + ph->core->maps = map; + ph->core->num_maps++; - return map; + return map; } // Part of the class sharing workaround static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset, uintptr_t vaddr, size_t memsz) { - map_info* map; - if ((map = allocate_init_map(ph->core->classes_jsa_fd, - offset, vaddr, memsz)) == NULL) { - return NULL; - } + map_info* map; + if ((map = allocate_init_map(ph->core->classes_jsa_fd, + offset, vaddr, memsz)) == NULL) { + return NULL; + } - map->next = ph->core->class_share_maps; - ph->core->class_share_maps = map; - return map; + map->next = ph->core->class_share_maps; + ph->core->class_share_maps = map; + return map; } // Return the map_info for the given virtual address. We keep a sorted // array of pointers in ph->map_array, so we can binary search. static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) { - int mid, lo = 0, hi = ph->core->num_maps - 1; - map_info *mp; + int mid, lo = 0, hi = ph->core->num_maps - 1; + map_info *mp; - while (hi - lo > 1) { - mid = (lo + hi) / 2; - if (addr >= ph->core->map_array[mid]->vaddr) - lo = mid; - else - hi = mid; - } + while (hi - lo > 1) { + mid = (lo + hi) / 2; + if (addr >= ph->core->map_array[mid]->vaddr) { + lo = mid; + } else { + hi = mid; + } + } - if (addr < ph->core->map_array[hi]->vaddr) - mp = ph->core->map_array[lo]; - else - mp = ph->core->map_array[hi]; + if (addr < ph->core->map_array[hi]->vaddr) { + mp = ph->core->map_array[lo]; + } else { + mp = ph->core->map_array[hi]; + } - if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) + if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) { + return (mp); + } + + + // Part of the class sharing workaround + // Unfortunately, we have no way of detecting -Xshare state. + // Check out the share maps atlast, if we don't find anywhere. + // This is done this way so to avoid reading share pages + // ahead of other normal maps. For eg. with -Xshare:off we don't + // want to prefer class sharing data to data from core. + mp = ph->core->class_share_maps; + if (mp) { + print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr); + } + while (mp) { + if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) { + print_debug("located map_info at 0x%lx from class share maps\n", addr); return (mp); + } + mp = mp->next; + } - - // Part of the class sharing workaround - // Unfortunately, we have no way of detecting -Xshare state. - // Check out the share maps atlast, if we don't find anywhere. - // This is done this way so to avoid reading share pages - // ahead of other normal maps. For eg. with -Xshare:off we don't - // want to prefer class sharing data to data from core. - mp = ph->core->class_share_maps; - if (mp) { - print_debug("can't locate map_info at 0x%lx, trying class share maps\n", - addr); - } - while (mp) { - if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) { - print_debug("located map_info at 0x%lx from class share maps\n", - addr); - return (mp); - } - mp = mp->next; - } - - print_debug("can't locate map_info at 0x%lx\n", addr); - return (NULL); + print_debug("can't locate map_info at 0x%lx\n", addr); + return (NULL); } //--------------------------------------------------------------- @@ -239,156 +242,170 @@ struct FileMapHeader { }; static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) { - jboolean i; - if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) { - *pvalue = i; - return true; - } else { - return false; - } + jboolean i; + if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) { + *pvalue = i; + return true; + } else { + return false; + } } static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) { - uintptr_t uip; - if (ps_pread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) { - *pvalue = uip; - return true; - } else { - return false; - } + uintptr_t uip; + if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) { + *pvalue = uip; + return true; + } else { + return false; + } } // used to read strings from debuggee static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) { - size_t i = 0; - char c = ' '; + size_t i = 0; + char c = ' '; - while (c != '\0') { - if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) - return false; - if (i < size - 1) - buf[i] = c; - else // smaller buffer - return false; - i++; addr++; - } - - buf[i] = '\0'; - return true; + while (c != '\0') { + if (ps_pread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) { + return false; + } + if (i < size - 1) { + buf[i] = c; + } else { + // smaller buffer + return false; + } + i++; addr++; + } + buf[i] = '\0'; + return true; } -#define USE_SHARED_SPACES_SYM "UseSharedSpaces" +#ifdef __APPLE__ +#define USE_SHARED_SPACES_SYM "_UseSharedSpaces" // mangled name of Arguments::SharedArchivePath #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE" +#else +#define USE_SHARED_SPACES_SYM "UseSharedSpaces" +// mangled name of Arguments::SharedArchivePath +#define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE" +#endif // __APPLE_ static bool init_classsharing_workaround(struct ps_prochandle* ph) { - lib_info* lib = ph->libs; - while (lib != NULL) { - // we are iterating over shared objects from the core dump. look for - // libjvm[_g].so. - const char *jvm_name = 0; - if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 || - (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) { - char classes_jsa[PATH_MAX]; - struct FileMapHeader header; - size_t n = 0; - int fd = -1, m = 0; - uintptr_t base = 0, useSharedSpacesAddr = 0; - uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0; - jboolean useSharedSpaces = 0; + int m; + size_t n; + lib_info* lib = ph->libs; + while (lib != NULL) { + // we are iterating over shared objects from the core dump. look for + // libjvm[_g].so. + const char *jvm_name = 0; +#ifdef __APPLE__ + if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0 || + (jvm_name = strstr(lib->name, "/libjvm_g.dylib")) != 0) +#else + if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 || + (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) +#endif // __APPLE__ + { + char classes_jsa[PATH_MAX]; + struct FileMapHeader header; + int fd = -1; + uintptr_t base = 0, useSharedSpacesAddr = 0; + uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0; + jboolean useSharedSpaces = 0; - memset(classes_jsa, 0, sizeof(classes_jsa)); - jvm_name = lib->name; - useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM); - if (useSharedSpacesAddr == 0) { - print_debug("can't lookup 'UseSharedSpaces' flag\n"); - return false; - } - - // Hotspot vm types are not exported to build this library. So - // using equivalent type jboolean to read the value of - // UseSharedSpaces which is same as hotspot type "bool". - if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) { - print_debug("can't read the value of 'UseSharedSpaces' flag\n"); - return false; - } - - if ((int)useSharedSpaces == 0) { - print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n"); - return true; - } - - sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM); - if (sharedArchivePathAddrAddr == 0) { - print_debug("can't lookup shared archive path symbol\n"); - return false; - } - - if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) { - print_debug("can't read shared archive path pointer\n"); - return false; - } - - if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) { - print_debug("can't read shared archive path value\n"); - return false; - } - - print_debug("looking for %s\n", classes_jsa); - // open the class sharing archive file - fd = pathmap_open(classes_jsa); - if (fd < 0) { - print_debug("can't open %s!\n", classes_jsa); - ph->core->classes_jsa_fd = -1; - return false; - } else { - print_debug("opened %s\n", classes_jsa); - } - - // read FileMapHeader from the file - memset(&header, 0, sizeof(struct FileMapHeader)); - if ((n = read(fd, &header, sizeof(struct FileMapHeader))) - != sizeof(struct FileMapHeader)) { - print_debug("can't read shared archive file map header from %s\n", classes_jsa); - close(fd); - return false; - } - - // check file magic - if (header._magic != 0xf00baba2) { - print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n", - classes_jsa, header._magic); - close(fd); - return false; - } - - // check version - if (header._version != CURRENT_ARCHIVE_VERSION) { - print_debug("%s has wrong shared archive file version %d, expecting %d\n", - classes_jsa, header._version, CURRENT_ARCHIVE_VERSION); - close(fd); - return false; - } - - ph->core->classes_jsa_fd = fd; - // add read-only maps from classes[_g].jsa to the list of maps - for (m = 0; m < NUM_SHARED_MAPS; m++) { - if (header._space[m]._read_only) { - base = (uintptr_t) header._space[m]._base; - // no need to worry about the fractional pages at-the-end. - // possible fractional pages are handled by core_read_data. - add_class_share_map_info(ph, (off_t) header._space[m]._file_offset, - base, (size_t) header._space[m]._used); - print_debug("added a share archive map at 0x%lx\n", base); - } - } - return true; + memset(classes_jsa, 0, sizeof(classes_jsa)); + jvm_name = lib->name; + useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM); + if (useSharedSpacesAddr == 0) { + print_debug("can't lookup 'UseSharedSpaces' flag\n"); + return false; } - lib = lib->next; - } - return true; -} + // Hotspot vm types are not exported to build this library. So + // using equivalent type jboolean to read the value of + // UseSharedSpaces which is same as hotspot type "bool". + if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) { + print_debug("can't read the value of 'UseSharedSpaces' flag\n"); + return false; + } + + if ((int)useSharedSpaces == 0) { + print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n"); + return true; + } + + sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM); + if (sharedArchivePathAddrAddr == 0) { + print_debug("can't lookup shared archive path symbol\n"); + return false; + } + + if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) { + print_debug("can't read shared archive path pointer\n"); + return false; + } + + if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) { + print_debug("can't read shared archive path value\n"); + return false; + } + + print_debug("looking for %s\n", classes_jsa); + // open the class sharing archive file + fd = pathmap_open(classes_jsa); + if (fd < 0) { + print_debug("can't open %s!\n", classes_jsa); + ph->core->classes_jsa_fd = -1; + return false; + } else { + print_debug("opened %s\n", classes_jsa); + } + + // read FileMapHeader from the file + memset(&header, 0, sizeof(struct FileMapHeader)); + if ((n = read(fd, &header, sizeof(struct FileMapHeader))) + != sizeof(struct FileMapHeader)) { + print_debug("can't read shared archive file map header from %s\n", classes_jsa); + close(fd); + return false; + } + + // check file magic + if (header._magic != 0xf00baba2) { + print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n", + classes_jsa, header._magic); + close(fd); + return false; + } + + // check version + if (header._version != CURRENT_ARCHIVE_VERSION) { + print_debug("%s has wrong shared archive file version %d, expecting %d\n", + classes_jsa, header._version, CURRENT_ARCHIVE_VERSION); + close(fd); + return false; + } + + ph->core->classes_jsa_fd = fd; + // add read-only maps from classes[_g].jsa to the list of maps + for (m = 0; m < NUM_SHARED_MAPS; m++) { + if (header._space[m]._read_only) { + base = (uintptr_t) header._space[m]._base; + // no need to worry about the fractional pages at-the-end. + // possible fractional pages are handled by core_read_data. + add_class_share_map_info(ph, (off_t) header._space[m]._file_offset, + base, (size_t) header._space[m]._used); + print_debug("added a share archive map at 0x%lx\n", base); + } + } + return true; + } + lib = lib->next; + } + return true; +} //--------------------------------------------------------------------------- // functions to handle map_info @@ -397,54 +414,57 @@ static bool init_classsharing_workaround(struct ps_prochandle* ph) { // callback for sorting the array of map_info pointers. static int core_cmp_mapping(const void *lhsp, const void *rhsp) { - const map_info *lhs = *((const map_info **)lhsp); - const map_info *rhs = *((const map_info **)rhsp); + const map_info *lhs = *((const map_info **)lhsp); + const map_info *rhs = *((const map_info **)rhsp); - if (lhs->vaddr == rhs->vaddr) - return (0); + if (lhs->vaddr == rhs->vaddr) { + return (0); + } - return (lhs->vaddr < rhs->vaddr ? -1 : 1); + return (lhs->vaddr < rhs->vaddr ? -1 : 1); } // we sort map_info by starting virtual address so that we can do // binary search to read from an address. static bool sort_map_array(struct ps_prochandle* ph) { - size_t num_maps = ph->core->num_maps; - map_info* map = ph->core->maps; - int i = 0; + size_t num_maps = ph->core->num_maps; + map_info* map = ph->core->maps; + int i = 0; - // allocate map_array - map_info** array; - if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) { - print_debug("can't allocate memory for map array\n"); - return false; - } + // allocate map_array + map_info** array; + if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) { + print_debug("can't allocate memory for map array\n"); + return false; + } - // add maps to array - while (map) { - array[i] = map; - i++; - map = map->next; - } + // add maps to array + while (map) { + array[i] = map; + i++; + map = map->next; + } - // sort is called twice. If this is second time, clear map array - if (ph->core->map_array) free(ph->core->map_array); - ph->core->map_array = array; - // sort the map_info array by base virtual address. - qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*), - core_cmp_mapping); + // sort is called twice. If this is second time, clear map array + if (ph->core->map_array) { + free(ph->core->map_array); + } + ph->core->map_array = array; + // sort the map_info array by base virtual address. + qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*), + core_cmp_mapping); - // print map - if (is_debug()) { - int j = 0; - print_debug("---- sorted virtual address map ----\n"); - for (j = 0; j < ph->core->num_maps; j++) { - print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr, - ph->core->map_array[j]->memsz); - } - } + // print map + if (is_debug()) { + int j = 0; + print_debug("---- sorted virtual address map ----\n"); + for (j = 0; j < ph->core->num_maps; j++) { + print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr, + ph->core->map_array[j]->memsz); + } + } - return true; + return true; } #ifndef MIN @@ -461,16 +481,18 @@ static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, off_t off; int fd; - if (mp == NULL) + if (mp == NULL) { break; /* No mapping for this address */ + } fd = mp->fd; mapoff = addr - mp->vaddr; len = MIN(resid, mp->memsz - mapoff); off = mp->offset + mapoff; - if ((len = pread(fd, buf, len, off)) <= 0) + if ((len = pread(fd, buf, len, off)) <= 0) { break; + } resid -= len; addr += len; @@ -507,8 +529,8 @@ static bool core_write_data(struct ps_prochandle* ph, static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct reg* regs) { - // for core we have cached the lwp regs from NOTE section - thread_info* thr = ph->threads; + // for core we have cached the lwp regs after segment parsed + sa_thread_info* thr = ph->threads; while (thr) { if (thr->lwp_id == lwp_id) { memcpy(regs, &thr->regs, sizeof(struct reg)); @@ -519,7 +541,7 @@ static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, return false; } -static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) { +static bool core_get_lwp_info(struct ps_prochandle *ph, lwpid_t id, void *info) { print_debug("core_get_lwp_info not implemented\n"); return false; } @@ -532,12 +554,451 @@ static ps_prochandle_ops core_ops = { .get_lwp_info= core_get_lwp_info }; -// read regs and create thread from NT_PRSTATUS entries from core file +// from this point, mainly two blocks divided by def __APPLE__ +// one for Macosx, the other for regular Bsd + +#ifdef __APPLE__ + +void print_thread(sa_thread_info *threadinfo) { + print_debug("thread added: %d\n", threadinfo->lwp_id); + print_debug("registers:\n"); + print_debug(" r_r15: 0x%" PRIx64 "\n", threadinfo->regs.r_r15); + print_debug(" r_r14: 0x%" PRIx64 "\n", threadinfo->regs.r_r14); + print_debug(" r_r13: 0x%" PRIx64 "\n", threadinfo->regs.r_r13); + print_debug(" r_r12: 0x%" PRIx64 "\n", threadinfo->regs.r_r12); + print_debug(" r_r11: 0x%" PRIx64 "\n", threadinfo->regs.r_r11); + print_debug(" r_r10: 0x%" PRIx64 "\n", threadinfo->regs.r_r10); + print_debug(" r_r9: 0x%" PRIx64 "\n", threadinfo->regs.r_r9); + print_debug(" r_r8: 0x%" PRIx64 "\n", threadinfo->regs.r_r8); + print_debug(" r_rdi: 0x%" PRIx64 "\n", threadinfo->regs.r_rdi); + print_debug(" r_rsi: 0x%" PRIx64 "\n", threadinfo->regs.r_rsi); + print_debug(" r_rbp: 0x%" PRIx64 "\n", threadinfo->regs.r_rbp); + print_debug(" r_rbx: 0x%" PRIx64 "\n", threadinfo->regs.r_rbx); + print_debug(" r_rdx: 0x%" PRIx64 "\n", threadinfo->regs.r_rdx); + print_debug(" r_rcx: 0x%" PRIx64 "\n", threadinfo->regs.r_rcx); + print_debug(" r_rax: 0x%" PRIx64 "\n", threadinfo->regs.r_rax); + print_debug(" r_fs: 0x%" PRIx32 "\n", threadinfo->regs.r_fs); + print_debug(" r_gs: 0x%" PRIx32 "\n", threadinfo->regs.r_gs); + print_debug(" r_rip 0x%" PRIx64 "\n", threadinfo->regs.r_rip); + print_debug(" r_cs: 0x%" PRIx64 "\n", threadinfo->regs.r_cs); + print_debug(" r_rsp: 0x%" PRIx64 "\n", threadinfo->regs.r_rsp); + print_debug(" r_rflags: 0x%" PRIx64 "\n", threadinfo->regs.r_rflags); +} + +// read all segments64 commands from core file +// read all thread commands from core file +static bool read_core_segments(struct ps_prochandle* ph) { + int i = 0; + int num_threads = 0; + int fd = ph->core->core_fd; + off_t offset = 0; + mach_header_64 fhead; + load_command lcmd; + segment_command_64 segcmd; + // thread_command thrcmd; + + lseek(fd, offset, SEEK_SET); + if(read(fd, (void *)&fhead, sizeof(mach_header_64)) != sizeof(mach_header_64)) { + goto err; + } + print_debug("total commands: %d\n", fhead.ncmds); + offset += sizeof(mach_header_64); + for (i = 0; i < fhead.ncmds; i++) { + lseek(fd, offset, SEEK_SET); + if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) { + goto err; + } + offset += lcmd.cmdsize; // next command position + if (lcmd.cmd == LC_SEGMENT_64) { + lseek(fd, -sizeof(load_command), SEEK_CUR); + if (read(fd, (void *)&segcmd, sizeof(segment_command_64)) != sizeof(segment_command_64)) { + print_debug("failed to read LC_SEGMENT_64 i = %d!\n", i); + goto err; + } + if (add_map_info(ph, fd, segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize) == NULL) { + print_debug("Failed to add map_info at i = %d\n", i); + goto err; + } + print_debug("segment added: %" PRIu64 " 0x%" PRIx64 " %d\n", + segcmd.fileoff, segcmd.vmaddr, segcmd.vmsize); + } else if (lcmd.cmd == LC_THREAD || lcmd.cmd == LC_UNIXTHREAD) { + typedef struct thread_fc { + uint32_t flavor; + uint32_t count; + } thread_fc; + thread_fc fc; + uint32_t size = sizeof(load_command); + while (size < lcmd.cmdsize) { + if (read(fd, (void *)&fc, sizeof(thread_fc)) != sizeof(thread_fc)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(thread_fc); + if (fc.flavor == x86_THREAD_STATE) { + x86_thread_state_t thrstate; + if (read(fd, (void *)&thrstate, sizeof(x86_thread_state_t)) != sizeof(x86_thread_state_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(x86_thread_state_t); + // create thread info list, update lwp_id later + sa_thread_info* newthr = add_thread_info(ph, (pthread_t) -1, (lwpid_t) num_threads++); + if (newthr == NULL) { + printf("create thread_info failed\n"); + goto err; + } + + // note __DARWIN_UNIX03 depengs on other definitions +#if __DARWIN_UNIX03 +#define get_register_v(regst, regname) \ + regst.uts.ts64.__##regname +#else +#define get_register_v(regst, regname) \ + regst.uts.ts64.##regname +#endif // __DARWIN_UNIX03 + newthr->regs.r_rax = get_register_v(thrstate, rax); + newthr->regs.r_rbx = get_register_v(thrstate, rbx); + newthr->regs.r_rcx = get_register_v(thrstate, rcx); + newthr->regs.r_rdx = get_register_v(thrstate, rdx); + newthr->regs.r_rdi = get_register_v(thrstate, rdi); + newthr->regs.r_rsi = get_register_v(thrstate, rsi); + newthr->regs.r_rbp = get_register_v(thrstate, rbp); + newthr->regs.r_rsp = get_register_v(thrstate, rsp); + newthr->regs.r_r8 = get_register_v(thrstate, r8); + newthr->regs.r_r9 = get_register_v(thrstate, r9); + newthr->regs.r_r10 = get_register_v(thrstate, r10); + newthr->regs.r_r11 = get_register_v(thrstate, r11); + newthr->regs.r_r12 = get_register_v(thrstate, r12); + newthr->regs.r_r13 = get_register_v(thrstate, r13); + newthr->regs.r_r14 = get_register_v(thrstate, r14); + newthr->regs.r_r15 = get_register_v(thrstate, r15); + newthr->regs.r_rip = get_register_v(thrstate, rip); + newthr->regs.r_rflags = get_register_v(thrstate, rflags); + newthr->regs.r_cs = get_register_v(thrstate, cs); + newthr->regs.r_fs = get_register_v(thrstate, fs); + newthr->regs.r_gs = get_register_v(thrstate, gs); + print_thread(newthr); + } else if (fc.flavor == x86_FLOAT_STATE) { + x86_float_state_t flstate; + if (read(fd, (void *)&flstate, sizeof(x86_float_state_t)) != sizeof(x86_float_state_t)) { + print_debug("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(x86_float_state_t); + } else if (fc.flavor == x86_EXCEPTION_STATE) { + x86_exception_state_t excpstate; + if (read(fd, (void *)&excpstate, sizeof(x86_exception_state_t)) != sizeof(x86_exception_state_t)) { + printf("Reading flavor, count failed.\n"); + goto err; + } + size += sizeof(x86_exception_state_t); + } + } + } + } + return true; +err: + return false; +} + +/**local function **/ +bool exists(const char *fname) +{ + int fd; + if ((fd = open(fname, O_RDONLY)) > 0) { + close(fd); + return true; + } + return false; +} + +// we check: 1. lib +// 2. lib/server +// 3. jre/lib +// 4. jre/lib/server +// from: 1. exe path +// 2. JAVA_HOME +// 3. DYLD_LIBRARY_PATH +static bool get_real_path(struct ps_prochandle* ph, char *rpath) { + /** check if they exist in JAVA ***/ + char* execname = ph->core->exec_path; + char filepath[4096]; + char* filename = strrchr(rpath, '/'); // like /libjvm.dylib + if (filename == NULL) { + return false; + } + + char* posbin = strstr(execname, "/bin/java"); + if (posbin != NULL) { + memcpy(filepath, execname, posbin - execname); // not include trailing '/' + filepath[posbin - execname] = '\0'; + } else { + char* java_home = getenv("JAVA_HOME"); + if (java_home != NULL) { + strcpy(filepath, java_home); + } else { + char* dyldpath = getenv("DYLD_LIBRARY_PATH"); + char* dypath = strtok(dyldpath, ":"); + while (dypath != NULL) { + strcpy(filepath, dypath); + strcat(filepath, filename); + if (exists(filepath)) { + strcpy(rpath, filepath); + return true; + } + dypath = strtok(dyldpath, ":"); + } + // not found + return false; + } + } + // for exec and java_home, jdkpath now is filepath + size_t filepath_base_size = strlen(filepath); + + // first try /lib/ and /lib/server + strcat(filepath, "/lib"); + strcat(filepath, filename); + if (exists(filepath)) { + strcpy(rpath, filepath); + return true; + } + char* pos = strstr(filepath, filename); // like /libjvm.dylib + *pos = '\0'; + strcat(filepath, "/server"); + strcat(filepath, filename); + if (exists(filepath)) { + strcpy(rpath, filepath); + return true; + } + + // then try /jre/lib/ and /jre/lib/server + filepath[filepath_base_size] = '\0'; + strcat(filepath, "/jre/lib"); + strcat(filepath, filename); + if (exists(filepath)) { + strcpy(rpath, filepath); + return true; + } + pos = strstr(filepath, filename); + *pos = '\0'; + strcat(filepath, "/server"); + strcat(filepath, filename); + if (exists(filepath)) { + strcpy(rpath, filepath); + return true; + } + + return false; +} + +static bool read_shared_lib_info(struct ps_prochandle* ph) { + static int pagesize = 0; + int fd = ph->core->core_fd; + int i = 0, j; + uint32_t v; + mach_header_64 header; // used to check if a file header in segment + load_command lcmd; + dylib_command dylibcmd; + + char name[BUF_SIZE]; // use to store name + + if (pagesize == 0) { + pagesize = getpagesize(); + print_debug("page size is %d\n", pagesize); + } + for (j = 0; j < ph->core->num_maps; j++) { + map_info *iter = ph->core->map_array[j]; // head + off_t fpos = iter->offset; + if (iter->fd != fd) { + // only search core file! + continue; + } + print_debug("map_info %d: vmaddr = 0x%016" PRIx64 " fileoff = %" PRIu64 " vmsize = %" PRIu64 "\n", + j, iter->vaddr, iter->offset, iter->memsz); + lseek(fd, fpos, SEEK_SET); + // we assume .dylib loaded at segment address --- which is true for JVM libraries + // multiple files may be loaded in one segment. + // if first word is not a magic word, means this segment does not contain lib file. + if (read(fd, (void *)&v, sizeof(uint32_t)) == sizeof(uint32_t)) { + if (v != MH_MAGIC_64) { + continue; + } + } else { + // may be encountered last map, which is not readable + continue; + } + while (ltell(fd) - iter->offset < iter->memsz) { + lseek(fd, fpos, SEEK_SET); + if (read(fd, (void *)&v, sizeof(uint32_t)) != sizeof(uint32_t)) { + break; + } + if (v != MH_MAGIC_64) { + fpos = (ltell(fd) + pagesize -1)/pagesize * pagesize; + continue; + } + lseek(fd, -sizeof(uint32_t), SEEK_CUR); + // this is the file begining to core file. + if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) { + goto err; + } + fpos = ltell(fd); + + // found a mach-o file in this segment + for (i = 0; i < header.ncmds; i++) { + // read commands in this "file" + // LC_ID_DYLIB is the file itself for a .dylib + lseek(fd, fpos, SEEK_SET); + if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) { + return false; // error + } + fpos += lcmd.cmdsize; // next command position + // make sure still within seg size. + if (fpos - lcmd.cmdsize - iter->offset > iter->memsz) { + print_debug("Warning: out of segement limit: %ld \n", fpos - lcmd.cmdsize - iter->offset); + break; // no need to iterate all commands + } + if (lcmd.cmd == LC_ID_DYLIB) { + lseek(fd, -sizeof(load_command), SEEK_CUR); + if (read(fd, (void *)&dylibcmd, sizeof(dylib_command)) != sizeof(dylib_command)) { + return false; + } + /**** name stored at dylib_command.dylib.name.offset, is a C string */ + lseek(fd, dylibcmd.dylib.name.offset - sizeof(dylib_command), SEEK_CUR); + int j = 0; + while (j < BUF_SIZE) { + read(fd, (void *)(name + j), sizeof(char)); + if (name[j] == '\0') break; + j++; + } + print_debug("%s\n", name); + // changed name from @rpath/xxxx.dylib to real path + if (strrchr(name, '@')) { + get_real_path(ph, name); + print_debug("get_real_path returned: %s\n", name); + } + add_lib_info(ph, name, iter->vaddr); + break; + } + } + // done with the file, advanced to next page to search more files + fpos = (ltell(fd) + pagesize - 1) / pagesize * pagesize; + } + } + return true; +err: + return false; +} + +bool read_macho64_header(int fd, mach_header_64* core_header) { + bool is_macho = false; + if (fd < 0) return false; + off_t pos = ltell(fd); + lseek(fd, 0, SEEK_SET); + if (read(fd, (void *)core_header, sizeof(mach_header_64)) != sizeof(mach_header_64)) { + is_macho = false; + } else { + is_macho = (core_header->magic == MH_MAGIC_64 || core_header->magic == MH_CIGAM_64); + } + lseek(fd, pos, SEEK_SET); + return is_macho; +} + +// the one and only one exposed stuff from this file +struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) { + mach_header_64 core_header; + mach_header_64 exec_header; + + struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle)); + if (ph == NULL) { + print_debug("cant allocate ps_prochandle\n"); + return NULL; + } + + if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) { + free(ph); + print_debug("can't allocate ps_prochandle\n"); + return NULL; + } + + // initialize ph + ph->ops = &core_ops; + ph->core->core_fd = -1; + ph->core->exec_fd = -1; + ph->core->interp_fd = -1; + + print_debug("exec: %s core: %s", exec_file, core_file); + + strncpy(ph->core->exec_path, exec_file, sizeof(ph->core->exec_path)); + + // open the core file + if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) { + print_error("can't open core file\n"); + goto err; + } + + // read core file header + if (read_macho64_header(ph->core->core_fd, &core_header) != true || core_header.filetype != MH_CORE) { + print_debug("core file is not a valid Mach-O file\n"); + goto err; + } + + if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) { + print_error("can't open executable file\n"); + goto err; + } + + if (read_macho64_header(ph->core->exec_fd, &exec_header) != true || + exec_header.filetype != MH_EXECUTE) { + print_error("executable file is not a valid Mach-O file\n"); + goto err; + } + + // process core file segments + if (read_core_segments(ph) != true) { + print_error("failed to read core segments\n"); + goto err; + } + + // allocate and sort maps into map_array, we need to do this + // here because read_shared_lib_info needs to read from debuggee + // address space + if (sort_map_array(ph) != true) { + print_error("failed to sort segment map array\n"); + goto err; + } + + if (read_shared_lib_info(ph) != true) { + print_error("failed to read libraries\n"); + goto err; + } + + // sort again because we have added more mappings from shared objects + if (sort_map_array(ph) != true) { + print_error("failed to sort segment map array\n"); + goto err; + } + + if (init_classsharing_workaround(ph) != true) { + print_error("failed to workaround classshareing\n"); + goto err; + } + + print_debug("Leave Pgrab_core\n"); + return ph; + +err: + Prelease(ph); + return NULL; +} + +#else // __APPLE__ (none macosx) + +// read regs and create thread from core file static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) { // we have to read prstatus_t from buf // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t"); prstatus_t* prstat = (prstatus_t*) buf; - thread_info* newthr; + sa_thread_info* newthr; print_debug("got integer regset for lwp %d\n", prstat->pr_pid); // we set pthread_t to -1 for core dump if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL) @@ -632,8 +1093,9 @@ static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) { notep->n_type, notep->n_descsz); if (notep->n_type == NT_PRSTATUS) { - if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) + if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) { return false; + } } p = descdata + ROUNDUP(notep->n_descsz, 4); } @@ -681,7 +1143,9 @@ static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) { for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) { switch (core_php->p_type) { case PT_NOTE: - if (core_handle_note(ph, core_php) != true) goto err; + if (core_handle_note(ph, core_php) != true) { + goto err; + } break; case PT_LOAD: { @@ -800,7 +1264,6 @@ err: return false; } - #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug, r_map) #define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase) #define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr) @@ -810,213 +1273,218 @@ err: // read shared library info from runtime linker's data structures. // This work is done by librtlb_db in Solaris static bool read_shared_lib_info(struct ps_prochandle* ph) { - uintptr_t addr = ph->core->dynamic_addr; - uintptr_t debug_base; - uintptr_t first_link_map_addr; - uintptr_t ld_base_addr; - uintptr_t link_map_addr; - uintptr_t lib_base_diff; - uintptr_t lib_base; - uintptr_t lib_name_addr; - char lib_name[BUF_SIZE]; - ELF_DYN dyn; - ELF_EHDR elf_ehdr; - int lib_fd; + uintptr_t addr = ph->core->dynamic_addr; + uintptr_t debug_base; + uintptr_t first_link_map_addr; + uintptr_t ld_base_addr; + uintptr_t link_map_addr; + uintptr_t lib_base_diff; + uintptr_t lib_base; + uintptr_t lib_name_addr; + char lib_name[BUF_SIZE]; + ELF_DYN dyn; + ELF_EHDR elf_ehdr; + int lib_fd; - // _DYNAMIC has information of the form - // [tag] [data] [tag] [data] ..... - // Both tag and data are pointer sized. - // We look for dynamic info with DT_DEBUG. This has shared object info. - // refer to struct r_debug in link.h + // _DYNAMIC has information of the form + // [tag] [data] [tag] [data] ..... + // Both tag and data are pointer sized. + // We look for dynamic info with DT_DEBUG. This has shared object info. + // refer to struct r_debug in link.h - dyn.d_tag = DT_NULL; - while (dyn.d_tag != DT_DEBUG) { - if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) { - print_debug("can't read debug info from _DYNAMIC\n"); - return false; - } - addr += sizeof(ELF_DYN); - } - - // we have got Dyn entry with DT_DEBUG - debug_base = dyn.d_un.d_ptr; - // at debug_base we have struct r_debug. This has first link map in r_map field - if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET, - &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) { - print_debug("can't read first link map address\n"); + dyn.d_tag = DT_NULL; + while (dyn.d_tag != DT_DEBUG) { + if (ps_pread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) { + print_debug("can't read debug info from _DYNAMIC\n"); return false; - } + } + addr += sizeof(ELF_DYN); + } - // read ld_base address from struct r_debug - // XXX: There is no r_ldbase member on BSD -/* - if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr, - sizeof(uintptr_t)) != PS_OK) { - print_debug("can't read ld base address\n"); + // we have got Dyn entry with DT_DEBUG + debug_base = dyn.d_un.d_ptr; + // at debug_base we have struct r_debug. This has first link map in r_map field + if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET, + &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read first link map address\n"); + return false; + } + + // read ld_base address from struct r_debug + // XXX: There is no r_ldbase member on BSD + /* + if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr, + sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read ld base address\n"); + return false; + } + ph->core->ld_base_addr = ld_base_addr; + */ + ph->core->ld_base_addr = 0; + + print_debug("interpreter base address is 0x%lx\n", ld_base_addr); + + // now read segments from interp (i.e ld-elf.so.1) + if (read_interp_segments(ph) != true) + return false; + + // after adding interpreter (ld.so) mappings sort again + if (sort_map_array(ph) != true) + return false; + + print_debug("first link map is at 0x%lx\n", first_link_map_addr); + + link_map_addr = first_link_map_addr; + while (link_map_addr != 0) { + // read library base address of the .so. Note that even though calls + // link_map->l_addr as "base address", this is * not * really base virtual + // address of the shared object. This is actually the difference b/w the virtual + // address mentioned in shared object and the actual virtual base where runtime + // linker loaded it. We use "base diff" in read_lib_segments call below. + + if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET, + &lib_base_diff, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read shared object base address diff\n"); return false; - } - ph->core->ld_base_addr = ld_base_addr; -*/ - ph->core->ld_base_addr = 0; + } - print_debug("interpreter base address is 0x%lx\n", ld_base_addr); - - // now read segments from interp (i.e ld-elf.so.1) - if (read_interp_segments(ph) != true) + // read address of the name + if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET, + &lib_name_addr, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read address of shared object name\n"); return false; + } - // after adding interpreter (ld.so) mappings sort again - if (sort_map_array(ph) != true) + // read name of the shared object + if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) { + print_debug("can't read shared object name\n"); return false; + } - print_debug("first link map is at 0x%lx\n", first_link_map_addr); + if (lib_name[0] != '\0') { + // ignore empty lib names + lib_fd = pathmap_open(lib_name); - link_map_addr = first_link_map_addr; - while (link_map_addr != 0) { - // read library base address of the .so. Note that even though calls - // link_map->l_addr as "base address", this is * not * really base virtual - // address of the shared object. This is actually the difference b/w the virtual - // address mentioned in shared object and the actual virtual base where runtime - // linker loaded it. We use "base diff" in read_lib_segments call below. - - if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET, - &lib_base_diff, sizeof(uintptr_t)) != PS_OK) { - print_debug("can't read shared object base address diff\n"); - return false; + if (lib_fd < 0) { + print_debug("can't open shared object %s\n", lib_name); + // continue with other libraries... + } else { + if (read_elf_header(lib_fd, &elf_ehdr)) { + lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr); + print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n", + lib_name, lib_base, lib_base_diff); + // while adding library mappings we need to use "base difference". + if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) { + print_debug("can't read shared object's segments\n"); + close(lib_fd); + return false; + } + add_lib_info_fd(ph, lib_name, lib_fd, lib_base); + // Map info is added for the library (lib_name) so + // we need to re-sort it before calling the p_pdread. + if (sort_map_array(ph) != true) + return false; + } else { + print_debug("can't read ELF header for shared object %s\n", lib_name); + close(lib_fd); + // continue with other libraries... + } } + } - // read address of the name - if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET, - &lib_name_addr, sizeof(uintptr_t)) != PS_OK) { - print_debug("can't read address of shared object name\n"); - return false; - } + // read next link_map address + if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET, + &link_map_addr, sizeof(uintptr_t)) != PS_OK) { + print_debug("can't read next link in link_map\n"); + return false; + } + } - // read name of the shared object - if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) { - print_debug("can't read shared object name\n"); - return false; - } - - if (lib_name[0] != '\0') { - // ignore empty lib names - lib_fd = pathmap_open(lib_name); - - if (lib_fd < 0) { - print_debug("can't open shared object %s\n", lib_name); - // continue with other libraries... - } else { - if (read_elf_header(lib_fd, &elf_ehdr)) { - lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr); - print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n", - lib_name, lib_base, lib_base_diff); - // while adding library mappings we need to use "base difference". - if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) { - print_debug("can't read shared object's segments\n"); - close(lib_fd); - return false; - } - add_lib_info_fd(ph, lib_name, lib_fd, lib_base); - // Map info is added for the library (lib_name) so - // we need to re-sort it before calling the p_pdread. - if (sort_map_array(ph) != true) - return false; - } else { - print_debug("can't read ELF header for shared object %s\n", lib_name); - close(lib_fd); - // continue with other libraries... - } - } - } - - // read next link_map address - if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET, - &link_map_addr, sizeof(uintptr_t)) != PS_OK) { - print_debug("can't read next link in link_map\n"); - return false; - } - } - - return true; + return true; } // the one and only one exposed stuff from this file struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) { - ELF_EHDR core_ehdr; - ELF_EHDR exec_ehdr; + ELF_EHDR core_ehdr; + ELF_EHDR exec_ehdr; - struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle)); - if (ph == NULL) { - print_debug("can't allocate ps_prochandle\n"); - return NULL; - } + struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle)); + if (ph == NULL) { + print_debug("cant allocate ps_prochandle\n"); + return NULL; + } - if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) { - free(ph); - print_debug("can't allocate ps_prochandle\n"); - return NULL; - } + if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) { + free(ph); + print_debug("can't allocate ps_prochandle\n"); + return NULL; + } - // initialize ph - ph->ops = &core_ops; - ph->core->core_fd = -1; - ph->core->exec_fd = -1; - ph->core->interp_fd = -1; + // initialize ph + ph->ops = &core_ops; + ph->core->core_fd = -1; + ph->core->exec_fd = -1; + ph->core->interp_fd = -1; - // open the core file - if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) { - print_debug("can't open core file\n"); - goto err; - } + print_debug("exec: %s core: %s", exec_file, core_file); - // read core file ELF header - if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) { - print_debug("core file is not a valid ELF ET_CORE file\n"); - goto err; - } + // open the core file + if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) { + print_debug("can't open core file\n"); + goto err; + } - if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) { - print_debug("can't open executable file\n"); - goto err; - } + // read core file ELF header + if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) { + print_debug("core file is not a valid ELF ET_CORE file\n"); + goto err; + } - if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) { - print_debug("executable file is not a valid ELF ET_EXEC file\n"); - goto err; - } + if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) { + print_debug("can't open executable file\n"); + goto err; + } - // process core file segments - if (read_core_segments(ph, &core_ehdr) != true) - goto err; + if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) { + print_debug("executable file is not a valid ELF ET_EXEC file\n"); + goto err; + } - // process exec file segments - if (read_exec_segments(ph, &exec_ehdr) != true) - goto err; + // process core file segments + if (read_core_segments(ph, &core_ehdr) != true) + goto err; - // exec file is also treated like a shared object for symbol search - if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd, - (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) - goto err; + // process exec file segments + if (read_exec_segments(ph, &exec_ehdr) != true) + goto err; - // allocate and sort maps into map_array, we need to do this - // here because read_shared_lib_info needs to read from debuggee - // address space - if (sort_map_array(ph) != true) - goto err; + // exec file is also treated like a shared object for symbol search + if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd, + (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) + goto err; - if (read_shared_lib_info(ph) != true) - goto err; + // allocate and sort maps into map_array, we need to do this + // here because read_shared_lib_info needs to read from debuggee + // address space + if (sort_map_array(ph) != true) + goto err; - // sort again because we have added more mappings from shared objects - if (sort_map_array(ph) != true) - goto err; + if (read_shared_lib_info(ph) != true) + goto err; - if (init_classsharing_workaround(ph) != true) - goto err; + // sort again because we have added more mappings from shared objects + if (sort_map_array(ph) != true) + goto err; - return ph; + if (init_classsharing_workaround(ph) != true) + goto err; + + print_debug("Leave Pgrab_core\n"); + return ph; err: - Prelease(ph); - return NULL; + Prelease(ph); + return NULL; } + +#endif // __APPLE__ diff --git a/hotspot/agent/src/os/bsd/symtab.c b/hotspot/agent/src/os/bsd/symtab.c index 9a9fbd23491..0299cb2b7a8 100644 --- a/hotspot/agent/src/os/bsd/symtab.c +++ b/hotspot/agent/src/os/bsd/symtab.c @@ -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 @@ -28,32 +28,182 @@ #include #include #include + +#include "libproc_impl.h" #include "symtab.h" +#ifndef __APPLE__ #include "salibelf.h" +#endif // __APPLE__ // ---------------------------------------------------- // functions for symbol lookups // ---------------------------------------------------- +typedef struct symtab_symbol { + char *name; // name like __ZThread_... + uintptr_t offset; // to loaded address + uintptr_t size; // size strlen +} symtab_symbol; + +typedef struct symtab { + char *strs; // all symbols "__symbol1__'\0'__symbol2__...." + size_t num_symbols; + DB* hash_table; + symtab_symbol* symbols; +} symtab_t; + +#ifdef __APPLE__ + +void build_search_table(symtab_t *symtab) { + int i; + for (i = 0; i < symtab->num_symbols; i++) { + DBT key, value; + key.data = symtab->symbols[i].name; + key.size = strlen(key.data) + 1; + value.data = &(symtab->symbols[i]); + value.size = sizeof(symtab_symbol); + (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0); + + // check result + if (is_debug()) { + DBT rkey, rvalue; + char* tmp = (char *)malloc(strlen(symtab->symbols[i].name) + 1); + strcpy(tmp, symtab->symbols[i].name); + rkey.data = tmp; + rkey.size = strlen(tmp) + 1; + (*symtab->hash_table->get)(symtab->hash_table, &rkey, &rvalue, 0); + // we may get a copy back so compare contents + symtab_symbol *res = (symtab_symbol *)rvalue.data; + if (strcmp(res->name, symtab->symbols[i].name) || + res->offset != symtab->symbols[i].offset || + res->size != symtab->symbols[i].size) { + print_debug("error to get hash_table value!\n"); + } + free(tmp); + } + } +} + +// read symbol table from given fd. +struct symtab* build_symtab(int fd) { + symtab_t* symtab = NULL; + int i; + mach_header_64 header; + off_t image_start; + + if (!get_arch_off(fd, CPU_TYPE_X86_64, &image_start)) { + print_debug("failed in get fat header\n"); + return NULL; + } + lseek(fd, image_start, SEEK_SET); + if (read(fd, (void *)&header, sizeof(mach_header_64)) != sizeof(mach_header_64)) { + print_debug("reading header failed!\n"); + return NULL; + } + // header + if (header.magic != MH_MAGIC_64) { + print_debug("not a valid .dylib file\n"); + return NULL; + } + + load_command lcmd; + symtab_command symtabcmd; + nlist_64 lentry; + + bool lcsymtab_exist = false; + + long filepos = ltell(fd); + for (i = 0; i < header.ncmds; i++) { + lseek(fd, filepos, SEEK_SET); + if (read(fd, (void *)&lcmd, sizeof(load_command)) != sizeof(load_command)) { + print_debug("read load_command failed for file\n"); + return NULL; + } + filepos += lcmd.cmdsize; // next command position + if (lcmd.cmd == LC_SYMTAB) { + lseek(fd, -sizeof(load_command), SEEK_CUR); + lcsymtab_exist = true; + break; + } + } + if (!lcsymtab_exist) { + print_debug("No symtab command found!\n"); + return NULL; + } + if (read(fd, (void *)&symtabcmd, sizeof(symtab_command)) != sizeof(symtab_command)) { + print_debug("read symtab_command failed for file"); + return NULL; + } + symtab = (symtab_t *)malloc(sizeof(symtab_t)); + if (symtab == NULL) { + print_debug("out of memory: allocating symtab\n"); + return NULL; + } + + // create hash table, we use berkeley db to + // manipulate the hash table. + symtab->hash_table = dbopen(NULL, O_CREAT | O_RDWR, 0600, DB_HASH, NULL); + if (symtab->hash_table == NULL) + goto quit; + + symtab->num_symbols = symtabcmd.nsyms; + symtab->symbols = (symtab_symbol *)malloc(sizeof(symtab_symbol) * symtab->num_symbols); + symtab->strs = (char *)malloc(sizeof(char) * symtabcmd.strsize); + if (symtab->symbols == NULL || symtab->strs == NULL) { + print_debug("out of memory: allocating symtab.symbol or symtab.strs\n"); + goto quit; + } + lseek(fd, image_start + symtabcmd.symoff, SEEK_SET); + for (i = 0; i < symtab->num_symbols; i++) { + if (read(fd, (void *)&lentry, sizeof(nlist_64)) != sizeof(nlist_64)) { + print_debug("read nlist_64 failed at %i\n", i); + goto quit; + } + symtab->symbols[i].offset = lentry.n_value; + symtab->symbols[i].size = lentry.n_un.n_strx; // index + } + + // string table + lseek(fd, image_start + symtabcmd.stroff, SEEK_SET); + int size = read(fd, (void *)(symtab->strs), symtabcmd.strsize * sizeof(char)); + if (size != symtabcmd.strsize * sizeof(char)) { + print_debug("reading string table failed\n"); + goto quit; + } + + for (i = 0; i < symtab->num_symbols; i++) { + symtab->symbols[i].name = symtab->strs + symtab->symbols[i].size; + if (i > 0) { + // fix size + symtab->symbols[i - 1].size = symtab->symbols[i].size - symtab->symbols[i - 1].size; + print_debug("%s size = %d\n", symtab->symbols[i - 1].name, symtab->symbols[i - 1].size); + + } + + if (i == symtab->num_symbols - 1) { + // last index + symtab->symbols[i].size = + symtabcmd.strsize - symtab->symbols[i].size; + print_debug("%s size = %d\n", symtab->symbols[i].name, symtab->symbols[i].size); + } + } + + // build a hashtable for fast query + build_search_table(symtab); + return symtab; +quit: + if (symtab) destroy_symtab(symtab); + return NULL; +} + +#else // __APPLE__ + struct elf_section { ELF_SHDR *c_shdr; void *c_data; }; -struct elf_symbol { - char *name; - uintptr_t offset; - uintptr_t size; -}; - -typedef struct symtab { - char *strs; - size_t num_symbols; - struct elf_symbol *symbols; - DB* hash_table; -} symtab_t; - // read symbol table from given fd. struct symtab* build_symtab(int fd) { ELF_EHDR ehdr; @@ -176,7 +326,7 @@ struct symtab* build_symtab(int fd) { key.data = sym_name; key.size = strlen(sym_name) + 1; value.data = &(symtab->symbols[j]); - value.size = sizeof(void *); + value.size = sizeof(symtab_symbol); (*symtab->hash_table->put)(symtab->hash_table, &key, &value, 0); } } @@ -201,30 +351,29 @@ quit: return symtab; } -void destroy_symtab(struct symtab* symtab) { +#endif // __APPLE__ + +void destroy_symtab(symtab_t* symtab) { if (!symtab) return; - if (symtab->strs) free(symtab->strs); - if (symtab->symbols) free(symtab->symbols); - if (symtab->hash_table) { - (*symtab->hash_table->close)(symtab->hash_table); - } + free(symtab->strs); + free(symtab->symbols); free(symtab); } -uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, - const char *sym_name, int *sym_size) { +uintptr_t search_symbol(struct symtab* symtab, uintptr_t base, const char *sym_name, int *sym_size) { DBT key, value; int ret; // library does not have symbol table - if (!symtab || !symtab->hash_table) + if (!symtab || !symtab->hash_table) { return 0; + } key.data = (char*)(uintptr_t)sym_name; key.size = strlen(sym_name) + 1; ret = (*symtab->hash_table->get)(symtab->hash_table, &key, &value, 0); if (ret == 0) { - struct elf_symbol *sym = value.data; + symtab_symbol *sym = value.data; uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset); if (sym_size) *sym_size = sym->size; return rslt; @@ -238,7 +387,7 @@ const char* nearest_symbol(struct symtab* symtab, uintptr_t offset, int n = 0; if (!symtab) return NULL; for (; n < symtab->num_symbols; n++) { - struct elf_symbol* sym = &(symtab->symbols[n]); + symtab_symbol* sym = &(symtab->symbols[n]); if (sym->name != NULL && offset >= sym->offset && offset < sym->offset + sym->size) { if (poffset) *poffset = (offset - sym->offset); diff --git a/hotspot/agent/src/os/bsd/symtab.h b/hotspot/agent/src/os/bsd/symtab.h index 9b7eef77d69..f5f8645dabc 100644 --- a/hotspot/agent/src/os/bsd/symtab.h +++ b/hotspot/agent/src/os/bsd/symtab.h @@ -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 @@ -27,11 +27,11 @@ #include -// interface to manage ELF symbol tables +// interface to manage ELF or MachO symbol tables struct symtab; -// build symbol table for a given ELF file descriptor +// build symbol table for a given ELF or MachO file escriptor struct symtab* build_symtab(int fd); // destroy the symbol table diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java index ed688758d41..6d422f62acc 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/BsdVtblAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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,11 +34,18 @@ public class BsdVtblAccess extends BasicVtblAccess { public BsdVtblAccess(SymbolLookup symbolLookup, String[] dllNames) { super(symbolLookup, dllNames); - - if (symbolLookup.lookup("libjvm.so", "__vt_10JavaThread") != null || - symbolLookup.lookup("libjvm_g.so", "__vt_10JavaThread") != null) { + boolean oldVT = false; + boolean isDarwin = dllNames[0].lastIndexOf(".dylib") != -1; + String vtJavaThread = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread"; + for (String dllName : dllNames) { + if (symbolLookup.lookup(dllName, vtJavaThread) != null) { + oldVT = true; + break; + } + } + if (oldVT) { // old C++ ABI - vt = "__vt_"; + vt = isDarwin ? "_vt_" : "__vt_"; } else { // new C++ ABI vt = "_ZTV"; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 23058f42858..8c73ca4d0fd 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -1517,7 +1517,7 @@ public class CommandProcessor { ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { - out.println(bos.toString() + " = " + thread.getAddress()); + out.println("Thread " + bos.toString() + " Address: " + thread.getAddress()); HTMLGenerator gen = new HTMLGenerator(false); try { out.println(gen.genHTMLForJavaStackTrace(thread)); @@ -1546,7 +1546,7 @@ public class CommandProcessor { ByteArrayOutputStream bos = new ByteArrayOutputStream(); thread.printThreadIDOn(new PrintStream(bos)); if (all || bos.toString().equals(name)) { - out.println(bos.toString() + " = " + thread.getAddress()); + out.println("Thread " + bos.toString() + " Address " + thread.getAddress()); if (!all) return; } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java index bb718d9f78b..8abd084c8b3 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -311,6 +311,8 @@ public class HotSpotAgent { setupDebuggerLinux(); } else if (os.equals("bsd")) { setupDebuggerBsd(); + } else if (os.equals("darwin")) { + setupDebuggerDarwin(); } else { // Add support for more operating systems here throw new DebuggerException("Operating system " + os + " not yet supported"); @@ -370,6 +372,10 @@ public class HotSpotAgent { db = new HotSpotTypeDataBase(machDesc, new BsdVtblAccess(debugger, jvmLibNames), debugger, jvmLibNames); + } else if (os.equals("darwin")) { + db = new HotSpotTypeDataBase(machDesc, + new BsdVtblAccess(debugger, jvmLibNames), + debugger, jvmLibNames); } else { throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess yet)"); } @@ -459,6 +465,8 @@ public class HotSpotAgent { setupJVMLibNamesLinux(); } else if (os.equals("bsd")) { setupJVMLibNamesBsd(); + } else if (os.equals("darwin")) { + setupJVMLibNamesDarwin(); } else { throw new RuntimeException("Unknown OS type"); } @@ -567,6 +575,29 @@ public class HotSpotAgent { jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" }; } + // + // Darwin + // + + private void setupDebuggerDarwin() { + setupJVMLibNamesDarwin(); + + if (cpu.equals("amd64") || cpu.equals("x86_64")) { + machDesc = new MachineDescriptionAMD64(); + } else { + throw new DebuggerException("Darwin only supported on x86_64. Current arch: " + cpu); + } + + BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer); + debugger = dbg; + + attachDebugger(); + } + + private void setupJVMLibNamesDarwin() { + jvmLibNames = new String[] { "libjvm.dylib", "libjvm_g.dylib" }; + } + /** Convenience routine which should be called by per-platform debugger setup. Should not be called when startupMode is REMOTE_MODE. */ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java index c6fbb7dab34..9a26584e324 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -31,6 +31,9 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.x86.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.utilities.*; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.Threads; +import sun.jvm.hotspot.runtime.JavaThread; import java.lang.reflect.*; /**

An implementation of the JVMDebugger interface. The basic debug @@ -51,10 +54,11 @@ import java.lang.reflect.*; public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { private boolean useGCC32ABI; private boolean attached; - private long p_ps_prochandle; // native debugger handle - private long symbolicator; // macosx symbolicator handle - private long task; // macosx task handle + private long p_ps_prochandle; // native debugger handle + private long symbolicator; // macosx symbolicator handle + private long task; // macosx task handle private boolean isCore; + private boolean isDarwin; // variant for bsd // CDebugger support private BsdCDebugger cdbg; @@ -208,6 +212,7 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { } } + isDarwin = getOS().equals("darwin"); workerThread = new BsdDebuggerLocalWorkerThread(this); workerThread.start(); } @@ -240,8 +245,11 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { /* called from attach methods */ private void findABIVersion() throws DebuggerException { - if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0 || - lookupByName0("libjvm_g.so", "__vt_10JavaThread") != 0) { + String libjvmName = isDarwin ? "libjvm.dylib" : "libjvm.so"; + String libjvm_gName = isDarwin? "libjvm_g.dylib" : "libjvm_g.so"; + String javaThreadVt = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread"; + if (lookupByName0(libjvmName, javaThreadVt) != 0 || + lookupByName0(libjvm_gName, javaThreadVt) != 0) { // old C++ ABI useGCC32ABI = false; } else { @@ -360,7 +368,8 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { } if (isCore) { - long addr = lookupByName0(objectName, symbol); + // MacOSX symbol with "_" as leading + long addr = lookupByName0(objectName, isDarwin ? "_" + symbol : symbol); return (addr == 0)? null : new BsdAddress(this, handleGCC32ABI(addr, symbol)); } else { class LookupByNameTask implements WorkerThreadTask { @@ -403,12 +412,12 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) { return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr); } + @Override public ThreadProxy getThreadForIdentifierAddress(Address addr) { throw new RuntimeException("unimplemented"); } - /** From the ThreadAccess interface via Debugger and JVMDebugger */ public ThreadProxy getThreadForThreadId(long id) { return new BsdThread(this, id); @@ -601,6 +610,33 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger { throw new DebuggerException("Unimplemented"); } + /** this functions used for core file reading and called from native attach0, + it returns an array of long integers as + [thread_id, stack_start, stack_end, thread_id, stack_start, stack_end, ....] for + all java threads recorded in Threads. Also adds the ThreadProxy to threadList */ + public long[] getJavaThreadsInfo() { + requireAttach(); + Threads threads = VM.getVM().getThreads(); + int len = threads.getNumberOfThreads(); + long[] result = new long[len * 3]; // triple + JavaThread t = threads.first(); + long beg, end; + int i = 0; + while (t != null) { + end = t.getStackBaseValue(); + beg = end - t.getStackSize(); + BsdThread bsdt = (BsdThread)t.getThreadProxy(); + long uid = bsdt.getUniqueThreadId(); + if (threadList != null) threadList.add(bsdt); + result[i] = uid; + result[i + 1] = beg; + result[i + 2] = end; + t = t.next(); + i += 3; + } + return result; + } + static { System.loadLibrary("saproc"); init0(); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java index f3351fb9ce1..0d637f30f14 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -44,7 +44,8 @@ class BsdThread implements ThreadProxy { BsdThread(BsdDebugger debugger, long id) { this.debugger = debugger; - this.thread_id = (int) id; + // use unique_thread_id to identify thread + this.unique_thread_id = id; } public boolean equals(Object obj) { @@ -52,7 +53,7 @@ class BsdThread implements ThreadProxy { return false; } - return (((BsdThread) obj).thread_id == thread_id); + return (((BsdThread) obj).unique_thread_id == unique_thread_id); } public int hashCode() { @@ -80,4 +81,9 @@ class BsdThread implements ThreadProxy { throws IllegalThreadStateException, DebuggerException { throw new DebuggerException("Unimplemented"); } + + /** this is not interface function, used in core file to get unique thread id on Macosx*/ + public long getUniqueThreadId() { + return unique_thread_id; + } } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java index 153d51bb090..926c11c4bad 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -320,6 +320,10 @@ public class JavaThread extends Thread { return stackBaseField.getValue(addr); } + public long getStackBaseValue() { + return VM.getVM().getAddressValue(getStackBase()); + } + public long getStackSize() { return stackSizeField.getValue(addr); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java index 8e259e3a145..b4b5903d139 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -42,6 +42,7 @@ import sun.jvm.hotspot.utilities.*; public class Threads { private static JavaThreadFactory threadFactory; private static AddressField threadListField; + private static CIntegerField numOfThreadsField; private static VirtualConstructor virtualConstructor; private static JavaThreadPDAccess access; @@ -57,6 +58,7 @@ public class Threads { Type type = db.lookupType("Threads"); threadListField = type.getAddressField("_thread_list"); + numOfThreadsField = type.getCIntegerField("_number_of_threads"); // Instantiate appropriate platform-specific JavaThreadFactory String os = VM.getVM().getOS(); @@ -102,6 +104,10 @@ public class Threads { } else if (cpu.equals("amd64") || cpu.equals("x86_64")) { access = new BsdAMD64JavaThreadPDAccess(); } + } else if (os.equals("darwin")) { + if (cpu.equals("amd64") || cpu.equals("x86_64")) { + access = new BsdAMD64JavaThreadPDAccess(); + } } if (access == null) { @@ -144,6 +150,10 @@ public class Threads { return createJavaThreadWrapper(threadAddr); } + public int getNumberOfThreads() { + return (int) numOfThreadsField.getValue(); + } + /** Routine for instantiating appropriately-typed wrapper for a JavaThread. Currently needs to be public for OopUtilities to access it. */ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java index 54aa0e0de5c..0b3720ff594 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.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 @@ -32,6 +32,7 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.utilities.PlatformInfo; public class PStack extends Tool { // in non-verbose mode, Method*s are not printed in java frames @@ -54,6 +55,11 @@ public class PStack extends Tool { } public void run(PrintStream out, Debugger dbg) { + if (PlatformInfo.getOS().equals("darwin")) { + out.println("Not available on Darwin"); + return; + } + CDebugger cdbg = dbg.getCDebugger(); if (cdbg != null) { ConcurrentLocksPrinter concLocksPrinter = null; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java index 9a5dc144a9c..afe81ef578d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,8 +43,8 @@ public class PlatformInfo { return "bsd"; } else if (os.equals("OpenBSD")) { return "bsd"; - } else if (os.equals("Darwin") || os.contains("OS X")) { - return "bsd"; + } else if (os.contains("Darwin") || os.contains("OS X")) { + return "darwin"; } else if (os.startsWith("Windows")) { return "win32"; } else { diff --git a/hotspot/agent/src/share/native/sadis.c b/hotspot/agent/src/share/native/sadis.c index f8bd9adbd64..926b4e5fd55 100644 --- a/hotspot/agent/src/share/native/sadis.c +++ b/hotspot/agent/src/share/native/sadis.c @@ -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 @@ -48,7 +48,10 @@ #include #include + +#ifndef __APPLE__ #include +#endif #endif @@ -109,9 +112,7 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_asm_Disassembler_load_1library(JNIE jstring libname_s) { uintptr_t func = 0; const char* error_message = NULL; - const char* java_home; jboolean isCopy; - uintptr_t *handle = NULL; const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/ const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy); @@ -167,7 +168,8 @@ typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va, void* event_stream, int (*printf_callback)(void*, const char*, ...), void* printf_stream, - const char* options); + const char* options, + int newline); /* container for call back state when decoding instructions */ typedef struct { @@ -281,7 +283,7 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_asm_Disassembler_decode(JNIEnv * env end - start, &event_to_env, (void*) &denv, &printf_to_env, (void*) &denv, - options); + options, 0 /* newline */); /* cleanup */ (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); diff --git a/hotspot/make/bsd/makefiles/saproc.make b/hotspot/make/bsd/makefiles/saproc.make index 4fb216b41f6..62e31a63dc0 100644 --- a/hotspot/make/bsd/makefiles/saproc.make +++ b/hotspot/make/bsd/makefiles/saproc.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 @@ -24,7 +24,7 @@ # Rules to build serviceability agent library, used by vm.make -# libsaproc.so: serviceability agent +# libsaproc.so(dylib): serviceability agent SAPROC = saproc ifeq ($(OS_VENDOR), Darwin) @@ -37,7 +37,7 @@ AGENT_DIR = $(GAMMADIR)/agent SASRCDIR = $(AGENT_DIR)/src/os/$(Platform_os_family) -NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \ +BSD_NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \ $(SASRCDIR)/symtab.c \ $(SASRCDIR)/libproc_impl.c \ $(SASRCDIR)/ps_proc.c \ @@ -45,13 +45,19 @@ NON_STUB_SASRCFILES = $(SASRCDIR)/salibelf.c \ $(SASRCDIR)/BsdDebuggerLocal.c \ $(AGENT_DIR)/src/share/native/sadis.c +DARWIN_NON_STUB_SASRCFILES = $(SASRCDIR)/symtab.c \ + $(SASRCDIR)/libproc_impl.c \ + $(SASRCDIR)/ps_core.c \ + $(SASRCDIR)/MacosxDebuggerLocal.m \ + $(AGENT_DIR)/src/share/native/sadis.c + ifeq ($(OS_VENDOR), FreeBSD) - SASRCFILES = $(NON_STUB_SASRCFILES) + SASRCFILES = $(BSD_NON_STUB_SASRCFILES) SALIBS = -lutil -lthread_db SAARCH = $(ARCHFLAG) else ifeq ($(OS_VENDOR), Darwin) - SASRCFILES = $(SASRCDIR)/MacosxDebuggerLocal.m + SASRCFILES = $(DARWIN_NON_STUB_SASRCFILES) SALIBS = -g -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation #objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles? SAARCH = $(subst -march=i586,,$(ARCHFLAG)) @@ -102,7 +108,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE) fi @echo Making SA debugger back-end... $(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \ - $(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG) \ + $(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG) \ -I$(SASRCDIR) \ -I$(GENERATED) \ $(BOOT_JAVA_INCLUDES) \ From be64bfbaadaefd9a0280d1f326b79bd80b08a669 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Thu, 14 Mar 2013 12:15:17 +0400 Subject: [PATCH 014/137] 8000183: 7163696: JCK Swing interactive test JScrollBarTest0013 fails with Nimbus and GTK L&Fs Reviewed-by: alexsch, serb --- .../swing/plaf/synth/SynthScrollBarUI.java | 1 + .../swing/JScrollBar/7163696/Test7163696.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java index 093aeaee5f8..fa631ed5cb8 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java @@ -57,6 +57,7 @@ public class SynthScrollBarUI extends BasicScrollBarUI */ @Override protected void installDefaults() { + super.installDefaults(); trackHighlight = NO_HIGHLIGHT; if (scrollbar.getLayout() == null || (scrollbar.getLayout() instanceof UIResource)) { diff --git a/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java b/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java new file mode 100644 index 00000000000..922bf2e4963 --- /dev/null +++ b/jdk/test/javax/swing/JScrollBar/7163696/Test7163696.java @@ -0,0 +1,103 @@ +/* + * 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 7163696 + * @summary Tests that JScrollBar scrolls to the left + * @author Sergey Malenkov + */ + +import sun.awt.SunToolkit; + +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; + +import javax.swing.JFrame; +import javax.swing.JScrollBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; + +public class Test7163696 implements Runnable { + + private static final boolean AUTO = null != System.getProperty("test.src", null); + + public static void main(String[] args) throws Exception { + new Test7163696().test(); + } + + private JScrollBar bar; + + private void test() throws Exception { + Robot robot = new Robot(); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { + UIManager.setLookAndFeel(info.getClassName()); + + SwingUtilities.invokeAndWait(this); + toolkit.realSync(500); // after creation + + Point point = this.bar.getLocation(); + SwingUtilities.convertPointToScreen(point, this.bar); + point.x += this.bar.getWidth() >> 2; + point.y += this.bar.getHeight() >> 1; + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + toolkit.realSync(500); // before validation + SwingUtilities.invokeAndWait(this); + + if (this.bar != null) { + this.bar = null; // allows to reuse the instance + if (AUTO) { // error reporting only for automatic testing + throw new Error("TEST FAILED"); + } + } + } + } + + public void run() { + if (this.bar == null) { + this.bar = new JScrollBar(JScrollBar.HORIZONTAL, 50, 10, 0, 100); + this.bar.setPreferredSize(new Dimension(400, 20)); + + JFrame frame = new JFrame(); + frame.add(this.bar); + frame.pack(); + frame.setVisible(true); + } + else if (40 != this.bar.getValue()) { + System.out.println("name = " + UIManager.getLookAndFeel().getName()); + System.out.println("value = " + this.bar.getValue()); + } + else { + SwingUtilities.getWindowAncestor(this.bar).dispose(); + this.bar = null; + } + } +} From a4a4c34e961dfa163bb26e285df18d1324dcf739 Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Thu, 14 Mar 2013 10:54:44 +0100 Subject: [PATCH 015/137] 8005602: NPG: classunloading does not happen while CMS GC with -XX:+CMSClassUnloadingEnabled is used Call purge() on CLDG after sweep(), reorder purge() call in GenCollectedHeap Reviewed-by: jmasa, stefank --- .../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 4 ++++ hotspot/src/share/vm/memory/genCollectedHeap.cpp | 7 ++----- hotspot/src/share/vm/memory/metaspace.cpp | 8 +++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 1d056338c7d..df6aabbb527 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -6068,6 +6068,10 @@ void CMSCollector::sweep(bool asynch) { verify_work_stacks_empty(); verify_overflow_empty(); + if (should_unload_classes()) { + ClassLoaderDataGraph::purge(); + } + _intra_sweep_timer.stop(); _intra_sweep_estimate.sample(_intra_sweep_timer.seconds()); diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp index 9d65cc15701..6b7402c8203 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp @@ -554,6 +554,8 @@ void GenCollectedHeap::do_collection(bool full, } if (complete) { + // Delete metaspaces for unloaded class loaders and clean up loader_data graph + ClassLoaderDataGraph::purge(); // Resize the metaspace capacity after full collections MetaspaceGC::compute_new_size(); update_full_collections_completed(); @@ -564,11 +566,6 @@ void GenCollectedHeap::do_collection(bool full, gc_epilogue(complete); - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - if (complete) { - ClassLoaderDataGraph::purge(); - } - if (must_restore_marks_for_biased_locking) { BiasedLocking::restore_marks(); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 56b14c22cf7..9fa054fe0eb 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1309,8 +1309,7 @@ void MetaspaceGC::compute_new_size() { gclog_or_tty->print_cr(" metaspace HWM: %.1fK", new_capacity_until_GC / (double) K); } } - assert(vsl->used_bytes_sum() == used_after_gc && - used_after_gc <= vsl->capacity_bytes_sum(), + assert(used_after_gc <= vsl->capacity_bytes_sum(), "sanity check"); } @@ -1970,6 +1969,9 @@ void SpaceManager::initialize() { } SpaceManager::~SpaceManager() { + // This call this->_lock which can't be done while holding expand_lock() + const size_t in_use_before = sum_capacity_in_chunks_in_use(); + MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); @@ -1987,7 +1989,7 @@ SpaceManager::~SpaceManager() { // Have to update before the chunks_in_use lists are emptied // below. - chunk_manager->inc_free_chunks_total(sum_capacity_in_chunks_in_use(), + chunk_manager->inc_free_chunks_total(in_use_before, sum_count_in_chunks_in_use()); // Add all the chunks in use by this space manager From e1df78e39021875579857673174090e73bad66b5 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 14 Mar 2013 09:37:38 +0100 Subject: [PATCH 016/137] 6733980: par compact - TraceGen1Time always shows 0.0000 seconds Use the correct collector to retrieve accumulated gen1 trace time Reviewed-by: johnc, jmasa --- .../gc_implementation/parallelScavenge/parallelScavengeHeap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 21e08b6f874..0c39e69e1be 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -656,7 +656,7 @@ void ParallelScavengeHeap::print_tracing_info() const { tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time); } if (TraceGen1Time) { - double time = PSMarkSweep::accumulated_time()->seconds(); + double time = UseParallelOldGC ? PSParallelCompact::accumulated_time()->seconds() : PSMarkSweep::accumulated_time()->seconds(); tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time); } } From 2aeaf10fffd24b57bb3cef0feac6c9059d288a15 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Thu, 14 Mar 2013 14:49:55 +0100 Subject: [PATCH 017/137] 8009982: Lazy execution bugfix. Added lazy sunspider unit test. Added mandreel to compile-octane test. Fixed warnings Reviewed-by: sundar, jlaskey --- .../scripting/NashornScriptEngineFactory.java | 2 +- .../internal/codegen/CodeGenerator.java | 5 ++- .../nashorn/internal/codegen/Compiler.java | 36 +++++++++++++++---- .../jdk/nashorn/internal/ir/FunctionNode.java | 12 +++---- .../jdk/nashorn/internal/objects/Global.java | 3 +- .../jdk/nashorn/internal/parser/Parser.java | 2 +- .../jdk/nashorn/internal/runtime/Context.java | 1 + .../internal/runtime/ScriptLoader.java | 3 +- .../runtime/linker/JavaAdapterFactory.java | 1 + .../runtime/regexp/DefaultRegExp.java | 10 +++--- .../internal/runtime/regexp/JoniRegExp.java | 10 +++--- .../internal/runtime/regexp/RegExp.java | 2 +- .../runtime/regexp/RegExpFactory.java | 9 +++-- .../internal/runtime/regexp/RegExpResult.java | 6 ++-- .../runtime/regexp/RegExpScanner.java | 2 -- .../script/basic/compile-octane.js.EXPECTED | 3 ++ nashorn/test/script/basic/run-octane.js | 23 +++++++++--- .../test/script/basic/runsunspider-eager.js | 33 +++++++++++++++++ .../test/script/basic/runsunspider-lazy.js | 34 ++++++++++++++++++ nashorn/test/script/basic/runsunspider.js | 30 +--------------- 20 files changed, 152 insertions(+), 75 deletions(-) create mode 100644 nashorn/test/script/basic/runsunspider-eager.js create mode 100644 nashorn/test/script/basic/runsunspider-lazy.js diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java index 4672f6a073e..e38284da99e 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java @@ -176,7 +176,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory { // -- Internals only below this point - private void checkConfigPermission() { + private static void checkConfigPermission() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("nashorn.setConfig")); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 71a2eb0fe1e..ce6a1fcdfdf 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -3230,8 +3230,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } private void newFunctionObject(final FunctionNode functionNode) { - final boolean isLazy = functionNode.isLazy(); - final Class[] cparams = new Class[] { RecompilableScriptFunctionData.class, ScriptObject.class }; + final boolean isLazy = functionNode.isLazy(); new ObjectCreator(this, new ArrayList(), new ArrayList(), false, false) { @Override @@ -3246,7 +3245,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } else { m.loadNull(); } - m.invoke(constructorNoLookup(className, cparams)); + m.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class)); } }.makeObject(method); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index a799ee0506f..87d26c1aab5 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -217,8 +217,6 @@ public final class Compiler { append(safeSourceName(functionNode.getSource())); this.scriptName = sb.toString(); - - LOG.info("Initializing compiler for '" + functionNode.getName() + "' scriptName = " + scriptName + ", root function: '" + functionNode.getName() + "' lazy=" + functionNode.isLazy()); } /** @@ -361,7 +359,10 @@ public final class Compiler { final Map> installedClasses = new HashMap<>(); final String rootClassName = firstCompileUnitName(); - final Class rootClass = install(rootClassName, bytecode.get(rootClassName)); + final byte[] rootByteCode = bytecode.get(rootClassName); + final Class rootClass = install(rootClassName, rootByteCode); + + int length = rootByteCode.length; installedClasses.put(rootClassName, rootClass); @@ -370,7 +371,10 @@ public final class Compiler { if (className.equals(rootClassName)) { continue; } - installedClasses.put(className, install(className, entry.getValue())); + final byte[] code = entry.getValue(); + length += code.length; + + installedClasses.put(className, install(className, code)); } for (final CompileUnit unit : compileUnits) { @@ -388,12 +392,32 @@ public final class Compiler { } }); - LOG.info("Installed root class: " + rootClass + " and " + bytecode.size() + " compile unit classes"); + final StringBuilder sb; + if (LOG.isEnabled()) { + sb = new StringBuilder(); + sb.append("Installed class '"). + append(rootClass.getSimpleName()). + append('\''). + append(" bytes="). + append(length). + append('.'); + if (bytecode.size() > 1) { + sb.append(' ').append(bytecode.size()).append(" compile units."); + } + } else { + sb = null; + } if (Timing.isEnabled()) { final long duration = System.currentTimeMillis() - t0; Timing.accumulateTime("[Code Installation]", duration); - LOG.info("Installation time: " + duration + " ms"); + if (sb != null) { + sb.append(" Install time: ").append(duration).append(" ms"); + } + } + + if (sb != null) { + LOG.info(sb.toString()); } return rootClass; diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java index 63590932d44..7fd77cd0471 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -218,8 +218,9 @@ public class FunctionNode extends Block { private static final int HAS_ALL_VARS_IN_SCOPE = HAS_DEEP_WITH_OR_EVAL | IS_SPLIT | HAS_LAZY_CHILDREN; /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */ private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL; - /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep with or eval. */ - private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_WITH_OR_EVAL; + /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep with or eval. + * We also pessimistically need a parent scope if we have lazy children that have not yet been compiled */ + private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_WITH_OR_EVAL | HAS_LAZY_CHILDREN; /** What is the return type of this function? */ private Type returnType = Type.UNKNOWN; @@ -724,13 +725,10 @@ public class FunctionNode extends Block { * their parent scope, functions that reference themselves, and non-strict functions that need an Arguments object * (since it exposes {@code arguments.callee} property) will need to have a callee parameter. * - * We also conservatively need a callee if we have lazy children, i.e. nested function nodes that have not yet - * been evaluated. _They_ may need the callee and we don't know it - * * @return true if the function's generated Java method needs a {@code callee} parameter. */ public boolean needsCallee() { - return hasLazyChildren() || needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode()); + return needsParentScope() || needsSelfSymbol() || (needsArguments() && !isStrictMode()); } /** @@ -1076,7 +1074,7 @@ public class FunctionNode extends Block { } else { this.flags |= USES_ANCESTOR_SCOPE; final FunctionNode parentFn = findParentFunction(); - if(parentFn != null) { + if (parentFn != null) { parentFn.setUsesScopeSymbol(symbol); } } diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index a9835f6fea9..e0bb9ecefd2 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -1528,8 +1528,9 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED); } - private void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) { + private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) { AccessController.doPrivileged(new PrivilegedAction() { + @Override public Void run() { for (Field f : scriptEnv.getClass().getFields()) { try { diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index bfc96abf47c..166fed91f9e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -126,7 +126,7 @@ public class Parser extends AbstractParser { /** Namespace for function names where not explicitly given */ private final Namespace namespace; - private static DebugLogger LOG = new DebugLogger("parser"); + private static final DebugLogger LOG = new DebugLogger("parser"); /** * Constructor diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 151615c07df..0ca2c47a9ec 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -744,6 +744,7 @@ public final class Context { global = (GlobalObject)Context.getGlobalTrusted(); script = global.findCachedClass(source); if (script != null) { + Compiler.LOG.fine("Code cache hit for " + source + " avoiding recompile."); return script; } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java index adecd8a3cbe..370faf312d0 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -60,8 +60,7 @@ final class ScriptLoader extends NashornLoader { synchronized Class installClass(final String name, final byte[] data, final CodeSource cs) { if (cs == null) { return defineClass(name, data, 0, data.length, new ProtectionDomain(null, getPermissions(null))); - } else { - return defineClass(name, data, 0, data.length, cs); } + return defineClass(name, data, 0, data.length, cs); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java index ba599da1a98..7b0d6d76190 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java @@ -412,6 +412,7 @@ public final class JavaAdapterFactory { public static MethodHandle getConstructor(final Class sourceType, final Class targetType) throws Exception { final StaticClass adapterClass = getAdapterClassFor(new Class[] { targetType }); return AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override public MethodHandle run() throws Exception { return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get( "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false, diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java index 7c1dd8b448d..ecbc8bc9340 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java @@ -95,14 +95,14 @@ public class DefaultRegExp extends RegExp { return null; // never matches or similar, e.g. a[] } - RegExpMatcher matcher = this.matcher; + RegExpMatcher currentMatcher = this.matcher; - if (matcher == null || matcher.getInput() != str) { - matcher = new DefaultMatcher(str); - this.matcher = matcher; + if (currentMatcher == null || matcher.getInput() != str) { + currentMatcher = new DefaultMatcher(str); + this.matcher = currentMatcher; } - return matcher; + return currentMatcher; } class DefaultMatcher implements RegExpMatcher { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java index f8c35bfe99d..719f6c398ca 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java @@ -97,14 +97,14 @@ public class JoniRegExp extends RegExp { return null; } - RegExpMatcher matcher = this.matcher; + RegExpMatcher currentMatcher = this.matcher; - if (matcher == null || input != matcher.getInput()) { - matcher = new JoniMatcher(input); - this.matcher = matcher; + if (currentMatcher == null || input != currentMatcher.getInput()) { + currentMatcher = new JoniMatcher(input); + this.matcher = currentMatcher; } - return matcher; + return currentMatcher; } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java index a4274f6ae8b..ff694b90790 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java @@ -156,7 +156,7 @@ public abstract class RegExp { * * @param key the message key * @param str string argument - * @throws jdk.nashorn.internal.runtime.ParserException + * @throws jdk.nashorn.internal.runtime.ParserException unconditionally */ protected static void throwParserException(final String key, final String str) throws ParserException { throw new ParserException(ECMAErrors.getMessage("parser.error.regex." + key, str)); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java index 367cc85b28a..6ff66f21d05 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.runtime.regexp; -import jdk.nashorn.internal.parser.Lexer; import jdk.nashorn.internal.runtime.ParserException; import jdk.nashorn.internal.runtime.options.Options; @@ -35,7 +34,6 @@ import jdk.nashorn.internal.runtime.options.Options; */ public class RegExpFactory { - private final static RegExpFactory instance; private final static String JDK = "jdk"; @@ -60,7 +58,8 @@ public class RegExpFactory { * Creates a Regular expression from the given {@code pattern} and {@code flags} strings. * * @param pattern RegExp pattern string - * @param flags RegExp flags string + * @param flags RegExp flags string + * @return new RegExp * @throws ParserException if flags is invalid or pattern string has syntax error. */ protected RegExp compile(final String pattern, final String flags) throws ParserException { @@ -71,8 +70,8 @@ public class RegExpFactory { * Compile a regexp with the given {@code source} and {@code flags}. * * @param pattern RegExp pattern string - * @param flags flag string - * + * @param flags flag string + * @return new RegExp * @throws ParserException if invalid source or flags */ public static RegExp create(final String pattern, final String flags) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java index ff838b6f346..cd81be3ccf8 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpResult.java @@ -80,11 +80,11 @@ public final class RegExpResult { /** * Get the group with the given index or the empty string if group index is not valid. - * @param index the group index + * @param groupIndex the group index * @return the group or "" */ - public Object getGroup(int index) { - return index >= 0 && index < groups.length ? groups[index] : ""; + public Object getGroup(final int groupIndex) { + return groupIndex >= 0 && groupIndex < groups.length ? groups[groupIndex] : ""; } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java index b579865b693..e8c60c4a63e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java @@ -182,8 +182,6 @@ final class RegExpScanner extends Scanner { * @return Committed token */ private boolean commit(final int n) { - final int startIn = position; - switch (n) { case 1: sb.append(ch0); diff --git a/nashorn/test/script/basic/compile-octane.js.EXPECTED b/nashorn/test/script/basic/compile-octane.js.EXPECTED index dab419e6d46..39f866c2d17 100644 --- a/nashorn/test/script/basic/compile-octane.js.EXPECTED +++ b/nashorn/test/script/basic/compile-octane.js.EXPECTED @@ -16,6 +16,9 @@ Compiled OK: earley-boyer.js Compiling... gbemu.js Compiled OK: gbemu.js +Compiling... mandreel.js +Compiled OK: mandreel.js + Compiling... navier-stokes.js Compiled OK: navier-stokes.js diff --git a/nashorn/test/script/basic/run-octane.js b/nashorn/test/script/basic/run-octane.js index 42bf77fa9e6..315451cbee8 100644 --- a/nashorn/test/script/basic/run-octane.js +++ b/nashorn/test/script/basic/run-octane.js @@ -31,7 +31,8 @@ var tests = [ "crypto.js", "deltablue.js", "earley-boyer.js", - "gbemu.js", + "gbemu.js", + "mandreel.js", "navier-stokes.js", "pdfjs.js", "raytrace.js", @@ -49,6 +50,12 @@ var ignoreTeardown = [ { name: "gbemu.js" }, ]; + +//TODO mandreel can be compiled as a test, but not run multiple times unless modified to not have global state +var compileOnly = { + "mandreel.js" : true +}; + var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__; // TODO: why is this path hard coded when it's defined in project properties? @@ -63,6 +70,10 @@ function endsWith(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; } +function should_compile_only(name) { + return (typeof compile_only !== 'undefined') || compileOnly[name] === true; +} + function run_one_benchmark(arg, iters) { var file_name; @@ -77,14 +88,18 @@ function run_one_benchmark(arg, iters) { } file_name = file[file.length - 1]; - if (typeof compile_only !== 'undefined') { + var compile_and_return = should_compile_only(file_name); + if (compile_and_return) { + if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them + return; + } print("Compiling... " + file_name); } load(path + 'base.js'); load(arg); - if (typeof compile_only !== 'undefined') { + if (compile_and_return) { print("Compiled OK: " + file_name); print(""); return; @@ -164,7 +179,7 @@ function run_one_benchmark(arg, iters) { function run_suite(tests, iters) { for (var idx = 0; idx < tests.length; idx++) { - run_one_benchmark(tests[idx], iters, false); + run_one_benchmark(tests[idx], iters); } } diff --git a/nashorn/test/script/basic/runsunspider-eager.js b/nashorn/test/script/basic/runsunspider-eager.js new file mode 100644 index 00000000000..db358d28555 --- /dev/null +++ b/nashorn/test/script/basic/runsunspider-eager.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. + */ + +/** + * runsunspider : runs the sunspider tests and checks for compliance + * + * @test + * @option -timezone=PST + * @runif external.sunspider + */ + +load(__DIR__ + "runsunspider.js"); + diff --git a/nashorn/test/script/basic/runsunspider-lazy.js b/nashorn/test/script/basic/runsunspider-lazy.js new file mode 100644 index 00000000000..6e24c0c5255 --- /dev/null +++ b/nashorn/test/script/basic/runsunspider-lazy.js @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/** + * runsunspider : runs the sunspider tests and checks for compliance + * + * @test + * @option -timezone=PST + * @option --lazy-compilation + * @runif external.sunspider + */ + +load(__DIR__ + "runsunspider.js"); + diff --git a/nashorn/test/script/basic/runsunspider.js b/nashorn/test/script/basic/runsunspider.js index 7b0d732c7e8..7f787975888 100644 --- a/nashorn/test/script/basic/runsunspider.js +++ b/nashorn/test/script/basic/runsunspider.js @@ -24,39 +24,11 @@ /** * runsunspider : runs the sunspider tests and checks for compliance * - * @test - * @option -timezone=PST - * @runif external.sunspider - */ - -/* - * Copyright (c) 2010-2011, 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. + * @subtest */ /** * This is not a test, but a test "framework" for running sunspider tests. - * */ function assertEq(a, b) { From b938257957f4bcf6cc19c26ec183bac1850407b3 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Thu, 14 Mar 2013 16:03:10 +0000 Subject: [PATCH 018/137] 8005716: Enhance JNI specification to allow support of static JNI libraries in Embedded JREs Co-authored-by: Bob Vandette Reviewed-by: dlong, alanb, mduigou --- jdk/make/java/java/mapfile-vers | 1 + jdk/makefiles/mapfiles/libjava/mapfile-vers | 1 + .../share/classes/java/lang/ClassLoader.java | 59 ++++--- jdk/src/share/classes/java/lang/Runtime.java | 43 +++-- jdk/src/share/classes/java/lang/System.java | 41 ++++- jdk/src/share/javavm/export/jni.h | 3 +- jdk/src/share/native/common/jni_util.h | 6 +- jdk/src/share/native/java/lang/ClassLoader.c | 162 +++++++++++++++--- jdk/src/solaris/native/common/jni_util_md.c | 22 ++- jdk/src/windows/native/common/jni_util_md.c | 34 +++- 10 files changed, 298 insertions(+), 74 deletions(-) diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index 81e678d7624..60f0f864607 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -133,6 +133,7 @@ SUNWprivate_1.1 { Java_java_lang_ClassLoader_00024NativeLibrary_find; Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_unload; + Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_getCaller; Java_java_lang_ClassLoader_registerNatives; Java_java_lang_Compiler_registerNatives; diff --git a/jdk/makefiles/mapfiles/libjava/mapfile-vers b/jdk/makefiles/mapfiles/libjava/mapfile-vers index 81e678d7624..60f0f864607 100644 --- a/jdk/makefiles/mapfiles/libjava/mapfile-vers +++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers @@ -133,6 +133,7 @@ SUNWprivate_1.1 { Java_java_lang_ClassLoader_00024NativeLibrary_find; Java_java_lang_ClassLoader_00024NativeLibrary_load; Java_java_lang_ClassLoader_00024NativeLibrary_unload; + Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib; Java_java_lang_ClassLoader_getCaller; Java_java_lang_ClassLoader_registerNatives; Java_java_lang_Compiler_registerNatives; diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index a1e18ffe62d..c41280d3c79 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -1683,22 +1683,29 @@ public abstract class ClassLoader { private int jniVersion; // the class from which the library is loaded, also indicates // the loader this native library belongs. - private Class fromClass; + private final Class fromClass; // the canonicalized name of the native library. + // or static library name String name; + // Indicates if the native library is linked into the VM + boolean isBuiltin; + // Indicates if the native library is loaded + boolean loaded; + native void load(String name, boolean isBuiltin); - native void load(String name); native long find(String name); - native void unload(); + native void unload(String name, boolean isBuiltin); + static native String findBuiltinLib(String name); - public NativeLibrary(Class fromClass, String name) { + public NativeLibrary(Class fromClass, String name, boolean isBuiltin) { this.name = name; this.fromClass = fromClass; + this.isBuiltin = isBuiltin; } protected void finalize() { synchronized (loadedLibraryNames) { - if (fromClass.getClassLoader() != null && handle != 0) { + if (fromClass.getClassLoader() != null && loaded) { /* remove the native library name */ int size = loadedLibraryNames.size(); for (int i = 0; i < size; i++) { @@ -1710,7 +1717,7 @@ public abstract class ClassLoader { /* unload the library. */ ClassLoader.nativeLibraryContext.push(this); try { - unload(); + unload(name, isBuiltin); } finally { ClassLoader.nativeLibraryContext.pop(); } @@ -1830,20 +1837,24 @@ public abstract class ClassLoader { } private static boolean loadLibrary0(Class fromClass, final File file) { - boolean exists = AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return file.exists() ? Boolean.TRUE : null; - }}) - != null; - if (!exists) { - return false; - } - String name; - try { - name = file.getCanonicalPath(); - } catch (IOException e) { - return false; + // Check to see if we're attempting to access a static library + String name = NativeLibrary.findBuiltinLib(file.getName()); + boolean isBuiltin = (name != null); + if (!isBuiltin) { + boolean exists = AccessController.doPrivileged( + new PrivilegedAction() { + public Object run() { + return file.exists() ? Boolean.TRUE : null; + }}) + != null; + if (!exists) { + return false; + } + try { + name = file.getCanonicalPath(); + } catch (IOException e) { + return false; + } } ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); @@ -1891,14 +1902,14 @@ public abstract class ClassLoader { } } } - NativeLibrary lib = new NativeLibrary(fromClass, name); + NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); nativeLibraryContext.push(lib); try { - lib.load(name); + lib.load(name, isBuiltin); } finally { nativeLibraryContext.pop(); } - if (lib.handle != 0) { + if (lib.loaded) { loadedLibraryNames.addElement(name); libs.addElement(lib); return true; diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java index 5454707b371..ada915dbb60 100644 --- a/jdk/src/share/classes/java/lang/Runtime.java +++ b/jdk/src/share/classes/java/lang/Runtime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, 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 @@ -749,10 +749,21 @@ public class Runtime { public native void traceMethodCalls(boolean on); /** - * Loads the specified filename as a dynamic library. The filename - * argument must be a complete path name, + * Loads the native library specified by the filename argument. The filename + * argument must be an absolute path name. * (for example * Runtime.getRuntime().load("/home/avh/lib/libX11.so");). + * + * If the filename argument, when stripped of any platform-specific library + * prefix, path, and file extension, indicates a library whose name is, + * for example, L, and a native library called L is statically linked + * with the VM, then the JNI_OnLoad_L function exported by the library + * is invoked rather than attempting to load a dynamic library. + * A filename matching the argument does not have to exist in the file + * system. See the JNI Specification for more details. + * + * Otherwise, the filename argument is mapped to a native library image in + * an implementation-dependent manner. *

* First, if there is a security manager, its checkLink * method is called with the filename as its argument. @@ -769,7 +780,10 @@ public class Runtime { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the file does not exist. + * @exception UnsatisfiedLinkError if either the filename is not an + * absolute path name, the native library is not statically + * linked with the VM, or the library cannot be mapped to + * a native library image by the host system. * @exception NullPointerException if filename is * null * @see java.lang.Runtime#getRuntime() @@ -793,12 +807,16 @@ public class Runtime { } /** - * Loads the dynamic library with the specified library name. - * A file containing native code is loaded from the local file system - * from a place where library files are conventionally obtained. The - * details of this process are implementation-dependent. The - * mapping from a library name to a specific filename is done in a - * system-specific manner. + * Loads the native library specified by the libname + * argument. The libname argument must not contain any platform + * specific prefix, file extension or path. If a native library + * called libname is statically linked with the VM, then the + * JNI_OnLoad_libname function exported by the library is invoked. + * See the JNI Specification for more details. + * + * Otherwise, the libname argument is loaded from a system library + * location and mapped to a native library image in an implementation- + * dependent manner. *

* First, if there is a security manager, its checkLink * method is called with the libname as its argument. @@ -823,7 +841,10 @@ public class Runtime { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the library does not exist. + * @exception UnsatisfiedLinkError if either the libname argument + * contains a file path, the native library is not statically + * linked with the VM, or the library cannot be mapped to a + * native library image by the host system. * @exception NullPointerException if libname is * null * @see java.lang.SecurityException diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 45ea7190ae8..9d1663ae819 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -1037,9 +1037,21 @@ public final class System { } /** - * Loads a code file with the specified filename from the local file - * system as a dynamic library. The filename - * argument must be a complete path name. + * Loads the native library specified by the filename argument. The filename + * argument must be an absolute path name. + * + * If the filename argument, when stripped of any platform-specific library + * prefix, path, and file extension, indicates a library whose name is, + * for example, L, and a native library called L is statically linked + * with the VM, then the JNI_OnLoad_L function exported by the library + * is invoked rather than attempting to load a dynamic library. + * A filename matching the argument does not have to exist in the + * file system. + * See the JNI Specification for more details. + * + * Otherwise, the filename argument is mapped to a native library image in + * an implementation-dependent manner. + * *

* The call System.load(name) is effectively equivalent * to the call: @@ -1051,7 +1063,10 @@ public final class System { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the file does not exist. + * @exception UnsatisfiedLinkError if either the filename is not an + * absolute path name, the native library is not statically + * linked with the VM, or the library cannot be mapped to + * a native library image by the host system. * @exception NullPointerException if filename is * null * @see java.lang.Runtime#load(java.lang.String) @@ -1062,9 +1077,16 @@ public final class System { } /** - * Loads the system library specified by the libname - * argument. The manner in which a library name is mapped to the - * actual system library is system dependent. + * Loads the native library specified by the libname + * argument. The libname argument must not contain any platform + * specific prefix, file extension or path. If a native library + * called libname is statically linked with the VM, then the + * JNI_OnLoad_libname function exported by the library is invoked. + * See the JNI Specification for more details. + * + * Otherwise, the libname argument is loaded from a system library + * location and mapped to a native library image in an implementation- + * dependent manner. *

* The call System.loadLibrary(name) is effectively * equivalent to the call @@ -1076,7 +1098,10 @@ public final class System { * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library - * @exception UnsatisfiedLinkError if the library does not exist. + * @exception UnsatisfiedLinkError if either the libname argument + * contains a file path, the native library is not statically + * linked with the VM, or the library cannot be mapped to a + * native library image by the host system. * @exception NullPointerException if libname is * null * @see java.lang.Runtime#loadLibrary(java.lang.String) diff --git a/jdk/src/share/javavm/export/jni.h b/jdk/src/share/javavm/export/jni.h index dc2c8f645f2..2e83cb7e06e 100644 --- a/jdk/src/share/javavm/export/jni.h +++ b/jdk/src/share/javavm/export/jni.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1951,6 +1951,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved); #define JNI_VERSION_1_2 0x00010002 #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 #ifdef __cplusplus } /* extern "C" */ diff --git a/jdk/src/share/native/common/jni_util.h b/jdk/src/share/native/common/jni_util.h index 55dd0fa91d8..65cabb7dd63 100644 --- a/jdk/src/share/native/common/jni_util.h +++ b/jdk/src/share/native/common/jni_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2004, 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 @@ -339,6 +339,10 @@ int getFastEncoding(); void initializeEncoding(); +void* getProcessHandle(); + +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName); #ifdef __cplusplus } /* extern "C" */ diff --git a/jdk/src/share/native/java/lang/ClassLoader.c b/jdk/src/share/native/java/lang/ClassLoader.c index 8965d0a86d7..47c41b2bd84 100644 --- a/jdk/src/share/native/java/lang/ClassLoader.c +++ b/jdk/src/share/native/java/lang/ClassLoader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -32,6 +32,7 @@ #include "jvm.h" #include "java_lang_ClassLoader.h" #include "java_lang_ClassLoader_NativeLibrary.h" +#include /* defined in libverify.so/verify.dll (src file common/check_format.c) */ extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed); @@ -286,6 +287,8 @@ Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, static jfieldID handleID; static jfieldID jniVersionID; +static jfieldID loadedID; +static void *procHandle; static jboolean initIDs(JNIEnv *env) { @@ -300,6 +303,10 @@ static jboolean initIDs(JNIEnv *env) jniVersionID = (*env)->GetFieldID(env, this, "jniVersion", "I"); if (jniVersionID == 0) return JNI_FALSE; + loadedID = (*env)->GetFieldID(env, this, "loaded", "Z"); + if (loadedID == 0) + return JNI_FALSE; + procHandle = getProcessHandle(); } return JNI_TRUE; } @@ -307,14 +314,60 @@ static jboolean initIDs(JNIEnv *env) typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *); typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *); +/* + * Support for finding JNI_On(Un)Load_ if it exists. + * If cname == NULL then just find normal JNI_On(Un)Load entry point + */ +static void *findJniFunction(JNIEnv *env, void *handle, + const char *cname, jboolean isLoad) { + const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; + const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; + const char **syms; + int symsLen; + void *entryName = NULL; + char *jniFunctionName; + int i; + int len; + + // Check for JNI_On(Un)Load<_libname> function + if (isLoad) { + syms = onLoadSymbols; + symsLen = sizeof(onLoadSymbols) / sizeof(char *); + } else { + syms = onUnloadSymbols; + symsLen = sizeof(onUnloadSymbols) / sizeof(char *); + } + for (i = 0; i < symsLen; i++) { + // cname + sym + '_' + '\0' + if ((len = (cname != NULL ? strlen(cname) : 0) + strlen(syms[i]) + 2) > + FILENAME_MAX) { + goto done; + } + jniFunctionName = malloc(len); + if (jniFunctionName == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + goto done; + } + buildJniFunctionName(syms[i], cname, jniFunctionName); + entryName = JVM_FindLibraryEntry(handle, jniFunctionName); + free(jniFunctionName); + if(entryName) { + break; + } + } + + done: + return entryName; +} + /* * Class: java_lang_ClassLoader_NativeLibrary * Method: load - * Signature: (Ljava/lang/String;)J + * Signature: (Ljava/lang/String;Z)V */ JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_load - (JNIEnv *env, jobject this, jstring name) + (JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) { const char *cname; jint jniVersion; @@ -327,18 +380,12 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load cname = JNU_GetStringPlatformChars(env, name, 0); if (cname == 0) return; - handle = JVM_LoadLibrary(cname); + handle = isBuiltin ? procHandle : JVM_LoadLibrary(cname); if (handle) { - const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; JNI_OnLoad_t JNI_OnLoad; - unsigned int i; - for (i = 0; i < sizeof(onLoadSymbols) / sizeof(char *); i++) { - JNI_OnLoad = (JNI_OnLoad_t) - JVM_FindLibraryEntry(handle, onLoadSymbols[i]); - if (JNI_OnLoad) { - break; - } - } + JNI_OnLoad = (JNI_OnLoad_t)findJniFunction(env, handle, + isBuiltin ? cname : NULL, + JNI_TRUE); if (JNI_OnLoad) { JavaVM *jvm; (*env)->GetJavaVM(env, &jvm); @@ -355,7 +402,8 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load goto done; } - if (!JVM_IsSupportedJNIVersion(jniVersion)) { + if (!JVM_IsSupportedJNIVersion(jniVersion) || + (isBuiltin && jniVersion < JNI_VERSION_1_8)) { char msg[256]; jio_snprintf(msg, sizeof(msg), "unsupported JNI version 0x%08X required by %s", @@ -375,6 +423,7 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load goto done; } (*env)->SetLongField(env, this, handleID, ptr_to_jlong(handle)); + (*env)->SetBooleanField(env, this, loadedID, JNI_TRUE); done: JNU_ReleaseStringPlatformChars(env, name, cname); @@ -383,41 +432,40 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load /* * Class: java_lang_ClassLoader_NativeLibrary * Method: unload - * Signature: ()V + * Signature: (Z)V */ JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_unload - (JNIEnv *env, jobject this) +(JNIEnv *env, jobject this, jstring name, jboolean isBuiltin) { const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; void *handle; JNI_OnUnload_t JNI_OnUnload; - unsigned int i; + const char *cname; if (!initIDs(env)) return; - - handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); - for (i = 0; i < sizeof(onUnloadSymbols) / sizeof(char *); i++) { - JNI_OnUnload = (JNI_OnUnload_t ) - JVM_FindLibraryEntry(handle, onUnloadSymbols[i]); - if (JNI_OnUnload) { - break; - } + cname = JNU_GetStringPlatformChars(env, name, 0); + if (cname == NULL) { + return; } - + handle = jlong_to_ptr((*env)->GetLongField(env, this, handleID)); + JNI_OnUnload = (JNI_OnUnload_t )findJniFunction(env, handle, + isBuiltin ? cname : NULL, + JNI_FALSE); if (JNI_OnUnload) { JavaVM *jvm; (*env)->GetJavaVM(env, &jvm); (*JNI_OnUnload)(jvm, NULL); } JVM_UnloadLibrary(handle); + JNU_ReleaseStringPlatformChars(env, name, cname); } /* * Class: java_lang_ClassLoader_NativeLibrary * Method: find - * Signature: (Ljava/lang/String;J)J + * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_find @@ -456,3 +504,63 @@ Java_java_lang_ClassLoader_getCaller(JNIEnv *env, jclass cls, jint index) return NULL; } +/* + * Class: java_lang_ClassLoader_NativeLibrary + * Method: findBuiltinLib + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib + (JNIEnv *env, jclass cls, jstring name) +{ + const char *cname; + char *libName; + int prefixLen = (int) strlen(JNI_LIB_PREFIX); + int suffixLen = (int) strlen(JNI_LIB_SUFFIX); + int len; + jstring lib; + void *ret; + const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; + + if (name == NULL) { + JNU_ThrowInternalError(env, "NULL filename for native library"); + return NULL; + } + // Can't call initIDs because it will recurse into NativeLibrary via + // FindClass to check context so set prochandle here as well. + procHandle = getProcessHandle(); + cname = JNU_GetStringPlatformChars(env, name, 0); + if (cname == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; + } + // Copy name Skipping PREFIX + len = strlen(cname); + if (len <= (prefixLen+suffixLen)) { + JNU_ReleaseStringPlatformChars(env, name, cname); + return NULL; + } + libName = malloc(len + 1); //+1 for null if prefix+suffix == 0 + if (libName == NULL) { + JNU_ReleaseStringPlatformChars(env, name, cname); + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; + } + if (len > prefixLen) { + strcpy(libName, cname+prefixLen); + } + JNU_ReleaseStringPlatformChars(env, name, cname); + + // Strip SUFFIX + libName[strlen(libName)-suffixLen] = '\0'; + + // Check for JNI_OnLoad_libname function + ret = findJniFunction(env, procHandle, libName, JNI_TRUE); + if (ret != NULL) { + lib = JNU_NewStringPlatform(env, libName); + free(libName); + return lib; + } + free(libName); + return NULL; +} diff --git a/jdk/src/solaris/native/common/jni_util_md.c b/jdk/src/solaris/native/common/jni_util_md.c index dc9fb9956e0..e9e0f4e0f3f 100644 --- a/jdk/src/solaris/native/common/jni_util_md.c +++ b/jdk/src/solaris/native/common/jni_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,7 @@ #include "jni.h" #include "jni_util.h" +#include "dlfcn.h" jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { return NULL; @@ -33,3 +34,22 @@ jstring nativeNewStringPlatform(JNIEnv *env, const char *str) { char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) { return NULL; } + +void* getProcessHandle() { + static void *procHandle = NULL; + if (procHandle != NULL) { + return procHandle; + } + procHandle = (void*)dlopen(NULL, RTLD_LAZY); + return procHandle; +} + +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName) { + strcpy(jniEntryName, sym); + if (cname != NULL) { + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + } +} + diff --git a/jdk/src/windows/native/common/jni_util_md.c b/jdk/src/windows/native/common/jni_util_md.c index 5b90a59ceea..cdaaa2b5574 100644 --- a/jdk/src/windows/native/common/jni_util_md.c +++ b/jdk/src/windows/native/common/jni_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -137,3 +137,35 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) else return NULL; } + +void* getProcessHandle() { + return (void*)GetModuleHandle(NULL); +} + +/* + * Windows symbols can be simple like JNI_OnLoad or __stdcall format + * like _JNI_OnLoad@8. We need to handle both. + */ +void buildJniFunctionName(const char *sym, const char *cname, + char *jniEntryName) { + if (cname != NULL) { + char *p = strrchr(sym, '@'); + if (p != NULL && p != sym) { + // sym == _JNI_OnLoad@8 + strncpy(jniEntryName, sym, (p - sym)); + jniEntryName[(p-sym)] = '\0'; + // jniEntryName == _JNI_OnLoad + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + strcat(jniEntryName, p); + //jniEntryName == _JNI_OnLoad_cname@8 + } else { + strcpy(jniEntryName, sym); + strcat(jniEntryName, "_"); + strcat(jniEntryName, cname); + } + } else { + strcpy(jniEntryName, sym); + } + return; +} From a7f501c6208e45686a3fa0b77be14d9bedc45716 Mon Sep 17 00:00:00 2001 From: Yiming Wang Date: Thu, 14 Mar 2013 16:59:06 +0000 Subject: [PATCH 019/137] 7183800: TEST_BUG: Update tests to run on Ubuntu 12.04 (localhost is 127.0.1.1) Reviewed-by: alanb, chegar --- .../nio/channels/DatagramChannel/Connect.java | 4 ++++ .../DatagramChannel/ConnectedSend.java | 18 +++++++++++++----- .../inheritedChannel/Launcher.java | 7 +++++-- .../connection/RMIConnectionIdTest.java | 4 ++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/jdk/test/java/nio/channels/DatagramChannel/Connect.java b/jdk/test/java/nio/channels/DatagramChannel/Connect.java index 5fac928b092..558f0321ee9 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/Connect.java +++ b/jdk/test/java/nio/channels/DatagramChannel/Connect.java @@ -22,6 +22,7 @@ */ /* @test + * @bug 4313882 7183800 * @summary Test DatagramChannel's send and receive methods * @author Mike McCloskey */ @@ -88,6 +89,9 @@ public class Connect { bb.put("hello".getBytes()); bb.flip(); InetAddress address = InetAddress.getLocalHost(); + if (address.isLoopbackAddress()) { + address = InetAddress.getLoopbackAddress(); + } InetSocketAddress isa = new InetSocketAddress(address, port); dc.connect(isa); dc.write(bb); diff --git a/jdk/test/java/nio/channels/DatagramChannel/ConnectedSend.java b/jdk/test/java/nio/channels/DatagramChannel/ConnectedSend.java index 9ac48eddf8d..1f56e516569 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/ConnectedSend.java +++ b/jdk/test/java/nio/channels/DatagramChannel/ConnectedSend.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4849277 + * @bug 4849277 7183800 * @summary Test DatagramChannel send while connected * @author Mike McCloskey */ @@ -46,14 +46,18 @@ public class ConnectedSend { DatagramChannel sndChannel = DatagramChannel.open(); sndChannel.socket().bind(null); + InetAddress address = InetAddress.getLocalHost(); + if (address.isLoopbackAddress()) { + address = InetAddress.getLoopbackAddress(); + } InetSocketAddress sender = new InetSocketAddress( - InetAddress.getLocalHost(), + address, sndChannel.socket().getLocalPort()); DatagramChannel rcvChannel = DatagramChannel.open(); rcvChannel.socket().bind(null); InetSocketAddress receiver = new InetSocketAddress( - InetAddress.getLocalHost(), + address, rcvChannel.socket().getLocalPort()); rcvChannel.connect(sender); @@ -80,14 +84,18 @@ public class ConnectedSend { private static void test2() throws Exception { DatagramChannel sndChannel = DatagramChannel.open(); sndChannel.socket().bind(null); + InetAddress address = InetAddress.getLocalHost(); + if (address.isLoopbackAddress()) { + address = InetAddress.getLoopbackAddress(); + } InetSocketAddress sender = new InetSocketAddress( - InetAddress.getLocalHost(), + address, sndChannel.socket().getLocalPort()); DatagramChannel rcvChannel = DatagramChannel.open(); rcvChannel.socket().bind(null); InetSocketAddress receiver = new InetSocketAddress( - InetAddress.getLocalHost(), + address, rcvChannel.socket().getLocalPort()); rcvChannel.connect(sender); diff --git a/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java b/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java index 834a9637df5..d8c88ffe0e5 100644 --- a/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java +++ b/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java @@ -133,8 +133,11 @@ public class Launcher { dc.close(); dc = DatagramChannel.open(); - - InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port); + InetAddress address = InetAddress.getLocalHost(); + if (address.isLoopbackAddress()) { + address = InetAddress.getLoopbackAddress(); + } + InetSocketAddress isa = new InetSocketAddress(address, port); dc.connect(isa); return dc; diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectionIdTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectionIdTest.java index 7de3c1a5aeb..c392f11bd54 100644 --- a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectionIdTest.java +++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectionIdTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4901808 + * @bug 4901808 7183800 * @summary Check that RMI connection ids include client host name * @author Eamonn McManus * @run clean RMIConnectionIdTest @@ -60,7 +60,7 @@ public class RMIConnectionIdTest { } String clientAddr = rest.substring(0, spaceIndex); InetAddress clientInetAddr = InetAddress.getByName(clientAddr); - InetAddress localAddr = InetAddress.getLocalHost(); + InetAddress localAddr = clientInetAddr.isLoopbackAddress() ? InetAddress.getLoopbackAddress() : InetAddress.getLocalHost(); System.out.println("InetAddresses: local=" + localAddr + "; " + "connectionId=" + clientInetAddr); if (!localAddr.equals(clientInetAddr)) { From 96ca9c41742d366b2c3cdf47796d753d802f626b Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Thu, 14 Mar 2013 11:29:16 -0700 Subject: [PATCH 020/137] 8008576: Calendar mismatch using Host LocaleProviderAdapter Reviewed-by: okutsu --- jdk/make/java/java/FILES_java.gmk | 2 + .../HostLocaleProviderAdapterImpl.java | 117 +++++++++++++----- jdk/src/share/classes/java/util/Calendar.java | 21 +++- .../classes/sun/util/locale/LanguageTag.java | 2 +- .../provider/AuxLocaleProviderAdapter.java | 9 ++ .../locale/provider/CalendarProviderImpl.java | 95 ++++++++++++++ .../provider/JRELocaleProviderAdapter.java | 24 ++++ .../provider/LocaleProviderAdapter.java | 14 ++- .../sun/util/spi/CalendarProvider.java | 64 ++++++++++ .../HostLocaleProviderAdapterImpl.java | 67 +++++----- .../provider/HostLocaleProviderAdapter_md.c | 14 ++- 11 files changed, 362 insertions(+), 67 deletions(-) create mode 100644 jdk/src/share/classes/sun/util/locale/provider/CalendarProviderImpl.java create mode 100644 jdk/src/share/classes/sun/util/spi/CalendarProvider.java diff --git a/jdk/make/java/java/FILES_java.gmk b/jdk/make/java/java/FILES_java.gmk index 189b9fcb7c2..8122bdf1aef 100644 --- a/jdk/make/java/java/FILES_java.gmk +++ b/jdk/make/java/java/FILES_java.gmk @@ -209,6 +209,7 @@ JAVA_JAVA_java = \ sun/util/locale/provider/CalendarDataProviderImpl.java \ sun/util/locale/provider/CalendarDataUtility.java \ sun/util/locale/provider/CalendarNameProviderImpl.java \ + sun/util/locale/provider/CalendarProviderImpl.java \ sun/util/locale/provider/CollationRules.java \ sun/util/locale/provider/CollatorProviderImpl.java \ sun/util/locale/provider/CurrencyNameProviderImpl.java \ @@ -232,6 +233,7 @@ JAVA_JAVA_java = \ sun/util/locale/provider/SPILocaleProviderAdapter.java \ sun/util/locale/provider/TimeZoneNameProviderImpl.java \ sun/util/locale/provider/TimeZoneNameUtility.java \ + sun/util/spi/CalendarProvider.java \ java/util/LocaleISOData.java \ sun/util/cldr/CLDRLocaleProviderAdapter.java \ java/util/MissingResourceException.java \ diff --git a/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java b/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java index f571512d30b..dfd5d4e8da4 100644 --- a/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java +++ b/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java @@ -32,11 +32,13 @@ import java.text.spi.DateFormatSymbolsProvider; import java.text.spi.DecimalFormatSymbolsProvider; import java.text.spi.NumberFormatProvider; import java.util.Collections; +import java.util.Calendar; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle.Control; import java.util.Set; +import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReferenceArray; @@ -45,6 +47,7 @@ import java.util.spi.CalendarNameProvider; import java.util.spi.CurrencyNameProvider; import java.util.spi.LocaleNameProvider; import java.util.spi.TimeZoneNameProvider; +import sun.util.spi.CalendarProvider; /** * LocaleProviderAdapter implementation for the Mac OS X locale data @@ -94,17 +97,56 @@ public class HostLocaleProviderAdapterImpl { private static final Set supportedLocaleSet; static { - Set tmpSet = new HashSet(); + Set tmpSet = new HashSet<>(); // Assuming the default locales do not include any extensions, so // no stripping is needed here. - Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-")); + Locale l = convertMacOSXLocaleToJavaLocale(getDefaultLocale(CAT_FORMAT)); tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); - l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-")); + l = convertMacOSXLocaleToJavaLocale(getDefaultLocale(CAT_DISPLAY)); tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); supportedLocaleSet = Collections.unmodifiableSet(tmpSet); } private final static Locale[] supportedLocale = supportedLocaleSet.toArray(new Locale[0]); + @SuppressWarnings("fallthrough") + private static Locale convertMacOSXLocaleToJavaLocale(String macosxloc) { + // MacOSX may return ICU notation, here is the quote from CFLocale doc: + // "The corresponding value is a CFString containing the POSIX locale + // identifier as used by ICU, such as "ja_JP". If you have a variant + // locale or a different currency or calendar, it can be as complex as + // "en_US_POSIX@calendar=japanese;currency=EUR" or + // "az_Cyrl_AZ@calendar=buddhist;currency=JPY". + String[] tmp = macosxloc.split("@"); + String langTag = tmp[0].replace('_', '-'); + if (tmp.length > 1) { + String[] ext = tmp[1].split(";"); + for (String keyval : ext) { + // We are only interested in "calendar" value for now. + if (keyval.startsWith("calendar=")) { + String calid = keyval.substring(keyval.indexOf('=')+1); + switch (calid) { + case "gregorian": + langTag += "-u-ca-gregory"; + break; + case "japanese": + // Tweak for ja_JP_JP + if (tmp[0].equals("ja_JP")) { + return JRELocaleConstants.JA_JP_JP; + } + + // fall through + + default: + langTag += "-u-ca-" + calid; + break; + } + } + } + } + + return Locale.forLanguageTag(langTag); + } + public static DateFormatProvider getDateFormatProvider() { return new DateFormatProvider() { @@ -170,9 +212,8 @@ public class HostLocaleProviderAdapterImpl { if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) { return supportedLocale; } - - return new Locale[0]; - } + return new Locale[0]; + } @Override public boolean isSupportedLocale(Locale locale) { @@ -362,6 +403,30 @@ public class HostLocaleProviderAdapterImpl { }; } + public static CalendarProvider getCalendarProvider() { + return new CalendarProvider() { + @Override + public Locale[] getAvailableLocales() { + return getSupportedCalendarLocales(); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return isSupportedCalendarLocale(locale); + } + + @Override + public Calendar getInstance(TimeZone zone, Locale locale) { + return new Calendar.Builder() + .setLocale(locale) + .setCalendarType(getCalendarID(locale.toLanguageTag())) + .setTimeZone(zone) + .setInstant(System.currentTimeMillis()) + .build(); + } + }; + } + public static CurrencyNameProvider getCurrencyNameProvider() { return new CurrencyNameProvider() { @Override @@ -455,23 +520,20 @@ public class HostLocaleProviderAdapterImpl { } private static boolean isSupportedCalendarLocale(Locale locale) { - // special case for ja_JP_JP - if (JRELocaleConstants.JA_JP_JP.equals(locale)) { - return isJapaneseCalendar(); - } - Locale base = locale.stripExtensions(); if (!supportedLocaleSet.contains(base)) { return false; } - String caltype = locale.getUnicodeLocaleType("ca"); - if (caltype == null) { - return true; - } + String requestedCalType = locale.getUnicodeLocaleType("ca"); + String nativeCalType = + getCalendarID(locale.toLanguageTag()).replaceFirst("gregorian", "gregory"); - return caltype.replaceFirst("gregory", "gregorian").equals( - getCalendarID(locale.toLanguageTag())); + if (requestedCalType == null) { + return Calendar.getAvailableCalendarTypes().contains(nativeCalType); + } else { + return requestedCalType.equals(nativeCalType); + } } private static boolean isJapaneseCalendar() { @@ -479,18 +541,15 @@ public class HostLocaleProviderAdapterImpl { } private static Locale getCalendarLocale(Locale locale) { - Locale.Builder lb = new Locale.Builder().setLocale(locale); - String calid = getCalendarID(locale.toLanguageTag()); - switch (calid) { - case "gregorian": - calid = "gregory"; - // FALL THROUGH! - case "japanese": - case "buddhist": - lb.setUnicodeLocaleKeyword("ca", calid); - return lb.build(); - default: - return locale; + String nativeCalType = getCalendarID(locale.toLanguageTag()) + .replaceFirst("gregorian", "gregory"); + if (Calendar.getAvailableCalendarTypes().contains(nativeCalType)) { + return new Locale.Builder() + .setLocale(locale) + .setUnicodeLocaleKeyword("ca", nativeCalType) + .build(); + } else { + return locale; } } diff --git a/jdk/src/share/classes/java/util/Calendar.java b/jdk/src/share/classes/java/util/Calendar.java index c57f50c59b3..19c3c8540a7 100644 --- a/jdk/src/share/classes/java/util/Calendar.java +++ b/jdk/src/share/classes/java/util/Calendar.java @@ -57,6 +57,8 @@ import java.util.concurrent.ConcurrentMap; import sun.util.BuddhistCalendar; import sun.util.calendar.ZoneInfo; import sun.util.locale.provider.CalendarDataUtility; +import sun.util.locale.provider.LocaleProviderAdapter; +import sun.util.spi.CalendarProvider; /** * The Calendar class is an abstract class that provides methods @@ -1608,9 +1610,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable langtags; + + public CalendarProviderImpl(LocaleProviderAdapter.Type type, Set langtags) { + this.type = type; + this.langtags = langtags; + } + + /** + * Returns an array of all locales for which this locale service provider + * can provide localized objects or names. + * + * @return An array of all locales for which this locale service provider + * can provide localized objects or names. + */ + @Override + public Locale[] getAvailableLocales() { + return LocaleProviderAdapter.toLocaleArray(langtags); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + // Support any locales. + return true; + } + + /** + * Returns a new Calendar instance for the + * specified locale. + * + * @param zone the time zone + * @param locale the desired locale + * @exception NullPointerException if locale is null + * @exception IllegalArgumentException if locale isn't + * one of the locales returned from + * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() + * getAvailableLocales()}. + * @return a Calendar instance. + * @see java.util.Calendar#getInstance(java.util.Locale) + */ + @Override + public Calendar getInstance(TimeZone zone, Locale locale) { + return new Calendar.Builder() + .setLocale(locale) + .setTimeZone(zone) + .setInstant(System.currentTimeMillis()) + .build(); + } + + @Override + public Set getAvailableLanguageTags() { + return langtags; + } +} diff --git a/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java b/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java index cd33bc2140d..beabfd1032a 100644 --- a/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java +++ b/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java @@ -34,10 +34,12 @@ import java.text.spi.DateFormatProvider; import java.text.spi.DateFormatSymbolsProvider; import java.text.spi.DecimalFormatSymbolsProvider; import java.text.spi.NumberFormatProvider; +import java.util.Calendar; import java.util.HashSet; import java.util.Locale; import java.util.Set; import java.util.StringTokenizer; +import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.spi.CalendarDataProvider; @@ -47,6 +49,7 @@ import java.util.spi.LocaleNameProvider; import java.util.spi.LocaleServiceProvider; import java.util.spi.TimeZoneNameProvider; import sun.util.resources.LocaleData; +import sun.util.spi.CalendarProvider; /** * LocaleProviderAdapter implementation for the legacy JRE locale data. @@ -104,6 +107,8 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R return (P) getCalendarDataProvider(); case "CalendarNameProvider": return (P) getCalendarNameProvider(); + case "CalendarProvider": + return (P) getCalendarProvider(); default: throw new InternalError("should not come down here"); } @@ -122,6 +127,8 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R private volatile CalendarDataProvider calendarDataProvider = null; private volatile CalendarNameProvider calendarNameProvider = null; + private volatile CalendarProvider calendarProvider = null; + /* * Getter methods for java.text.spi.* providers */ @@ -283,6 +290,23 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R return calendarNameProvider; } + /** + * Getter methods for sun.util.spi.* providers + */ + @Override + public CalendarProvider getCalendarProvider() { + if (calendarProvider == null) { + CalendarProvider provider = new CalendarProviderImpl(getAdapterType(), + getLanguageTagSet("CalendarData")); + synchronized (this) { + if (calendarProvider == null) { + calendarProvider = provider; + } + } + } + return calendarProvider; + } + @Override public LocaleResources getLocaleResources(Locale locale) { LocaleResources lr = localeResourcesMap.get(locale); diff --git a/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java index d7e32408cbc..fa5eac14ba0 100644 --- a/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java +++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java @@ -47,6 +47,7 @@ import java.util.spi.LocaleNameProvider; import java.util.spi.LocaleServiceProvider; import java.util.spi.TimeZoneNameProvider; import sun.util.cldr.CLDRLocaleProviderAdapter; +import sun.util.spi.CalendarProvider; /** * The LocaleProviderAdapter abstract class. @@ -295,7 +296,10 @@ public abstract class LocaleProviderAdapter { } if (type == Type.JRE) { String oldname = locale.toString().replace('_', '-'); - return langtags.contains(oldname); + return langtags.contains(oldname) || + "ja-JP-JP".equals(oldname) || + "th-TH-TH".equals(oldname) || + "no-NO-NY".equals(oldname); } return false; } @@ -422,6 +426,14 @@ public abstract class LocaleProviderAdapter { */ public abstract CalendarNameProvider getCalendarNameProvider(); + /** + * Returns a CalendarProvider for this LocaleProviderAdapter, or null if no + * CalendarProvider is available. + * + * @return a CalendarProvider + */ + public abstract CalendarProvider getCalendarProvider(); + public abstract LocaleResources getLocaleResources(Locale locale); public abstract Locale[] getAvailableLocales(); diff --git a/jdk/src/share/classes/sun/util/spi/CalendarProvider.java b/jdk/src/share/classes/sun/util/spi/CalendarProvider.java new file mode 100644 index 00000000000..7114aada72d --- /dev/null +++ b/jdk/src/share/classes/sun/util/spi/CalendarProvider.java @@ -0,0 +1,64 @@ +/* + * 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 sun.util.spi; + +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; +import java.util.spi.LocaleServiceProvider; + +/** + * An abstract class for service providers that + * provide instances of the + * {@link java.util.Calendar Calendar} class. + * + * @since 1.8 + */ +public abstract class CalendarProvider extends LocaleServiceProvider { + + /** + * Sole constructor. (For invocation by subclass constructors, typically + * implicit.) + */ + protected CalendarProvider() { + } + + /** + * Returns a new Calendar instance for the + * specified locale. + * + * @param zone the time zone + * @param locale the desired locale + * @exception NullPointerException if locale is null + * @exception IllegalArgumentException if locale isn't + * one of the locales returned from + * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() + * getAvailableLocales()}. + * @return a Calendar instance. + * @see java.util.Calendar#getInstance(java.util.Locale) + */ + public abstract Calendar getInstance(TimeZone zone, Locale locale); +} diff --git a/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java b/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java index a5666f6b6a9..afe980e88c5 100644 --- a/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java +++ b/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java @@ -35,17 +35,20 @@ import java.text.spi.DateFormatProvider; import java.text.spi.DateFormatSymbolsProvider; import java.text.spi.DecimalFormatSymbolsProvider; import java.text.spi.NumberFormatProvider; +import java.util.Calendar; import java.util.Collections; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle.Control; import java.util.Set; +import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.spi.CalendarDataProvider; import java.util.spi.CalendarNameProvider; +import sun.util.spi.CalendarProvider; /** * LocaleProviderdapter implementation for the Windows locale data. @@ -98,9 +101,9 @@ public class HostLocaleProviderAdapterImpl { if (initialize()) { // Assuming the default locales do not include any extensions, so // no stripping is needed here. - Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replaceAll("_","-")); + Locale l = Locale.forLanguageTag(getDefaultLocale(CAT_FORMAT).replace('_', '-')); tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); - l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replaceAll("_","-")); + l = Locale.forLanguageTag(getDefaultLocale(CAT_DISPLAY).replace('_', '-')); tmpSet.addAll(Control.getNoFallbackControl(Control.FORMAT_DEFAULT).getCandidateLocales("", l)); } supportedLocaleSet = Collections.unmodifiableSet(tmpSet); @@ -173,24 +176,12 @@ public class HostLocaleProviderAdapterImpl { @Override public Locale[] getAvailableLocales() { - if (isSupportedLocale(Locale.getDefault(Locale.Category.FORMAT))) { - return supportedLocale; - } - - return new Locale[0]; + return getSupportedCalendarLocales(); } @Override public boolean isSupportedLocale(Locale locale) { - // Only supports the locale with Gregorian calendar - if (supportedLocale.length != 0) { - int calid = getCalendarID(locale.toLanguageTag()); - if (calid > 0 && calid < calIDToLDML.length) { - return calIDToLDML[calid].startsWith("gregory"); - } - } - - return false; + return isSupportedCalendarLocale(locale); } @Override @@ -380,6 +371,29 @@ public class HostLocaleProviderAdapterImpl { }; } + public static CalendarProvider getCalendarProvider() { + return new CalendarProvider() { + @Override + public Locale[] getAvailableLocales() { + return getSupportedCalendarLocales(); + } + + @Override + public boolean isSupportedLocale(Locale locale) { + return isSupportedCalendarLocale(locale); + } + + @Override + public Calendar getInstance(TimeZone zone, Locale locale) { + return new Calendar.Builder() + .setLocale(getCalendarLocale(locale)) + .setTimeZone(zone) + .setInstant(System.currentTimeMillis()) + .build(); + } + }; + } + private static String convertDateTimePattern(String winPattern) { String ret = winPattern.replaceAll("dddd", "EEEE"); ret = ret.replaceAll("ddd", "EEE"); @@ -401,24 +415,21 @@ public class HostLocaleProviderAdapterImpl { } private static boolean isSupportedCalendarLocale(Locale locale) { - // special case for ja_JP_JP - if (JRELocaleConstants.JA_JP_JP.equals(locale)) { - return isJapaneseCalendar(); - } - Locale base = locale.stripExtensions(); if (!supportedLocaleSet.contains(base)) { return false; } - String caltype = locale.getUnicodeLocaleType("ca"); - if (caltype == null) { - return true; - } + String requestedCalType = locale.getUnicodeLocaleType("ca"); + String nativeCalType = + calIDToLDML[getCalendarID(locale.toLanguageTag())] + .replaceFirst("_.*", ""); // remove locale part. - return caltype.equals( - calIDToLDML[getCalendarID(locale.toLanguageTag())] - .replaceFirst("_.*", "")); + if (requestedCalType == null) { + return Calendar.getAvailableCalendarTypes().contains(nativeCalType); + } else { + return requestedCalType.equals(nativeCalType); + } } private static Locale[] getSupportedNativeDigitLocales() { diff --git a/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c b/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c index e507a6fb598..037ea5ee578 100644 --- a/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c +++ b/jdk/src/windows/native/sun/util/locale/provider/HostLocaleProviderAdapter_md.c @@ -611,7 +611,12 @@ JNIEXPORT jint JNICALL Java_sun_util_locale_provider_HostLocaleProviderAdapterIm int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buflen) { if (pGetLocaleInfoEx) { - return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen); + if (wcscmp(L"und", (LPWSTR)langtag) == 0) { + // defaults to "en" + return pGetLocaleInfoEx(L"en", type, data, buflen); + } else { + return pGetLocaleInfoEx((LPWSTR)langtag, type, data, buflen); + } } else { // If we ever wanted to support WinXP, we will need extra module from // MS... @@ -622,7 +627,12 @@ int getLocaleInfoWrapper(const jchar *langtag, LCTYPE type, LPWSTR data, int buf int getCalendarInfoWrapper(const jchar *langtag, CALID id, LPCWSTR reserved, CALTYPE type, LPWSTR data, int buflen, LPDWORD val) { if (pGetCalendarInfoEx) { - return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val); + if (wcscmp(L"und", (LPWSTR)langtag) == 0) { + // defaults to "en" + return pGetCalendarInfoEx(L"en", id, reserved, type, data, buflen, val); + } else { + return pGetCalendarInfoEx((LPWSTR)langtag, id, reserved, type, data, buflen, val); + } } else { // If we ever wanted to support WinXP, we will need extra module from // MS... From 79eaa97ca4893d8beae96c86b6fc21d4d7202b63 Mon Sep 17 00:00:00 2001 From: Krystal Mo Date: Thu, 14 Mar 2013 13:22:04 -0700 Subject: [PATCH 021/137] 8010116: Abstract_VM_Version::internal_vm_info_string() should recognize VS2010 and VS2012 Add cases for _MSC_VER == 1600 and 1700 Reviewed-by: zgu --- hotspot/src/share/vm/runtime/vm_version.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp index ef03c76f62b..322a5b6c03a 100644 --- a/hotspot/src/share/vm/runtime/vm_version.cpp +++ b/hotspot/src/share/vm/runtime/vm_version.cpp @@ -211,6 +211,10 @@ const char* Abstract_VM_Version::internal_vm_info_string() { #define HOTSPOT_BUILD_COMPILER "MS VC++ 8.0 (VS2005)" #elif _MSC_VER == 1500 #define HOTSPOT_BUILD_COMPILER "MS VC++ 9.0 (VS2008)" + #elif _MSC_VER == 1600 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)" + #elif _MSC_VER == 1700 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)" #else #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER) #endif From ccff3589627a87aca5c69642acdce4c3c33b9eba Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 15 Mar 2013 17:02:24 +0400 Subject: [PATCH 022/137] 8009221: [macosx] Two closed/javax/swing regression tests fail on MacOSX Reviewed-by: serb, alexp --- .../javax/swing/JMenu/4515762/bug4515762.java | 172 ++++++++++++++++++ .../swing/JRootPane/4670486/bug4670486.java | 145 +++++++++++++++ jdk/test/javax/swing/regtesthelpers/Util.java | 17 ++ 3 files changed, 334 insertions(+) create mode 100644 jdk/test/javax/swing/JMenu/4515762/bug4515762.java create mode 100644 jdk/test/javax/swing/JRootPane/4670486/bug4670486.java diff --git a/jdk/test/javax/swing/JMenu/4515762/bug4515762.java b/jdk/test/javax/swing/JMenu/4515762/bug4515762.java new file mode 100644 index 00000000000..cb86ac168fa --- /dev/null +++ b/jdk/test/javax/swing/JMenu/4515762/bug4515762.java @@ -0,0 +1,172 @@ +/* + * 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.awt.*; +import java.awt.event.*; +import javax.swing.*; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 4515762 + * @author Mark Davidson + * @summary Tests the ability to support duplicate mnemonics + * @library ../../regtesthelpers + * @build Util + * @run main bug4515762 + */ +public class bug4515762 { + + private static volatile boolean actionExpected = false; + private static volatile boolean actionRecieved = false; + + /** + * @param str name of Menu + */ + private static JMenuBar createMenuBar() { + JMenuBar menubar = new JMenuBar(); + + // Duplicate menu item test for 4515762 + JMenu menu = new JMenu("Duplicate Menu"); + menu.setMnemonic('D'); + menu.add(createMenuItem("Sunday", 'S')); + menu.add(createMenuItem("Monday", 'M')); + + menu.add(createMenuItem("Tuesday", 'S')); + menu.add(createMenuItem("Wednesday", 'S')); + menu.add(createMenuItem("Thursday", 'S')); + menu.add(createMenuItem("Friday", 'F')); + menu.add(createMenuItem("Saturday", 'S')); + + // Control with unique menu + JMenu menu2 = new JMenu("Unique Menu"); + menu2.setMnemonic('U'); + menu2.add(createMenuItem("Sunday", 'S')); + menu2.add(createMenuItem("Monday", 'M')); + + menu2.add(createMenuItem("Tuesday", 'T')); + menu2.add(createMenuItem("Wednesday", 'W')); + menu2.add(createMenuItem("Thursday", 'U')); + menu2.add(createMenuItem("Friday", 'F')); + menu2.add(createMenuItem("Saturday", 'A')); + + menubar.add(menu); + menubar.add(menu2); + + return menubar; + } + + /** + * Creates and returns the menu item. + */ + private static JMenuItem createMenuItem(String name, char mnemonic) { + JMenuItem menuItem = new JMenuItem(name, mnemonic); + menuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent evt) { + JMenuItem item = (JMenuItem) evt.getSource(); + if (actionExpected == false) { + throw new RuntimeException("Menu Action: " + + item.getText() + " should not be called"); + } else { + actionRecieved = true; + } + } + }); + + return menuItem; + } + + public static void checkAction() { + if (actionRecieved == true) { + actionRecieved = false; + } else { + throw new RuntimeException("Action has not been received"); + } + } + + public static void main(String[] args) throws Throwable { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(250); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + JFrame frame = new JFrame("Test"); + frame.setJMenuBar(createMenuBar()); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + }); + + toolkit.realSync(); + + Util.hitMnemonics(robot, KeyEvent.VK_D); + toolkit.realSync(); + + // Press the S key many times (should not cause an action peformed) + int TIMES = 5; + for (int i = 0; i < TIMES; i++) { + Util.hitKeys(robot, KeyEvent.VK_S); + } + toolkit.realSync(); + + // Unique menu items. + actionExpected = true; + Util.hitMnemonics(robot, KeyEvent.VK_U); + + robot.keyPress(KeyEvent.VK_S); + robot.keyRelease(KeyEvent.VK_S); + toolkit.realSync(); + + checkAction(); + + Util.hitMnemonics(robot, KeyEvent.VK_U); + robot.keyPress(KeyEvent.VK_M); + robot.keyRelease(KeyEvent.VK_M); + toolkit.realSync(); + + checkAction(); + + Util.hitMnemonics(robot, KeyEvent.VK_U); + Util.hitKeys(robot, KeyEvent.VK_T); + toolkit.realSync(); + + checkAction(); + Util.hitMnemonics(robot, KeyEvent.VK_U); + Util.hitKeys(robot, KeyEvent.VK_W); + toolkit.realSync(); + + checkAction(); + + Util.hitMnemonics(robot, KeyEvent.VK_U); + Util.hitKeys(robot, KeyEvent.VK_U); + toolkit.realSync(); + + checkAction(); + } +} diff --git a/jdk/test/javax/swing/JRootPane/4670486/bug4670486.java b/jdk/test/javax/swing/JRootPane/4670486/bug4670486.java new file mode 100644 index 00000000000..6682f8afccf --- /dev/null +++ b/jdk/test/javax/swing/JRootPane/4670486/bug4670486.java @@ -0,0 +1,145 @@ +/* + * 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.awt.*; +import java.awt.event.*; +import javax.swing.*; +import sun.awt.SunToolkit; + +/** + * @test + * @bug 4670486 + * @author Mark Davidson + * @summary Regression: Popup menu bindings doesn't work when a default button has been defined. + * @library ../../regtesthelpers + * @build Util + * @run main bug4670486 + */ +public class bug4670486 { + + public static volatile boolean actionExpected = false; + public static volatile boolean actionRecieved = false; + + private static JMenuBar createMenuBar() { + JMenuBar menubar = new JMenuBar(); + + // Control with unique menu + JMenu menu = new JMenu("Unique Menu"); + menu.setMnemonic('U'); + menu.add(createMenuItem("Sunday", 'S')); + menu.add(createMenuItem("Monday", 'M')); + + menu.add(createMenuItem("Tuesday", 'T')); + menu.add(createMenuItem("Wednesday", 'W')); + menu.add(createMenuItem("Thursday", 'U')); + menu.add(createMenuItem("Friday", 'F')); + menu.add(createMenuItem("Saturday", 'A')); + + menubar.add(menu); + + return menubar; + } + + private static JPanel createPanel(JFrame frame) { + JPanel panel = new JPanel(); + JButton button = new JButton("Button"); + JButton button2 = new JButton("Button 2"); + JButton button3 = new JButton("Button 3"); + + JRootPane root = frame.getRootPane(); + root.setDefaultButton(button); + + panel.add(button); + panel.add(button2); + panel.add(button3); + + return panel; + } + + /** + * Creates and returns the menu item. + */ + private static JMenuItem createMenuItem(String name, char mnemonic) { + JMenuItem menuItem = new JMenuItem(name, mnemonic); + menuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent evt) { + actionRecieved = true; + } + }); + + return menuItem; + } + + public static void checkAction() { + if (actionRecieved == true) { + actionRecieved = false; + } else { + throw new RuntimeException("Action has not been received"); + } + } + + public static void main(String[] args) throws Throwable { + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(250); + + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + JFrame frame = new JFrame("Test"); + frame.setContentPane(createPanel(frame)); + frame.setJMenuBar(createMenuBar()); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + }); + + toolkit.realSync(); + + // Change the default button to + // force a call to BasicRootPaneUI.updateDefaultButtonBindings() + Util.hitKeys(robot, KeyEvent.VK_TAB); + + // If the bug exists, then as soon as the menu appears, + // the VK_ENTER, VK_DOWN, VK_UP and VK_ESC will have no + // effect. + Util.hitMnemonics(robot, KeyEvent.VK_U); + Util.hitKeys(robot, KeyEvent.VK_ENTER); + toolkit.realSync(); + + checkAction(); + + Util.hitMnemonics(robot, KeyEvent.VK_U); + Util.hitKeys(robot, KeyEvent.VK_DOWN); + Util.hitKeys(robot, KeyEvent.VK_ENTER); + toolkit.realSync(); + + checkAction(); + } +} diff --git a/jdk/test/javax/swing/regtesthelpers/Util.java b/jdk/test/javax/swing/regtesthelpers/Util.java index df7ab7ade80..33460714003 100644 --- a/jdk/test/javax/swing/regtesthelpers/Util.java +++ b/jdk/test/javax/swing/regtesthelpers/Util.java @@ -145,6 +145,23 @@ public class Util { return null; } + /** + * Hits mnemonics by robot. + */ + public static void hitMnemonics(Robot robot, int... keys) { + + ArrayList mnemonicKeyCodes = getSystemMnemonicKeyCodes(); + for (Integer mnemonic : mnemonicKeyCodes) { + robot.keyPress(mnemonic); + } + + hitKeys(robot, keys); + + for (Integer mnemonic : mnemonicKeyCodes) { + robot.keyRelease(mnemonic); + } + } + /** * Hits keys by robot. */ From e05970ca52edee6f3dfcb61f82754c2d5523328c Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Fri, 15 Mar 2013 16:07:13 +0100 Subject: [PATCH 023/137] 8010147: Forgot to add EXPECTED files for lazy and eager sunspider test Reviewed-by: sundar, jlaskey --- .../{runsunspider.js.EXPECTED => runsunspider-eager.js.EXPECTED} | 0 nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED | 1 + 2 files changed, 1 insertion(+) rename nashorn/test/script/basic/{runsunspider.js.EXPECTED => runsunspider-eager.js.EXPECTED} (100%) create mode 100644 nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED diff --git a/nashorn/test/script/basic/runsunspider.js.EXPECTED b/nashorn/test/script/basic/runsunspider-eager.js.EXPECTED similarity index 100% rename from nashorn/test/script/basic/runsunspider.js.EXPECTED rename to nashorn/test/script/basic/runsunspider-eager.js.EXPECTED diff --git a/nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED b/nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED new file mode 100644 index 00000000000..dd360839514 --- /dev/null +++ b/nashorn/test/script/basic/runsunspider-lazy.js.EXPECTED @@ -0,0 +1 @@ +Sunspider finished! From 10a02b0e2c08760592e8ce0f7ab7fc0f25b190c0 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Fri, 15 Mar 2013 11:53:28 -0400 Subject: [PATCH 024/137] 8009614: nsk/split_verifier/stress/ifelse/ifelse002_30 fails with 'assert((size & (granularity - 1)) == 0) failed: size not aligned to os::vm_allocation_granularity() Align up vm allocation size to os defined granularity Reviewed-by: dholmes, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 7853b3d51f1..2c4d865342f 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -334,6 +334,9 @@ class VirtualSpaceNode : public CHeapObj { // byte_size is the size of the associated virtualspace. VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(0) { + // align up to vm allocation granularity + byte_size = align_size_up(byte_size, os::vm_allocation_granularity()); + // This allocates memory with mmap. For DumpSharedspaces, allocate the // space at low memory so that other shared images don't conflict. // This is the same address as memory needed for UseCompressedOops but From 5aea724d29eb99d92d46cb28be8aebeafb91d7f3 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 15 Mar 2013 21:52:40 +0530 Subject: [PATCH 025/137] 8010145: removed workaround "init.js" in nashorn repo Reviewed-by: jlaskey, lagergren --- .../jdk/nashorn/api/scripting/Formatter.java | 10 +- .../api/scripting/NashornScriptEngine.java | 8 - .../nashorn/api/scripting/ScriptUtils.java | 12 + .../nashorn/api/scripting/resources/engine.js | 46 + .../nashorn/api/scripting/resources/init.js | 939 ------------------ 5 files changed, 63 insertions(+), 952 deletions(-) delete mode 100644 nashorn/src/jdk/nashorn/api/scripting/resources/init.js diff --git a/nashorn/src/jdk/nashorn/api/scripting/Formatter.java b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java index 3b47d3479e4..5cb19ed47af 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/Formatter.java +++ b/nashorn/src/jdk/nashorn/api/scripting/Formatter.java @@ -46,7 +46,7 @@ import java.util.regex.Pattern; *

Pattern and the logic for parameter position: java.util.Formatter * */ -public final class Formatter { +final class Formatter { private Formatter() { } @@ -59,8 +59,8 @@ public final class Formatter { * @param args arguments referenced by the format specifiers in format * @return a formatted string */ - public static String format(final String format, final Object[] args) { - Matcher m = FS_PATTERN.matcher(format); + static String format(final String format, final Object[] args) { + final Matcher m = FS_PATTERN.matcher(format); int positionalParameter = 1; while (m.find()) { @@ -143,7 +143,7 @@ public final class Formatter { /** * Method to parse the integer of the argument index. * - * @param s + * @param s string to parse * @return -1 if parsing failed, 0 if string is null, > 0 integer */ private static int index(final String s) { @@ -166,7 +166,7 @@ public final class Formatter { * Method to check if a string contains '<'. This is used to find out if * previous parameter is used. * - * @param s + * @param s string to check * @return true if '<' is in the string, else false */ private static boolean isPreviousArgument(final String s) { diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index ce16a7e82d0..4fa6033c11f 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -394,14 +394,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C setContextVariables(ctxt); final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); final String fileName = (val != null) ? val.toString() : ""; - - // NOTE: FIXME: If this is jrunscript's init.js, we want to run the replacement. - // This should go away once we fix jrunscript's copy of init.js. - if ("".equals(fileName)) { - evalSupportScript("resources/init.js", "nashorn:engine/resources/init.js"); - return null; - } - Object res = ScriptRuntime.apply(script, ctxtGlobal); return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(res, ctxtGlobal)); } catch (final Exception e) { diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java index 63358bd7db9..ccd5879b3f9 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java @@ -45,4 +45,16 @@ public final class ScriptUtils { public static String parse(final String code, final String name, final boolean includeLoc) { return ScriptRuntime.parse(code, name, includeLoc); } + + /** + * Method which converts javascript types to java types for the + * String.format method (jrunscript function sprintf). + * + * @param format a format string + * @param args arguments referenced by the format specifiers in format + * @return a formatted string + */ + public static String format(final String format, final Object[] args) { + return Formatter.format(format, args); + } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js index 65b82dfe797..e95607287d4 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js +++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js @@ -46,3 +46,49 @@ function print(str) { } writer.println(String(str)); } + +/** + * This is C-like printf + * + * @param format string to format the rest of the print items + * @param args variadic argument list + */ +Object.defineProperty(this, "printf", { + configurable: true, + enumerable: false, + writable: true, + value: function (format, args/*, more args*/) { + print(sprintf.apply(this, arguments)); + } +}); + +/** + * This is C-like sprintf + * + * @param format string to format the rest of the print items + * @param args variadic argument list + */ +Object.defineProperty(this, "sprintf", { + configurable: true, + enumerable: false, + writable: true, + value: function (format, args/*, more args*/) { + var len = arguments.length - 1; + var array = []; + + if (len < 0) { + return ""; + } + + for (var i = 0; i < len; i++) { + if (arguments[i+1] instanceof Date) { + array[i] = arguments[i+1].getTime(); + } else { + array[i] = arguments[i+1]; + } + } + + array = Java.toJavaArray(array); + return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array); + } +}); diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/init.js b/nashorn/src/jdk/nashorn/api/scripting/resources/init.js deleted file mode 100644 index 18cde929451..00000000000 --- a/nashorn/src/jdk/nashorn/api/scripting/resources/init.js +++ /dev/null @@ -1,939 +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. - */ - -/** - * jrunscript JavaScript built-in functions and objects. - */ - -/** - * Creates an object that delegates all method calls on - * it to the 'invoke' method on the given delegate object.
- * - * Example: - *

- * 
- *     var x  = { invoke: function(name, args) { //code...}
- *     var y = new JSInvoker(x);
- *     y.func(3, 3); // calls x.invoke('func', args); where args is array of arguments
- * 
- * 
- * @param obj object to be wrapped by JSInvoker - * @constructor - */ -function JSInvoker(obj) { - return new JSAdapter({ - __get__ : function(name) { - return function() { - return obj.invoke(name, arguments); - } - } - }); -} - -/** - * This variable represents OS environment. Environment - * variables can be accessed as fields of this object. For - * example, env.PATH will return PATH value configured. - */ -var env = new JSAdapter({ - __get__ : function (name) { - return java.lang.System.getenv(name); - }, - __has__ : function (name) { - return java.lang.System.getenv().containsKey(name); - }, - __getIds__ : function() { - return java.lang.System.getenv().keySet().toArray(); - }, - __delete__ : function(name) { - println("can't delete env item"); - }, - __put__ : function (name, value) { - println("can't change env item"); - }, - toString: function() { - return java.lang.System.getenv().toString(); - } -}); - -/** - * Creates a convenient script object to deal with java.util.Map instances. - * The result script object's field names are keys of the Map. For example, - * scriptObj.keyName can be used to access value associated with given key.
- * Example: - *
- * 
- *     var x = java.lang.SystemProperties();
- *     var y = jmap(x);
- *     println(y['java.class.path']); // prints java.class.path System property
- *     delete y['java.class.path']; // remove java.class.path System property
- * 
- * 
- * - * @param map java.util.Map instance that will be wrapped - * @constructor - */ -function jmap(map) { - return new JSAdapter({ - __get__ : function(name) { - if (map.containsKey(name)) { - return map.get(name); - } else { - return undefined; - } - }, - __has__ : function(name) { - return map.containsKey(name); - }, - - __delete__ : function (name) { - return map.remove(name); - }, - __put__ : function(name, value) { - map.put(name, value); - }, - __getIds__ : function() { - return map.keySet().toArray(); - }, - toString: function() { - return map.toString(); - } - }); -} - -/** - * Creates a convenient script object to deal with java.util.List instances. - * The result script object behaves like an array. For example, - * scriptObj[index] syntax can be used to access values in the List instance. - * 'length' field gives size of the List.
- * - * Example: - *
- * 
- *    var x = new java.util.ArrayList(4);
- *    x.add('Java');
- *    x.add('JavaScript');
- *    x.add('SQL');
- *    x.add('XML');
- *
- *    var y = jlist(x);
- *    println(y[2]); // prints third element of list
- *    println(y.length); // prints size of the list
- *
- * @param map java.util.List instance that will be wrapped
- * @constructor
- */
-function jlist(list) {
-    function isValid(index) {
-        return typeof(index) == 'number' &&
-            index > -1 && index < list.size();
-    }
-    return new JSAdapter({
-        __get__ :  function(name) {
-            if (isValid(name)) {
-                return list.get(name);
-            } else if (name == 'length') {
-                return list.size();
-            } else {
-                return undefined;
-            }
-        },
-        __has__ : function (name) {
-            return isValid(name) || name == 'length';
-        },
-        __delete__ : function(name) {
-            if (isValid(name)) {
-                list.remove(name);
-            }
-        },
-        __put__ : function(name, value) {
-            if (isValid(name)) {
-                list.set(name, value);
-            }
-        },
-        __getIds__: function() {
-            var res = new Array(list.size());
-            for (var i = 0; i < res.length; i++) {
-                res[i] = i;
-            }
-            return res;
-        },
-        toString: function() {
-            return list.toString();
-        }
-    });
-}
-
-/**
- * This is java.lang.System properties wrapped by JSAdapter.
- * For eg. to access java.class.path property, you can use
- * the syntax sysProps["java.class.path"]
- */
-var sysProps = new JSAdapter({
-    __get__ : function (name) {
-        return java.lang.System.getProperty(name);
-    },
-    __has__ : function (name) {
-        return java.lang.System.getProperty(name) != null;
-    },
-    __getIds__ : function() {
-        return java.lang.System.getProperties().keySet().toArray();
-    },
-    __delete__ : function(name) {
-        java.lang.System.clearProperty(name);
-        return true;
-    },
-    __put__ : function (name, value) {
-        java.lang.System.setProperty(name, value);
-    },
-    toString: function() {
-        return "";
-    }
-});
-
-// stdout, stderr & stdin
-var out = java.lang.System.out;
-var err = java.lang.System.err;
-// can't use 'in' because it is a JavaScript keyword :-(
-var inp = java.lang.System["in"];
-
-var BufferedInputStream = java.io.BufferedInputStream;
-var BufferedOutputStream = java.io.BufferedOutputStream;
-var BufferedReader = java.io.BufferedReader;
-var DataInputStream = java.io.DataInputStream;
-var File = java.io.File;
-var FileInputStream = java.io.FileInputStream;
-var FileOutputStream = java.io.FileOutputStream;
-var InputStream = java.io.InputStream;
-var InputStreamReader = java.io.InputStreamReader;
-var OutputStream = java.io.OutputStream;
-var Reader = java.io.Reader;
-var URL = java.net.URL;
-
-/**
- * Generic any object to input stream mapper
- * @param str input file name, URL or InputStream
- * @return InputStream object
- * @private
- */
-function inStream(str) {
-    if (typeof(str) == "string") {
-        // '-' means standard input
-        if (str == '-') {
-            return java.lang.System["in"];
-        }
-        // try file first
-        var file = null;
-        try {
-            file = pathToFile(str);
-        } catch (e) {
-        }
-        if (file && file.exists()) {
-            return new FileInputStream(file);
-        } else {
-            try {
-                // treat the string as URL
-                return new URL(str).openStream();
-            } catch (e) {
-                throw 'file or URL ' + str + ' not found';
-            }
-        }
-    } else {
-        if (str instanceof InputStream) {
-            return str;
-        } else if (str instanceof URL) {
-            return str.openStream();
-        } else if (str instanceof File) {
-            return new FileInputStream(str);
-        }
-    }
-    // everything failed, just give input stream
-    return java.lang.System["in"];
-}
-
-/**
- * Generic any object to output stream mapper
- *
- * @param out output file name or stream
- * @return OutputStream object
- * @private
- */
-function outStream(out) {
-    if (typeof(out) == "string") {
-        if (out == '>') {
-            return java.lang.System.out;
-        } else {
-            // treat it as file
-            return new FileOutputStream(pathToFile(out));
-        }
-    } else {
-        if (out instanceof OutputStream) {
-            return out;
-        } else if (out instanceof File) {
-            return new FileOutputStream(out);
-        }
-    }
-
-    // everything failed, just return System.out
-    return java.lang.System.out;
-}
-
-/**
- * stream close takes care not to close stdin, out & err.
- * @private
- */
-function streamClose(stream) {
-    if (stream) {
-        if (stream != java.lang.System["in"] &&
-            stream != java.lang.System.out &&
-            stream != java.lang.System.err) {
-            try {
-                stream.close();
-            } catch (e) {
-                println(e);
-            }
-        }
-    }
-}
-
-/**
- * Loads and evaluates JavaScript code from a stream or file or URL
- * - * Examples: - *
- * 
- *    load('test.js'); // load script file 'test.js'
- *    load('http://java.sun.com/foo.js'); // load from a URL
- * 
- * 
- * - * @param str input from which script is loaded and evaluated - */ -if (typeof(load) == 'undefined') { - var load = function(str) { - var stream = inStream(str); - var bstream = new BufferedInputStream(stream); - var reader = new BufferedReader(new InputStreamReader(bstream)); - var oldFilename = engine.get(engine.FILENAME); - engine.put(engine.FILENAME, str); - try { - engine.eval(reader); - } finally { - engine.put(engine.FILENAME, oldFilename); - streamClose(stream); - } - } -} - -// file system utilities - -/** - * Creates a Java byte[] of given length - * @param len size of the array to create - * @private - */ -function javaByteArray(len) { - return java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, len); -} - -var curDir = new File('.'); - -/** - * Print present working directory - */ -function pwd() { - println(curDir.getAbsolutePath()); -} - -/** - * Changes present working directory to given directory - * @param target directory to change to. optional, defaults to user's HOME - */ -function cd(target) { - if (target == undefined) { - target = sysProps["user.home"]; - } - if (!(target instanceof File)) { - target = pathToFile(target); - } - if (target.exists() && target.isDirectory()) { - curDir = target; - } else { - println(target + " is not a directory"); - } -} - -/** - * Converts path to java.io.File taking care of shell present working dir - * - * @param pathname file path to be converted - * @private - */ -function pathToFile(pathname) { - var tmp = pathname; - if (!(tmp instanceof File)) { - tmp = new File(tmp); - } - if (!tmp.isAbsolute()) { - return new File(curDir, pathname); - } else { - return tmp; - } -} - -/** - * Copies a file or URL or stream to another file or stream - * - * @param from input file or URL or stream - * @param to output stream or file - */ -function cp(from, to) { - if (from == to) { - println("file " + from + " cannot be copied onto itself!"); - return; - } - var inp = inStream(from); - var out = outStream(to); - var binp = new BufferedInputStream(inp); - var bout = new BufferedOutputStream(out); - var buff = javaByteArray(1024); - var len; - while ((len = binp.read(buff)) > 0 ) - bout.write(buff, 0, len); - - bout.flush(); - streamClose(inp); - streamClose(out); -} - -/** - * Shows the content of a file or URL or any InputStream
- * Examples: - *
- * 
- *    cat('test.txt'); // show test.txt file contents
- *    cat('http://java.net'); // show the contents from the URL http://java.net
- * 
- * 
- * @param obj input to show - * @param pattern optional. show only the lines matching the pattern - */ -function cat(obj, pattern) { - if (obj instanceof File && obj.isDirectory()) { - ls(obj); - return; - } - - var inp = null; - if (!(obj instanceof Reader)) { - inp = inStream(obj); - obj = new BufferedReader(new InputStreamReader(inp)); - } - var line; - if (pattern) { - var count = 1; - while ((line=obj.readLine()) != null) { - if (line.match(pattern)) { - println(count + "\t: " + line); - } - count++; - } - } else { - while ((line=obj.readLine()) != null) { - println(line); - } - } -} - -/** - * Returns directory part of a filename - * - * @param pathname input path name - * @return directory part of the given file name - */ -function dirname(pathname) { - var dirName = "."; - // Normalize '/' to local file separator before work. - var i = pathname.replace('/', File.separatorChar ).lastIndexOf( - File.separator ); - if ( i != -1 ) - dirName = pathname.substring(0, i); - return dirName; -} - -/** - * Creates a new dir of given name - * - * @param dir name of the new directory - */ -function mkdir(dir) { - dir = pathToFile(dir); - println(dir.mkdir()? "created" : "can not create dir"); -} - -/** - * Creates the directory named by given pathname, including - * any necessary but nonexistent parent directories. - * - * @param dir input path name - */ -function mkdirs(dir) { - dir = pathToFile(dir); - println(dir.mkdirs()? "created" : "can not create dirs"); -} - -/** - * Removes a given file - * - * @param pathname name of the file - */ -function rm(pathname) { - var file = pathToFile(pathname); - if (!file.exists()) { - println("file not found: " + pathname); - return false; - } - // note that delete is a keyword in JavaScript! - println(file["delete"]()? "deleted" : "can not delete"); -} - -/** - * Removes a given directory - * - * @param pathname name of the directory - */ -function rmdir(pathname) { - rm(pathname); -} - -/** - * Synonym for 'rm' - */ -function del(pathname) { - rm(pathname); -} - -/** - * Moves a file to another - * - * @param from original name of the file - * @param to new name for the file - */ -function mv(from, to) { - println(pathToFile(from).renameTo(pathToFile(to))? - "moved" : "can not move"); -} - -/** - * Synonym for 'mv'. - */ -function ren(from, to) { - mv(from, to); -} - -var months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; - -/** - * Helper function called by ls - * @private - */ -function printFile(f) { - var sb = new java.lang.StringBuffer(); - sb.append(f.isDirectory()? "d" : "-"); - sb.append(f.canRead() ? "r": "-" ); - sb.append(f.canWrite() ? "w": "-" ); - sb.append(" "); - - var d = new java.util.Date(f.lastModified()); - var c = new java.util.GregorianCalendar(); - c.setTime(d); - var day = c.get(java.util.Calendar.DAY_OF_MONTH); - sb.append(months[c.get(java.util.Calendar.MONTH)] - + " " + day ); - if (day < 10) { - sb.append(" "); - } - - // to get fixed length 'length' field - var fieldlen = 8; - var len = new java.lang.StringBuffer(); - for(var j=0; j - * - * Examples: - *
- * 
- *    find('.')
- *    find('.', '.*\.class', rm);  // remove all .class files
- *    find('.', '.*\.java');       // print fullpath of each .java file
- *    find('.', '.*\.java', cat);  // print all .java files
- * 
- * 
- * - * @param dir directory to search files - * @param pattern to search in the files - * @param callback function to call for matching files - */ -function find(dir, pattern, callback) { - dir = pathToFile(dir); - if (!callback) callback = print; - var files = dir.listFiles(); - for (var f in files) { - var file = files[f]; - if (file.isDirectory()) { - find(file, pattern, callback); - } else { - if (pattern) { - if (file.getName().match(pattern)) { - callback(file); - } - } else { - callback(file); - } - } - } -} - -// process utilities - -/** - * Exec's a child process, waits for completion & returns exit code - * - * @param cmd command to execute in child process - */ -function exec(cmd) { - var process = java.lang.Runtime.getRuntime().exec(cmd); - var inp = new DataInputStream(process.getInputStream()); - var line = null; - while ((line = inp.readLine()) != null) { - println(line); - } - process.waitFor(); - $exit = process.exitValue(); -} - -// XML utilities - -/** - * Converts input to DOM Document object - * - * @param inp file or reader. optional, without this param, - * this function returns a new DOM Document. - * @return returns a DOM Document object - */ -function XMLDocument(inp) { - var factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); - var builder = factory.newDocumentBuilder(); - if (inp) { - if (typeof(inp) == "string") { - return builder.parse(pathToFile(inp)); - } else { - return builder.parse(inp); - } - } else { - return builder.newDocument(); - } -} - -/** - * Converts arbitrary stream, file, URL to XMLSource - * - * @param inp input stream or file or URL - * @return XMLSource object - */ -function XMLSource(inp) { - if (inp instanceof javax.xml.transform.Source) { - return inp; - } else if (inp instanceof Packages.org.w3c.dom.Document) { - return new javax.xml.transform.dom.DOMSource(inp); - } else { - inp = new BufferedInputStream(inStream(inp)); - return new javax.xml.transform.stream.StreamSource(inp); - } -} - -/** - * Converts arbitrary stream, file to XMLResult - * - * @param inp output stream or file - * @return XMLResult object - */ -function XMLResult(out) { - if (out instanceof javax.xml.transform.Result) { - return out; - } else if (out instanceof Packages.org.w3c.dom.Document) { - return new javax.xml.transform.dom.DOMResult(out); - } else { - out = new BufferedOutputStream(outStream(out)); - return new javax.xml.transform.stream.StreamResult(out); - } -} - -/** - * Perform XSLT transform - * - * @param inp Input XML to transform (URL, File or InputStream) - * @param style XSL Stylesheet to be used (URL, File or InputStream). optional. - * @param out Output XML (File or OutputStream - */ -function XSLTransform(inp, style, out) { - switch (arguments.length) { - case 2: - inp = arguments[0]; - out = arguments[1]; - break; - case 3: - inp = arguments[0]; - style = arguments[1]; - out = arguments[2]; - break; - default: - println("XSL tranform requires 2 or 3 arguments"); - return; - } - - var factory = javax.xml.transform.TransformerFactory.newInstance(); - var transformer; - if (style) { - transformer = factory.newTransformer(XMLSource(style)); - } else { - transformer = factory.newTransformer(); - } - var source = XMLSource(inp); - var result = XMLResult(out); - transformer.transform(source, result); - if (source.getInputStream) { - streamClose(source.getInputStream()); - } - if (result.getOutputStream) { - streamClose(result.getOutputStream()); - } -} - -// miscellaneous utilities - -/** - * Prints which command is selected from PATH - * - * @param cmd name of the command searched from PATH - */ -function which(cmd) { - var st = new java.util.StringTokenizer(env.PATH, File.pathSeparator); - while (st.hasMoreTokens()) { - var file = new File(st.nextToken(), cmd); - if (file.exists()) { - println(file.getAbsolutePath()); - return; - } - } -} - -/** - * Prints IP addresses of given domain name - * - * @param name domain name - */ -function ip(name) { - var addrs = InetAddress.getAllByName(name); - for (var i in addrs) { - println(addrs[i]); - } -} - -/** - * Prints current date in current locale - */ -function date() { - println(new Date().toLocaleString()); -} - -/** - * Echoes the given string arguments - */ -function echo(x) { - for (var i = 0; i < arguments.length; i++) { - println(arguments[i]); - } -} - -/** - * Reads one or more lines from stdin after printing prompt - * - * @param prompt optional, default is '>' - * @param multiline to tell whether to read single line or multiple lines - */ -function read(prompt, multiline) { - if (!prompt) { - prompt = '>'; - } - var inp = java.lang.System["in"]; - var reader = new BufferedReader(new InputStreamReader(inp)); - if (multiline) { - var line = ''; - while (true) { - java.lang.System.err.print(prompt); - java.lang.System.err.flush(); - var tmp = reader.readLine(); - if (tmp == '' || tmp == null) break; - line += tmp + '\n'; - } - return line; - } else { - java.lang.System.err.print(prompt); - java.lang.System.err.flush(); - return reader.readLine(); - } -} - -if (typeof(println) == 'undefined') { - var print = function(str, newline) { - if (typeof(str) == 'undefined') { - str = 'undefined'; - } else if (str == null) { - str = 'null'; - } - - if (!(out instanceof java.io.PrintWriter)) { - out = new java.io.PrintWriter(out); - } - - out.print(String(str)); - if (newline) { - out.print('\n'); - } - out.flush(); - } - - var println = function(str) { - print(str, true); - }; -} - -/** - * This is C-like printf - * - * @param format string to format the rest of the print items - * @param args variadic argument list - */ -function printf(format, args/*, more args*/) { - print(sprintf.apply(this, arguments)); -} - -/** - * This is C-like sprintf - * - * @param format string to format the rest of the print items - * @param args variadic argument list - */ -function sprintf(format, args/*, more args*/) { - var len = arguments.length - 1; - var array = []; - - if (len < 0) { - return ""; - } - - for (var i = 0; i < len; i++) { - if (arguments[i+1] instanceof Date) { - array[i] = arguments[i+1].getTime(); - } else { - array[i] = arguments[i+1]; - } - } - - array = Java.toJavaArray(array); - return Packages.jdk.nashorn.api.scripting.Formatter.format(format, array); -} From 54485169dd7c29174938a64340e2235a4c855415 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 15 Mar 2013 11:44:33 -0700 Subject: [PATCH 026/137] 8010105: new hotspot build - hs25-b24 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 28b5a9a1114..69b8ad849df 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=23 +HS_BUILD_NUMBER=24 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From f5f5775dc3a12d0cf627c5f194362ccbb74891d3 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Fri, 15 Mar 2013 15:20:40 -0400 Subject: [PATCH 027/137] 8005716: Enhance JNI specification to allow support of static JNI libraries in Embedded JREs Reviewed-by: dlong, alanb, mduigou --- hotspot/src/share/vm/prims/jni.cpp | 4 ++-- hotspot/src/share/vm/prims/jni.h | 3 ++- hotspot/src/share/vm/runtime/thread.cpp | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index f45568a7ca7..22716c400c2 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -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. * Copyright (c) 2012 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -92,7 +92,7 @@ # include "os_bsd.inline.hpp" #endif -static jint CurrentVersion = JNI_VERSION_1_6; +static jint CurrentVersion = JNI_VERSION_1_8; // The DT_RETURN_MARK macros create a scoped object to fire the dtrace diff --git a/hotspot/src/share/vm/prims/jni.h b/hotspot/src/share/vm/prims/jni.h index a67c2e540f3..582f2c97024 100644 --- a/hotspot/src/share/vm/prims/jni.h +++ b/hotspot/src/share/vm/prims/jni.h @@ -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 @@ -1951,6 +1951,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved); #define JNI_VERSION_1_2 0x00010002 #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 #ifdef __cplusplus } /* extern "C" */ diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index cb883c5d821..322597fe4cc 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -4061,6 +4061,7 @@ jboolean Threads::is_supported_jni_version(jint version) { if (version == JNI_VERSION_1_2) return JNI_TRUE; if (version == JNI_VERSION_1_4) return JNI_TRUE; if (version == JNI_VERSION_1_6) return JNI_TRUE; + if (version == JNI_VERSION_1_8) return JNI_TRUE; return JNI_FALSE; } From 6f76ade8e159655b72614708664f8d523d4aa8b7 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 15 Mar 2013 17:24:40 -0400 Subject: [PATCH 028/137] 8007725: NPG: Klass::restore_unshareable_info() triggers assert(k->java_mirror() == NULL) Check for exception during SystemDictionary::resolve_instance_class_or_null() and clean up. Reviewed-by: coleenp, acorn, hseigel, minqi --- .../share/vm/classfile/classLoaderData.cpp | 5 +++ .../share/vm/classfile/systemDictionary.cpp | 44 ++++++++++++++++--- .../share/vm/classfile/systemDictionary.hpp | 1 + hotspot/src/share/vm/oops/klass.cpp | 6 +++ hotspot/src/share/vm/oops/method.cpp | 10 ++++- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index e74a88d7d33..f74f8f1ce13 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -105,6 +105,7 @@ void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool m void ClassLoaderData::classes_do(KlassClosure* klass_closure) { for (Klass* k = _klasses; k != NULL; k = k->next_link()) { klass_closure->do_klass(k); + assert(k != k->next_link(), "no loops!"); } } @@ -113,6 +114,7 @@ void ClassLoaderData::classes_do(void f(InstanceKlass*)) { if (k->oop_is_instance()) { f(InstanceKlass::cast(k)); } + assert(k != k->next_link(), "no loops!"); } } @@ -258,6 +260,7 @@ void ClassLoaderData::remove_class(Klass* scratch_class) { return; } prev = k; + assert(k != k->next_link(), "no loops!"); } ShouldNotReachHere(); // should have found this class!! } @@ -439,6 +442,7 @@ void ClassLoaderData::dump(outputStream * const out) { while (k != NULL) { out->print_cr("klass "PTR_FORMAT", %s, CT: %d, MUT: %d", k, k->name()->as_C_string(), k->has_modified_oops(), k->has_accumulated_modified_oops()); + assert(k != k->next_link(), "no loops!"); k = k->next_link(); } } @@ -465,6 +469,7 @@ void ClassLoaderData::verify() { for (Klass* k = _klasses; k != NULL; k = k->next_link()) { guarantee(k->class_loader_data() == this, "Must be the same"); k->verify(); + assert(k != k->next_link(), "no loops!"); } } diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index 002d781f928..edd3107062b 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -804,6 +804,32 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla } } // load_instance_class loop + if (HAS_PENDING_EXCEPTION) { + // An exception, such as OOM could have happened at various places inside + // load_instance_class. We might have partially initialized a shared class + // and need to clean it up. + if (class_loader.is_null()) { + // In some cases k may be null. Let's find the shared class again. + instanceKlassHandle ik(THREAD, find_shared_class(name)); + if (ik.not_null()) { + if (ik->class_loader_data() == NULL) { + // We didn't go as far as Klass::restore_unshareable_info(), + // so nothing to clean up. + } else { + MutexLocker mu(SystemDictionary_lock, THREAD); + Klass* kk = find_class(name, ik->class_loader_data()); + if (kk != NULL) { + // No clean up is needed if the shared class has been entered + // into system dictionary, as load_shared_class() won't be called + // again. + } else { + clean_up_shared_class(ik, class_loader, THREAD); + } + } + } + } + } + if (load_instance_added == true) { // clean up placeholder entries for LOAD_INSTANCE success or error // This brackets the SystemDictionary updates for both defining @@ -1140,11 +1166,6 @@ instanceKlassHandle SystemDictionary::load_shared_class( return load_shared_class(ik, class_loader, THREAD); } -// Note well! Changes to this method may affect oop access order -// in the shared archive. Please take care to not make changes that -// adversely affect cold start time by changing the oop access order -// that is specified in dump.cpp MarkAndMoveOrderedReadOnly and -// MarkAndMoveOrderedReadWrite closures. instanceKlassHandle SystemDictionary::load_shared_class( instanceKlassHandle ik, Handle class_loader, TRAPS) { assert(class_loader.is_null(), "non-null classloader for shared class?"); @@ -1205,6 +1226,19 @@ instanceKlassHandle SystemDictionary::load_shared_class( return ik; } +void SystemDictionary::clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS) { + // Updating methods must be done under a lock so multiple + // threads don't update these in parallel + // Shared classes are all currently loaded by the bootstrap + // classloader, so this will never cause a deadlock on + // a custom class loader lock. + { + Handle lockObject = compute_loader_lock_object(class_loader, THREAD); + check_loader_lock_contention(lockObject, THREAD); + ObjectLocker ol(lockObject, THREAD, true); + ik->remove_unshareable_info(); + } +} instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) { instanceKlassHandle nh = instanceKlassHandle(); // null Handle diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp index d415c9b1e4f..d282fedfb4d 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp @@ -621,6 +621,7 @@ private: Handle class_loader, TRAPS); static instanceKlassHandle load_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS); + static void clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS); static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS); static Handle compute_loader_lock_object(Handle class_loader, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS); diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index edfda97a539..06c644c3478 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -486,6 +486,12 @@ void Klass::oops_do(OopClosure* cl) { } void Klass::remove_unshareable_info() { + if (!DumpSharedSpaces) { + // Clean up after OOM during class loading + if (class_loader_data() != NULL) { + class_loader_data()->remove_class(this); + } + } set_subklass(NULL); set_next_sibling(NULL); // Clear the java mirror diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 0ee78f17605..11ddd21f1f6 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -798,7 +798,15 @@ void Method::unlink_method() { backedge_counter()->reset(); _adapter = NULL; _from_compiled_entry = NULL; - assert(_method_data == NULL, "unexpected method data?"); + + // In case of DumpSharedSpaces, _method_data should always be NULL. + // + // During runtime (!DumpSharedSpaces), when we are cleaning a + // shared class that failed to load, this->link_method() may + // have already been called (before an exception happened), so + // this->_method_data may not be NULL. + assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?"); + set_method_data(NULL); set_interpreter_throwout_count(0); set_interpreter_invocation_count(0); From f27f7d4c5724cdff28f1ade427970cdd87c17f2f Mon Sep 17 00:00:00 2001 From: Yunda Date: Fri, 15 Mar 2013 22:07:42 -0700 Subject: [PATCH 029/137] 8008796: SA: Oop.iterateFields() should support CompressedKlassPointers again Add a missing change from JDK-7054512 so that Oop.iterateFields() works with UseCompressedKlassPointers Reviewed-by: coleenp, roland --- hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java index ab81252d4e7..241e5be3756 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -148,7 +148,7 @@ public class Oop { if (doVMFields) { visitor.doCInt(mark, true); if (VM.getVM().isCompressedKlassPointersEnabled()) { - throw new InternalError("unimplemented"); + visitor.doMetadata(compressedKlass, true); } else { visitor.doMetadata(klass, true); } From f8081de0064719d226e472f7f892ac2ac1d39a41 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Sat, 16 Mar 2013 07:39:14 -0700 Subject: [PATCH 030/137] 8009166: [parfait] Null pointer deference in hotspot/src/share/vm/opto/type.cpp Add guarantee() to as_instance_type() Reviewed-by: kvn, twisti --- hotspot/src/share/vm/opto/type.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index 3928c23aff3..68f681342d9 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -4193,6 +4193,7 @@ const TypeOopPtr* TypeKlassPtr::as_instance_type() const { bool xk = klass_is_exact(); //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0); const TypeOopPtr* toop = TypeOopPtr::make_from_klass_raw(k); + guarantee(toop != NULL, "need type for given klass"); toop = toop->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr(); return toop->cast_to_exactness(xk)->is_oopptr(); } From 5b729220581f217c037d2e38fb983e30594f8cb7 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Sat, 16 Mar 2013 07:39:57 -0700 Subject: [PATCH 031/137] 8009156: [parfait] Null pointer deference in hotspot/src/share/vm/services/memoryService.cpp Add guarantee() to add_generation_memory_pool() Reviewed-by: kvn, twisti --- hotspot/src/share/vm/services/memoryService.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index 0040f9d96fc..75693dbcf69 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -240,6 +240,7 @@ MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space, void MemoryService::add_generation_memory_pool(Generation* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) { + guarantee(gen != NULL, "No generation for memory pool"); Generation::Name kind = gen->kind(); int index = _pools_list->length(); From e98f593fb0123ac71f10fec52f0b270a4a996e20 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Sat, 16 Mar 2013 07:40:36 -0700 Subject: [PATCH 032/137] 8008328: [partfait] Null pointer defererence in hotspot/src/cpu/x86/vm/frame_x86.inline.hpp Add guarantee() to oop_result inlines Reviewed-by: kvn, twisti --- hotspot/src/cpu/x86/vm/frame_x86.inline.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp index ea8111b9fd7..b15b00be586 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp @@ -295,14 +295,18 @@ inline bool frame::volatile_across_calls(Register reg) { return true; } +inline oop frame::saved_oop_result(RegisterMap* map) const { + oop* result_adr = (oop *)map->location(rax->as_VMReg()); + guarantee(result_adr != NULL, "bad register save location"); - -inline oop frame::saved_oop_result(RegisterMap* map) const { - return *((oop*) map->location(rax->as_VMReg())); + return (*result_adr); } inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) { - *((oop*) map->location(rax->as_VMReg())) = obj; + oop* result_adr = (oop *)map->location(rax->as_VMReg()); + guarantee(result_adr != NULL, "bad register save location"); + + *result_adr = obj; } #endif // CPU_X86_VM_FRAME_X86_INLINE_HPP From 2cd055b0b2de433464b5952705fd601b27a47797 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Sat, 16 Mar 2013 07:41:09 -0700 Subject: [PATCH 033/137] 8010144: [parfait] Null pointer deference in hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Add null check to signal handler Reviewed-by: dcubed --- hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 4c9d3dbed8b..5cdab45d4cb 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -340,7 +340,7 @@ JVM_handle_linux_signal(int sig, // here if the underlying file has been truncated. // Do not crash the VM in such a case. CodeBlob* cb = CodeCache::find_blob_unsafe(pc); - nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; + nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL; if (nm != NULL && nm->has_unsafe_access()) { stub = StubRoutines::handler_for_unsafe_access(); } From bb303a20eff6e2f23fc0ae64fb96d68ad48cab8e Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Sun, 17 Mar 2013 09:55:03 +0000 Subject: [PATCH 034/137] 8010142: ProblemList.txt updates (3/2013) Reviewed-by: alanb --- jdk/test/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 842ffbe2532..befe68372f3 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -137,6 +137,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all # 8008200 java/lang/Class/asSubclass/BasicUnit.java generic-all +# 8009552 +vm/verifier/TestStaticIF.java generic-all + ############################################################################ # jdk_management From 51c733dfb1a1d809aaeea26c5275547a8862dcf6 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Mon, 18 Mar 2013 04:29:08 -0700 Subject: [PATCH 035/137] 8008211: Some of WB tests on compiler fail Reviewed-by: kvn, vlivanov --- .../whitebox/CompilerWhiteBoxTest.java | 18 +++++++++++++++--- .../compiler/whitebox/DeoptimizeAllTest.java | 4 ++-- .../whitebox/DeoptimizeMethodTest.java | 4 ++-- .../whitebox/IsMethodCompilableTest.java | 4 ++-- .../whitebox/MakeMethodNotCompilableTest.java | 2 ++ 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java index ebd5a9af45f..02b92815825 100644 --- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java +++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java @@ -35,6 +35,8 @@ public abstract class CompilerWhiteBoxTest { protected static final Method METHOD = getMethod("method"); protected static final int COMPILE_THRESHOLD = Integer.parseInt(getVMOption("CompileThreshold", "10000")); + protected static final boolean BACKGROUND_COMPILATION + = Boolean.valueOf(getVMOption("BackgroundCompilation", "true")); protected static Method getMethod(String name) { try { @@ -45,11 +47,16 @@ public abstract class CompilerWhiteBoxTest { } } - protected static String getVMOption(String name, String defaultValue) { + protected static String getVMOption(String name) { String result; HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); result = diagnostic.getVMOption(name).getValue(); + return result; + } + + protected static String getVMOption(String name, String defaultValue) { + String result = getVMOption(name); return result == null ? defaultValue : result; } @@ -66,6 +73,7 @@ public abstract class CompilerWhiteBoxTest { } catch (Exception e) { System.out.printf("on exception '%s':", e.getMessage()); printInfo(METHOD); + e.printStackTrace(); throw new RuntimeException(e); } System.out.println("at test's end:"); @@ -100,6 +108,9 @@ public abstract class CompilerWhiteBoxTest { protected static void waitBackgroundCompilation(Method method) throws InterruptedException { + if (!BACKGROUND_COMPILATION) { + return; + } final Object obj = new Object(); synchronized (obj) { for (int i = 0; i < 10; ++i) { @@ -129,13 +140,14 @@ public abstract class CompilerWhiteBoxTest { protected final int compile() { int result = 0; - for (int i = 0; i < COMPILE_THRESHOLD; ++i) { + int count = Math.max(COMPILE_THRESHOLD, 150000); + for (int i = 0; i < count; ++i) { result += method(); } + System.out.println("method was invoked " + count + " times"); return result; } - protected int method() { return 42; } diff --git a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java index 7690e6a9071..fdf498c31b4 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java @@ -32,12 +32,12 @@ public class DeoptimizeAllTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { + // to prevent inlining #method into #compile() + WHITE_BOX.setDontInlineMethod(METHOD, true); new DeoptimizeAllTest().runTest(); } protected void test() throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.setDontInlineMethod(METHOD, true); compile(); checkCompiled(METHOD); WHITE_BOX.deoptimizeAll(); diff --git a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java index bc1c9d67962..7894c524ffa 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java @@ -32,12 +32,12 @@ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { + // to prevent inlining #method into #compile() + WHITE_BOX.setDontInlineMethod(METHOD, true); new DeoptimizeMethodTest().runTest(); } protected void test() throws Exception { - // to prevent inlining #method into #compile() - WHITE_BOX.setDontInlineMethod(METHOD, true); compile(); checkCompiled(METHOD); WHITE_BOX.deoptimizeMethod(METHOD); diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java index d0c102f54f0..374d48402fc 100644 --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java @@ -44,6 +44,8 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { } public static void main(String[] args) throws Exception { + // to prevent inlining #method into #compile() + WHITE_BOX.setDontInlineMethod(METHOD, true); new IsMethodCompilableTest().runTest(); } @@ -58,8 +60,6 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { "Warning: test is not applicable if PerMethodRecompilationCutoff == Inf"); return; } - // to prevent inlining #method into #compile() - WHITE_BOX.setDontInlineMethod(METHOD, true); boolean madeNotCompilable = false; for (long i = 0; i < PER_METHOD_RECOMPILATION_CUTOFF; ++i) { diff --git a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java index ad4930b6426..0b9144c407c 100644 --- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java +++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java @@ -32,6 +32,8 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { public static void main(String[] args) throws Exception { + // to prevent inlining #method into #compile() + WHITE_BOX.setDontInlineMethod(METHOD, true); new MakeMethodNotCompilableTest().runTest(); } From 8f1814d8743b01becf7dd59400dc85834c90fe5c Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 18 Mar 2013 13:19:06 +0100 Subject: [PATCH 036/137] 8008555: Debugging code in compiled method sometimes leaks memory Support for strings that have same life-time as code that uses them. Reviewed-by: kvn, twisti --- .../src/cpu/sparc/vm/macroAssembler_sparc.cpp | 38 ++--- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 28 +++- hotspot/src/share/vm/asm/assembler.cpp | 10 +- hotspot/src/share/vm/asm/assembler.hpp | 2 + hotspot/src/share/vm/asm/codeBuffer.cpp | 130 +++++++++++------- hotspot/src/share/vm/asm/codeBuffer.hpp | 25 ++-- hotspot/src/share/vm/code/codeBlob.cpp | 2 +- hotspot/src/share/vm/code/codeBlob.hpp | 8 +- hotspot/src/share/vm/code/icBuffer.hpp | 2 +- hotspot/src/share/vm/code/stubs.cpp | 16 +-- hotspot/src/share/vm/code/stubs.hpp | 10 +- .../src/share/vm/compiler/disassembler.cpp | 12 +- .../src/share/vm/compiler/disassembler.hpp | 2 +- .../src/share/vm/interpreter/interpreter.cpp | 2 +- .../src/share/vm/interpreter/interpreter.hpp | 6 +- .../share/vm/runtime/stubCodeGenerator.cpp | 2 +- 16 files changed, 174 insertions(+), 121 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index 251e42cd6af..578650a3419 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -1385,13 +1385,13 @@ void MacroAssembler::_verify_oop(Register reg, const char* msg, const char * fil } #endif - int len = strlen(file) + strlen(msg) + 1 + 4; - sprintf(buffer, "%d", line); - len += strlen(buffer); - sprintf(buffer, " at offset %d ", offset()); - len += strlen(buffer); - char * real_msg = new char[len]; - sprintf(real_msg, "%s%s(%s:%d)", msg, buffer, file, line); + const char* real_msg = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("%s at offset %d (%s:%d)", msg, offset(), file, line); + real_msg = code_string(ss.as_string()); + } // Call indirectly to solve generation ordering problem AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); @@ -1423,13 +1423,13 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* msg, const char // plausibility check for oops if (!VerifyOops) return; - char buffer[64]; - sprintf(buffer, "%d", line); - int len = strlen(file) + strlen(msg) + 1 + 4 + strlen(buffer); - sprintf(buffer, " at SP+%d ", addr.disp()); - len += strlen(buffer); - char * real_msg = new char[len]; - sprintf(real_msg, "%s at SP+%d (%s:%d)", msg, addr.disp(), file, line); + const char* real_msg = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("%s at SP+%d (%s:%d)", msg, addr.disp(), file, line); + real_msg = code_string(ss.as_string()); + } // Call indirectly to solve generation ordering problem AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); @@ -1622,9 +1622,13 @@ void MacroAssembler::untested(const char* what) { // in order to run automated test scripts on the VM // Use the flag ShowMessageBoxOnError - char* b = new char[1024]; - sprintf(b, "untested: %s", what); - + const char* b = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("untested: %s", what); + b = code_string(ss.as_string()); + } if (ShowMessageBoxOnError) { STOP(b); } else { warn(b); } } diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index bda1550ac25..b64518a7bc1 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -4262,8 +4262,13 @@ void MacroAssembler::verify_oop(Register reg, const char* s) { if (!VerifyOops) return; // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop: %s: %s", reg->name(), s); + const char* b = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("verify_oop: %s: %s", reg->name(), s); + b = code_string(ss.as_string()); + } BLOCK_COMMENT("verify_oop {"); #ifdef _LP64 push(rscratch1); // save r10, trashed by movptr() @@ -4297,9 +4302,14 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad { Label L; testptr(tmp, tmp); if (WizardMode) { + const char* buf = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]); + buf = code_string(ss.as_string()); + } jcc(Assembler::notZero, L); - char* buf = new char[40]; - sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]); STOP(buf); } else { jccb(Assembler::notZero, L); @@ -4343,9 +4353,13 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) { // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); // Pass register number to verify_oop_subroutine - char* b = new char[strlen(s) + 50]; - sprintf(b, "verify_oop_addr: %s", s); - + const char* b = NULL; + { + ResourceMark rm; + stringStream ss; + ss.print("verify_oop_addr: %s", s); + b = code_string(ss.as_string()); + } #ifdef _LP64 push(rscratch1); // save r10, trashed by movptr() #endif diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp index 669f49039fc..d23c0f50f2e 100644 --- a/hotspot/src/share/vm/asm/assembler.cpp +++ b/hotspot/src/share/vm/asm/assembler.cpp @@ -284,15 +284,19 @@ void AbstractAssembler::update_delayed_values() { DelayedConstant::update_all(); } - - - void AbstractAssembler::block_comment(const char* comment) { if (sect() == CodeBuffer::SECT_INSTS) { code_section()->outer()->block_comment(offset(), comment); } } +const char* AbstractAssembler::code_string(const char* str) { + if (sect() == CodeBuffer::SECT_INSTS || sect() == CodeBuffer::SECT_STUBS) { + return code_section()->outer()->code_string(str); + } + return NULL; +} + bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { // Exception handler checks the nmethod's implicit null checks table // only when this method returns false. diff --git a/hotspot/src/share/vm/asm/assembler.hpp b/hotspot/src/share/vm/asm/assembler.hpp index 0a55dc90eb9..8a9e2758a58 100644 --- a/hotspot/src/share/vm/asm/assembler.hpp +++ b/hotspot/src/share/vm/asm/assembler.hpp @@ -336,6 +336,8 @@ class AbstractAssembler : public ResourceObj { // along with the disassembly when printing nmethods. Currently // only supported in the instruction section of the code buffer. void block_comment(const char* comment); + // Copy str to a buffer that has the same lifetime as the CodeBuffer + const char* code_string(const char* str); // Label functions void bind(Label& L); // binds an unbound label L to the current code position diff --git a/hotspot/src/share/vm/asm/codeBuffer.cpp b/hotspot/src/share/vm/asm/codeBuffer.cpp index 2a4a8f2981f..f885c415332 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.cpp +++ b/hotspot/src/share/vm/asm/codeBuffer.cpp @@ -703,8 +703,8 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) { this->compute_final_layout(&dest); relocate_code_to(&dest); - // transfer comments from buffer to blob - dest_blob->set_comments(_comments); + // transfer strings and comments from buffer to blob + dest_blob->set_strings(_strings); // Done moving code bytes; were they the right size? assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); @@ -1003,58 +1003,78 @@ void CodeSection::decode() { void CodeBuffer::block_comment(intptr_t offset, const char * comment) { - _comments.add_comment(offset, comment); + _strings.add_comment(offset, comment); } -class CodeComment: public CHeapObj { - private: - friend class CodeComments; - intptr_t _offset; - const char * _comment; - CodeComment* _next; +const char* CodeBuffer::code_string(const char* str) { + return _strings.add_string(str); +} - ~CodeComment() { +class CodeString: public CHeapObj { + private: + friend class CodeStrings; + const char * _string; + CodeString* _next; + intptr_t _offset; + + ~CodeString() { assert(_next == NULL, "wrong interface for freeing list"); - os::free((void*)_comment, mtCode); + os::free((void*)_string, mtCode); } + bool is_comment() const { return _offset >= 0; } + public: - CodeComment(intptr_t offset, const char * comment) { - _offset = offset; - _comment = os::strdup(comment, mtCode); - _next = NULL; + CodeString(const char * string, intptr_t offset = -1) + : _next(NULL), _offset(offset) { + _string = os::strdup(string, mtCode); } - intptr_t offset() const { return _offset; } - const char * comment() const { return _comment; } - CodeComment* next() { return _next; } + const char * string() const { return _string; } + intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; } + CodeString* next() const { return _next; } - void set_next(CodeComment* next) { _next = next; } + void set_next(CodeString* next) { _next = next; } - CodeComment* find(intptr_t offset) { - CodeComment* a = this; - while (a != NULL && a->_offset != offset) { - a = a->_next; + CodeString* first_comment() { + if (is_comment()) { + return this; + } else { + return next_comment(); } - return a; } - - // Convenience for add_comment. - CodeComment* find_last(intptr_t offset) { - CodeComment* a = find(offset); - if (a != NULL) { - while ((a->_next != NULL) && (a->_next->_offset == offset)) { - a = a->_next; - } + CodeString* next_comment() const { + CodeString* s = _next; + while (s != NULL && !s->is_comment()) { + s = s->_next; } - return a; + return s; } }; +CodeString* CodeStrings::find(intptr_t offset) const { + CodeString* a = _strings->first_comment(); + while (a != NULL && a->offset() != offset) { + a = a->next_comment(); + } + return a; +} -void CodeComments::add_comment(intptr_t offset, const char * comment) { - CodeComment* c = new CodeComment(offset, comment); - CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset); +// Convenience for add_comment. +CodeString* CodeStrings::find_last(intptr_t offset) const { + CodeString* a = find(offset); + if (a != NULL) { + CodeString* c = NULL; + while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) { + a = c; + } + } + return a; +} + +void CodeStrings::add_comment(intptr_t offset, const char * comment) { + CodeString* c = new CodeString(comment, offset); + CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset); if (inspos) { // insert after already existing comments with same offset @@ -1062,43 +1082,47 @@ void CodeComments::add_comment(intptr_t offset, const char * comment) { inspos->set_next(c); } else { // no comments with such offset, yet. Insert before anything else. - c->set_next(_comments); - _comments = c; + c->set_next(_strings); + _strings = c; } } - -void CodeComments::assign(CodeComments& other) { - _comments = other._comments; +void CodeStrings::assign(CodeStrings& other) { + _strings = other._strings; } - -void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const { - if (_comments != NULL) { - CodeComment* c = _comments->find(offset); +void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const { + if (_strings != NULL) { + CodeString* c = find(offset); while (c && c->offset() == offset) { stream->bol(); stream->print(" ;; "); - stream->print_cr(c->comment()); - c = c->next(); + stream->print_cr(c->string()); + c = c->next_comment(); } } } -void CodeComments::free() { - CodeComment* n = _comments; +void CodeStrings::free() { + CodeString* n = _strings; while (n) { // unlink the node from the list saving a pointer to the next - CodeComment* p = n->_next; - n->_next = NULL; + CodeString* p = n->next(); + n->set_next(NULL); delete n; n = p; } - _comments = NULL; + _strings = NULL; } - +const char* CodeStrings::add_string(const char * string) { + CodeString* s = new CodeString(string); + s->set_next(_strings); + _strings = s; + assert(s->string() != NULL, "should have a string"); + return s->string(); +} void CodeBuffer::decode() { ttyLocker ttyl; diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp index d13697ef46e..8ce94646d95 100644 --- a/hotspot/src/share/vm/asm/codeBuffer.hpp +++ b/hotspot/src/share/vm/asm/codeBuffer.hpp @@ -28,7 +28,7 @@ #include "code/oopRecorder.hpp" #include "code/relocInfo.hpp" -class CodeComments; +class CodeStrings; class PhaseCFG; class Compile; class BufferBlob; @@ -240,27 +240,31 @@ class CodeSection VALUE_OBJ_CLASS_SPEC { #endif //PRODUCT }; -class CodeComment; -class CodeComments VALUE_OBJ_CLASS_SPEC { +class CodeString; +class CodeStrings VALUE_OBJ_CLASS_SPEC { private: #ifndef PRODUCT - CodeComment* _comments; + CodeString* _strings; #endif + CodeString* find(intptr_t offset) const; + CodeString* find_last(intptr_t offset) const; + public: - CodeComments() { + CodeStrings() { #ifndef PRODUCT - _comments = NULL; + _strings = NULL; #endif } + const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;); + void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN; - void assign(CodeComments& other) PRODUCT_RETURN; + void assign(CodeStrings& other) PRODUCT_RETURN; void free() PRODUCT_RETURN; }; - // A CodeBuffer describes a memory space into which assembly // code is generated. This memory space usually occupies the // interior of a single BufferBlob, but in some cases it may be @@ -326,7 +330,7 @@ class CodeBuffer: public StackObj { csize_t _total_size; // size in bytes of combined memory buffer OopRecorder* _oop_recorder; - CodeComments _comments; + CodeStrings _strings; OopRecorder _default_oop_recorder; // override with initialize_oop_recorder Arena* _overflow_arena; @@ -527,7 +531,7 @@ class CodeBuffer: public StackObj { void initialize_oop_recorder(OopRecorder* r); OopRecorder* oop_recorder() const { return _oop_recorder; } - CodeComments& comments() { return _comments; } + CodeStrings& strings() { return _strings; } // Code generation void relocate(address at, RelocationHolder const& rspec, int format = 0) { @@ -556,6 +560,7 @@ class CodeBuffer: public StackObj { address transform_address(const CodeBuffer &cb, address addr) const; void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; + const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;); // Log a little info about section usage in the CodeBuffer void log_section_sizes(const char* name); diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp index 779235f25fe..6120d3535ae 100644 --- a/hotspot/src/share/vm/code/codeBlob.cpp +++ b/hotspot/src/share/vm/code/codeBlob.cpp @@ -186,7 +186,7 @@ void CodeBlob::flush() { FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode); _oop_maps = NULL; } - _comments.free(); + _strings.free(); } diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp index 1d47bd9729c..e59ae7f1f89 100644 --- a/hotspot/src/share/vm/code/codeBlob.hpp +++ b/hotspot/src/share/vm/code/codeBlob.hpp @@ -66,7 +66,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { int _data_offset; // offset to where data region begins int _frame_size; // size of stack frame OopMapSet* _oop_maps; // OopMap for this CodeBlob - CodeComments _comments; + CodeStrings _strings; public: // Returns the space needed for CodeBlob @@ -186,12 +186,12 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { // Print the comment associated with offset on stream, if there is one virtual void print_block_comment(outputStream* stream, address block_begin) const { intptr_t offset = (intptr_t)(block_begin - code_begin()); - _comments.print_block_comment(stream, offset); + _strings.print_block_comment(stream, offset); } // Transfer ownership of comments to this CodeBlob - void set_comments(CodeComments& comments) { - _comments.assign(comments); + void set_strings(CodeStrings& strings) { + _strings.assign(strings); } }; diff --git a/hotspot/src/share/vm/code/icBuffer.hpp b/hotspot/src/share/vm/code/icBuffer.hpp index 36d0c761666..47db2d6b269 100644 --- a/hotspot/src/share/vm/code/icBuffer.hpp +++ b/hotspot/src/share/vm/code/icBuffer.hpp @@ -50,7 +50,7 @@ class ICStub: public Stub { friend class ICStubInterface; // This will be called only by ICStubInterface void initialize(int size, - CodeComments comments) { _size = size; _ic_site = NULL; } + CodeStrings strings) { _size = size; _ic_site = NULL; } void finalize(); // called when a method is removed // General info diff --git a/hotspot/src/share/vm/code/stubs.cpp b/hotspot/src/share/vm/code/stubs.cpp index 245a2463a05..930c637fac9 100644 --- a/hotspot/src/share/vm/code/stubs.cpp +++ b/hotspot/src/share/vm/code/stubs.cpp @@ -101,8 +101,8 @@ Stub* StubQueue::stub_containing(address pc) const { Stub* StubQueue::request_committed(int code_size) { Stub* s = request(code_size); - CodeComments comments; - if (s != NULL) commit(code_size, comments); + CodeStrings strings; + if (s != NULL) commit(code_size, strings); return s; } @@ -119,8 +119,8 @@ Stub* StubQueue::request(int requested_code_size) { assert(_buffer_limit == _buffer_size, "buffer must be fully usable"); if (_queue_end + requested_size <= _buffer_size) { // code fits in at the end => nothing to do - CodeComments comments; - stub_initialize(s, requested_size, comments); + CodeStrings strings; + stub_initialize(s, requested_size, strings); return s; } else { // stub doesn't fit in at the queue end @@ -137,8 +137,8 @@ Stub* StubQueue::request(int requested_code_size) { // Queue: |XXX|.......|XXXXXXX|.......| // ^0 ^end ^begin ^limit ^size s = current_stub(); - CodeComments comments; - stub_initialize(s, requested_size, comments); + CodeStrings strings; + stub_initialize(s, requested_size, strings); return s; } // Not enough space left @@ -147,12 +147,12 @@ Stub* StubQueue::request(int requested_code_size) { } -void StubQueue::commit(int committed_code_size, CodeComments& comments) { +void StubQueue::commit(int committed_code_size, CodeStrings& strings) { assert(committed_code_size > 0, "committed_code_size must be > 0"); int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment); Stub* s = current_stub(); assert(committed_size <= stub_size(s), "committed size must not exceed requested size"); - stub_initialize(s, committed_size, comments); + stub_initialize(s, committed_size, strings); _queue_end += committed_size; _number_of_stubs++; if (_mutex != NULL) _mutex->unlock(); diff --git a/hotspot/src/share/vm/code/stubs.hpp b/hotspot/src/share/vm/code/stubs.hpp index 36ada2a4cd9..233f43e2dae 100644 --- a/hotspot/src/share/vm/code/stubs.hpp +++ b/hotspot/src/share/vm/code/stubs.hpp @@ -73,7 +73,7 @@ class Stub VALUE_OBJ_CLASS_SPEC { public: // Initialization/finalization void initialize(int size, - CodeComments& comments) { ShouldNotCallThis(); } // called to initialize/specify the stub's size + CodeStrings& strings) { ShouldNotCallThis(); } // called to initialize/specify the stub's size void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated // General info/converters @@ -107,7 +107,7 @@ class StubInterface: public CHeapObj { public: // Initialization/finalization virtual void initialize(Stub* self, int size, - CodeComments& comments) = 0; // called after creation (called twice if allocated via (request, commit)) + CodeStrings& strings) = 0; // called after creation (called twice if allocated via (request, commit)) virtual void finalize(Stub* self) = 0; // called before deallocation // General info/converters @@ -136,7 +136,7 @@ class StubInterface: public CHeapObj { public: \ /* Initialization/finalization */ \ virtual void initialize(Stub* self, int size, \ - CodeComments& comments) { cast(self)->initialize(size, comments); } \ + CodeStrings& strings) { cast(self)->initialize(size, strings); } \ virtual void finalize(Stub* self) { cast(self)->finalize(); } \ \ /* General info */ \ @@ -176,7 +176,7 @@ class StubQueue: public CHeapObj { // Stub functionality accessed via interface void stub_initialize(Stub* s, int size, - CodeComments& comments) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); } + CodeStrings& strings) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, strings); } void stub_finalize(Stub* s) { _stub_interface->finalize(s); } int stub_size(Stub* s) const { return _stub_interface->size(s); } bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } @@ -206,7 +206,7 @@ class StubQueue: public CHeapObj { Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue void commit (int committed_code_size, - CodeComments& comments); // commit the previously requested stub - unlocks the queue + CodeStrings& strings); // commit the previously requested stub - unlocks the queue // Stub deallocation void remove_first(); // remove the first stub in the queue diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp index 3efe079142f..070e0321e08 100644 --- a/hotspot/src/share/vm/compiler/disassembler.cpp +++ b/hotspot/src/share/vm/compiler/disassembler.cpp @@ -158,7 +158,7 @@ class decode_env { private: nmethod* _nm; CodeBlob* _code; - CodeComments _comments; + CodeStrings _strings; outputStream* _output; address _start, _end; @@ -198,7 +198,7 @@ class decode_env { void print_address(address value); public: - decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments()); + decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings()); address decode_instructions(address start, address end); @@ -242,13 +242,13 @@ class decode_env { const char* options() { return _option_buf; } }; -decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) { +decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) { memset(this, 0, sizeof(*this)); _output = output ? output : tty; _code = code; if (code != NULL && code->is_nmethod()) _nm = (nmethod*) code; - _comments.assign(c); + _strings.assign(c); // by default, output pc but not bytes: _print_pc = true; @@ -370,7 +370,7 @@ void decode_env::print_insn_labels() { if (cb != NULL) { cb->print_block_comment(st, p); } - _comments.print_block_comment(st, (intptr_t)(p - _start)); + _strings.print_block_comment(st, (intptr_t)(p - _start)); if (_print_pc) { st->print(" " PTR_FORMAT ": ", p); } @@ -498,7 +498,7 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) { env.decode_instructions(cb->code_begin(), cb->code_end()); } -void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { +void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) { if (!load_library()) return; decode_env env(CodeCache::find_blob_unsafe(start), st, c); env.decode_instructions(start, end); diff --git a/hotspot/src/share/vm/compiler/disassembler.hpp b/hotspot/src/share/vm/compiler/disassembler.hpp index fd1f52eee1b..c81666ec25d 100644 --- a/hotspot/src/share/vm/compiler/disassembler.hpp +++ b/hotspot/src/share/vm/compiler/disassembler.hpp @@ -100,7 +100,7 @@ class Disassembler { } static void decode(CodeBlob *cb, outputStream* st = NULL); static void decode(nmethod* nm, outputStream* st = NULL); - static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments()); + static void decode(address begin, address end, outputStream* st = NULL, CodeStrings c = CodeStrings()); }; #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp index 24de109f39c..06554172bf1 100644 --- a/hotspot/src/share/vm/interpreter/interpreter.cpp +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp @@ -76,7 +76,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { if (PrintInterpreter) { st->cr(); - Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments())); + Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_strings) NOT_DEBUG(CodeStrings())); } } diff --git a/hotspot/src/share/vm/interpreter/interpreter.hpp b/hotspot/src/share/vm/interpreter/interpreter.hpp index 346af856a04..1fb4ac5c8ce 100644 --- a/hotspot/src/share/vm/interpreter/interpreter.hpp +++ b/hotspot/src/share/vm/interpreter/interpreter.hpp @@ -48,12 +48,12 @@ class InterpreterCodelet: public Stub { int _size; // the size in bytes const char* _description; // a description of the codelet, for debugging & printing Bytecodes::Code _bytecode; // associated bytecode if any - DEBUG_ONLY(CodeComments _comments;) // Comments for annotating assembler output. + DEBUG_ONLY(CodeStrings _strings;) // Comments for annotating assembler output. public: // Initialization/finalization void initialize(int size, - CodeComments& comments) { _size = size; DEBUG_ONLY(_comments.assign(comments);) } + CodeStrings& strings) { _size = size; DEBUG_ONLY(_strings.assign(strings);) } void finalize() { ShouldNotCallThis(); } // General info/converters @@ -131,7 +131,7 @@ class CodeletMark: ResourceMark { // commit Codelet - AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments()); + AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->strings()); // make sure nobody can use _masm outside a CodeletMark lifespan *_masm = NULL; } diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp index 2ba8e159fec..127b5e3169f 100644 --- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp +++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp @@ -87,7 +87,7 @@ StubCodeGenerator::~StubCodeGenerator() { CodeBuffer* cbuf = _masm->code(); CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start()); if (blob != NULL) { - blob->set_comments(cbuf->comments()); + blob->set_strings(cbuf->strings()); } bool saw_first = false; StubCodeDesc* toprint[1000]; From c846064c8fb08c9623703205e31d990c4a84087c Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 18 Mar 2013 21:03:11 +0530 Subject: [PATCH 037/137] 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing Reviewed-by: lagergren, jlaskey --- nashorn/bin/jjs | 2 +- nashorn/bin/jjssecure | 2 +- nashorn/bin/nashorn | 2 +- nashorn/bin/nashornsecure | 2 +- .../api/scripting/NashornScriptEngine.java | 26 +++++++- nashorn/test/script/basic/JDK-8010199.js | 51 +++++++++++++++ .../api/scripting/ScriptEngineTest.java | 62 +++++++++++++++++++ 7 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8010199.js diff --git a/nashorn/bin/jjs b/nashorn/bin/jjs index ca531f4dd02..fe6665c3c3d 100644 --- a/nashorn/bin/jjs +++ b/nashorn/bin/jjs @@ -26,4 +26,4 @@ [ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; -$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $* +$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $* diff --git a/nashorn/bin/jjssecure b/nashorn/bin/jjssecure index 614ffd36213..db6bdfc4178 100644 --- a/nashorn/bin/jjssecure +++ b/nashorn/bin/jjssecure @@ -26,4 +26,4 @@ [ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; -$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $* +$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $* diff --git a/nashorn/bin/nashorn b/nashorn/bin/nashorn index 3fccdd04c72..da22be1fb01 100644 --- a/nashorn/bin/nashorn +++ b/nashorn/bin/nashorn @@ -26,4 +26,4 @@ [ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; -$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $* +$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $* diff --git a/nashorn/bin/nashornsecure b/nashorn/bin/nashornsecure index 3d02c5293e5..77c7c52933a 100644 --- a/nashorn/bin/nashornsecure +++ b/nashorn/bin/nashornsecure @@ -26,4 +26,4 @@ [ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; -$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $* +$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $* diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 4fa6033c11f..55967bb04d4 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.lang.reflect.Method; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; @@ -179,14 +180,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } private T getInterfaceInner(final Object self, final Class clazz) { - final Object realSelf; + final ScriptObject realSelf; final ScriptObject ctxtGlobal = getNashornGlobalFrom(context); if(self == null) { realSelf = ctxtGlobal; } else if (!(self instanceof ScriptObject)) { - realSelf = ScriptObjectMirror.unwrap(self, ctxtGlobal); + realSelf = (ScriptObject)ScriptObjectMirror.unwrap(self, ctxtGlobal); } else { - realSelf = self; + realSelf = (ScriptObject)self; } try { final ScriptObject oldGlobal = getNashornGlobal(); @@ -194,6 +195,10 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if(oldGlobal != ctxtGlobal) { setNashornGlobal(ctxtGlobal); } + + if (! isInterfaceImplemented(clazz, realSelf)) { + return null; + } return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf)); } finally { if(oldGlobal != ctxtGlobal) { @@ -463,6 +468,21 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } + private static boolean isInterfaceImplemented(final Class iface, final ScriptObject sobj) { + for (final Method method : iface.getMethods()) { + // ignore methods of java.lang.Object class + if (method.getDeclaringClass() == Object.class) { + continue; + } + + Object obj = sobj.get(method.getName()); + if (! (obj instanceof ScriptFunction)) { + return false; + } + } + return true; + } + // don't make this public!! static ScriptObject getNashornGlobal() { return Context.getGlobal(); diff --git a/nashorn/test/script/basic/JDK-8010199.js b/nashorn/test/script/basic/JDK-8010199.js new file mode 100644 index 00000000000..ddd3ba0ff25 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8010199.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-8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing + * + * @test + * @run + */ + +var m = new javax.script.ScriptEngineManager(); +var e = m.getEngineByName("nashorn"); + +var iface = e.getInterface(java.lang.Runnable.class); + +if (iface != null) { + fail("Expected interface object to be null"); +} + +e.eval("var runcalled = false; function run() { runcalled = true }"); + +iface = e.getInterface(java.lang.Runnable.class); +if (iface == null) { + fail("Expected interface object to be non-null"); +} + +iface.run(); + +if (e.get("runcalled") != true) { + fail("runcalled is not true"); +} diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index 0994b0d26ca..48277aa8ab1 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -283,6 +283,68 @@ public class ScriptEngineTest { } } + public interface Foo { + public void bar(); + } + + public interface Foo2 extends Foo { + public void bar2(); + } + + @Test + public void getInterfaceMissingTest() { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine engine = manager.getEngineByName("nashorn"); + + // don't define any function. + try { + engine.eval(""); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + + Runnable runnable = ((Invocable)engine).getInterface(Runnable.class); + if (runnable != null) { + fail("runnable is not null!"); + } + + // now define "run" + try { + engine.eval("function run() { print('this is run function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + runnable = ((Invocable)engine).getInterface(Runnable.class); + // should not return null now! + runnable.run(); + + // define only one method of "Foo2" + try { + engine.eval("function bar() { print('bar function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + + Foo2 foo2 = ((Invocable)engine).getInterface(Foo2.class); + if (foo2 != null) { + throw new RuntimeException("foo2 is not null!"); + } + + // now define other method of "Foo2" + try { + engine.eval("function bar2() { print('bar2 function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + foo2 = ((Invocable)engine).getInterface(Foo2.class); + foo2.bar(); + foo2.bar2(); + } + @Test public void accessGlobalTest() { final ScriptEngineManager m = new ScriptEngineManager(); From d41c0fce7fc6a0ec7e8d0fbde8216db41aeab918 Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Mon, 18 Mar 2013 11:05:27 -0700 Subject: [PATCH 038/137] 8009536: G1: Apache Lucene hang during reference processing In CMTask::do_marking_step(), Skip offering termination and entering the first and second synchronization barriers if called from a serial context, i.e. the VM thread. Reviewed-by: brutisso, tschatzl --- .../gc_implementation/g1/concurrentMark.cpp | 186 +++++++++++------- .../gc_implementation/g1/concurrentMark.hpp | 6 +- 2 files changed, 116 insertions(+), 76 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 2a462481faa..63cb028da1f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1065,8 +1065,8 @@ public: double mark_step_duration_ms = G1ConcMarkStepDurationMillis; the_task->do_marking_step(mark_step_duration_ms, - true /* do_stealing */, - true /* do_termination */); + true /* do_termination */, + false /* is_serial*/); double end_time_sec = os::elapsedTime(); double end_vtime_sec = os::elapsedVTime(); @@ -2184,14 +2184,17 @@ bool G1CMIsAliveClosure::do_object_b(oop obj) { // operating on the global stack. class G1CMKeepAliveAndDrainClosure: public OopClosure { - ConcurrentMark* _cm; - CMTask* _task; - int _ref_counter_limit; - int _ref_counter; + ConcurrentMark* _cm; + CMTask* _task; + int _ref_counter_limit; + int _ref_counter; + bool _is_serial; public: - G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) : - _cm(cm), _task(task), _ref_counter_limit(G1RefProcDrainInterval) { + G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) : + _cm(cm), _task(task), _is_serial(is_serial), + _ref_counter_limit(G1RefProcDrainInterval) { assert(_ref_counter_limit > 0, "sanity"); + assert(!_is_serial || _task->worker_id() == 0, "only task 0 for serial code"); _ref_counter = _ref_counter_limit; } @@ -2230,8 +2233,8 @@ class G1CMKeepAliveAndDrainClosure: public OopClosure { do { double mark_step_duration_ms = G1ConcMarkStepDurationMillis; _task->do_marking_step(mark_step_duration_ms, - false /* do_stealing */, - false /* do_termination */); + false /* do_termination */, + _is_serial); } while (_task->has_aborted() && !_cm->has_overflown()); _ref_counter = _ref_counter_limit; } @@ -2253,27 +2256,18 @@ class G1CMKeepAliveAndDrainClosure: public OopClosure { class G1CMDrainMarkingStackClosure: public VoidClosure { ConcurrentMark* _cm; CMTask* _task; - bool _do_stealing; - bool _do_termination; + bool _is_serial; public: - G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_par) : - _cm(cm), _task(task) { - assert(is_par || _task->worker_id() == 0, - "Only task for worker 0 should be used if ref processing is single threaded"); - // We only allow stealing and only enter the termination protocol - // in CMTask::do_marking_step() if this closure is being instantiated - // for parallel reference processing. - _do_stealing = _do_termination = is_par; + G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) : + _cm(cm), _task(task), _is_serial(is_serial) { + assert(!_is_serial || _task->worker_id() == 0, "only task 0 for serial code"); } void do_void() { do { if (_cm->verbose_high()) { - gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - " - "stealing: %s, termination: %s", - _task->worker_id(), - BOOL_TO_STR(_do_stealing), - BOOL_TO_STR(_do_termination)); + gclog_or_tty->print_cr("\t[%u] Drain: Calling do_marking_step - serial: %s", + _task->worker_id(), BOOL_TO_STR(_is_serial)); } // We call CMTask::do_marking_step() to completely drain the local @@ -2294,8 +2288,8 @@ class G1CMDrainMarkingStackClosure: public VoidClosure { // has_aborted() flag that the marking step has completed. _task->do_marking_step(1000000000.0 /* something very large */, - _do_stealing, - _do_termination); + true /* do_termination */, + _is_serial); } while (_task->has_aborted() && !_cm->has_overflown()); } }; @@ -2328,7 +2322,6 @@ class G1CMRefProcTaskProxy: public AbstractGangTask { ProcessTask& _proc_task; G1CollectedHeap* _g1h; ConcurrentMark* _cm; - bool _processing_is_mt; public: G1CMRefProcTaskProxy(ProcessTask& proc_task, @@ -2336,15 +2329,15 @@ public: ConcurrentMark* cm) : AbstractGangTask("Process reference objects in parallel"), _proc_task(proc_task), _g1h(g1h), _cm(cm) { - ReferenceProcessor* rp = _g1h->ref_processor_cm(); - _processing_is_mt = rp->processing_is_mt(); - } + ReferenceProcessor* rp = _g1h->ref_processor_cm(); + assert(rp->processing_is_mt(), "shouldn't be here otherwise"); + } virtual void work(uint worker_id) { - CMTask* marking_task = _cm->task(worker_id); + CMTask* task = _cm->task(worker_id); G1CMIsAliveClosure g1_is_alive(_g1h); - G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task); - G1CMDrainMarkingStackClosure g1_par_drain(_cm, marking_task, _processing_is_mt); + G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, task, false /* is_serial */); + G1CMDrainMarkingStackClosure g1_par_drain(_cm, task, false /* is_serial */); _proc_task.work(worker_id, g1_is_alive, g1_par_keep_alive, g1_par_drain); } @@ -2415,26 +2408,35 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { rp->setup_policy(clear_all_soft_refs); assert(_markStack.isEmpty(), "mark stack should be empty"); - // Non-MT instances 'Keep Alive' and 'Complete GC' oop closures. - G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0)); - G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), false); - - // We need at least one active thread. If reference processing is - // not multi-threaded we use the current (ConcurrentMarkThread) thread, - // otherwise we use the work gang from the G1CollectedHeap and we - // utilize all the worker threads we can. - uint active_workers = (rp->processing_is_mt() && g1h->workers() != NULL - ? g1h->workers()->active_workers() - : 1U); + // Instances of the 'Keep Alive' and 'Complete GC' closures used + // in serial reference processing. Note these closures are also + // used for serially processing (by the the current thread) the + // JNI references during parallel reference processing. + // + // These closures do not need to synchronize with the worker + // threads involved in parallel reference processing as these + // instances are executed serially by the current thread (e.g. + // reference processing is not multi-threaded and is thus + // performed by the current thread instead of a gang worker). + // + // The gang tasks involved in parallel reference procssing create + // their own instances of these closures, which do their own + // synchronization among themselves. + G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0), true /* is_serial */); + G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), true /* is_serial */); + // We need at least one active thread. If reference processing + // is not multi-threaded we use the current (VMThread) thread, + // otherwise we use the work gang from the G1CollectedHeap and + // we utilize all the worker threads we can. + bool processing_is_mt = rp->processing_is_mt() && g1h->workers() != NULL; + uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U); active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U); + // Parallel processing task executor. G1CMRefProcTaskExecutor par_task_executor(g1h, this, g1h->workers(), active_workers); - - AbstractRefProcTaskExecutor* executor = (rp->processing_is_mt() - ? &par_task_executor - : NULL); + AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL); // Set the degree of MT processing here. If the discovery was done MT, // the number of threads involved during discovery could differ from @@ -2454,6 +2456,7 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { assert(_markStack.overflow() || _markStack.isEmpty(), "mark stack should be empty (unless it overflowed)"); + if (_markStack.overflow()) { // This should have been done already when we tried to push an // entry on to the global mark stack. But let's do it again. @@ -2482,8 +2485,8 @@ void ConcurrentMark::swapMarkBitMaps() { class CMRemarkTask: public AbstractGangTask { private: - ConcurrentMark *_cm; - + ConcurrentMark* _cm; + bool _is_serial; public: void work(uint worker_id) { // Since all available tasks are actually started, we should @@ -2493,8 +2496,8 @@ public: task->record_start_time(); do { task->do_marking_step(1000000000.0 /* something very large */, - true /* do_stealing */, - true /* do_termination */); + true /* do_termination */, + _is_serial); } while (task->has_aborted() && !_cm->has_overflown()); // If we overflow, then we do not want to restart. We instead // want to abort remark and do concurrent marking again. @@ -2502,8 +2505,8 @@ public: } } - CMRemarkTask(ConcurrentMark* cm, int active_workers) : - AbstractGangTask("Par Remark"), _cm(cm) { + CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) : + AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) { _cm->terminator()->reset_for_reuse(active_workers); } }; @@ -2530,20 +2533,26 @@ void ConcurrentMark::checkpointRootsFinalWork() { // constructor and pass values of the active workers // through the gang in the task. - CMRemarkTask remarkTask(this, active_workers); + CMRemarkTask remarkTask(this, active_workers, false /* is_serial */); + // We will start all available threads, even if we decide that the + // active_workers will be fewer. The extra ones will just bail out + // immediately. g1h->set_par_threads(active_workers); g1h->workers()->run_task(&remarkTask); g1h->set_par_threads(0); } else { G1CollectedHeap::StrongRootsScope srs(g1h); - // this is remark, so we'll use up all available threads uint active_workers = 1; set_phase(active_workers, false /* concurrent */); - CMRemarkTask remarkTask(this, active_workers); - // We will start all available threads, even if we decide that the - // active_workers will be fewer. The extra ones will just bail out - // immediately. + // Note - if there's no work gang then the VMThread will be + // the thread to execute the remark - serially. We have + // to pass true for the is_serial parameter so that + // CMTask::do_marking_step() doesn't enter the sync + // barriers in the event of an overflow. Doing so will + // cause an assert that the current thread is not a + // concurrent GC thread. + CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/); remarkTask.work(0); } SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); @@ -3854,8 +3863,8 @@ void CMTask::print_stats() { /***************************************************************************** - The do_marking_step(time_target_ms) method is the building block - of the parallel marking framework. It can be called in parallel + The do_marking_step(time_target_ms, ...) method is the building + block of the parallel marking framework. It can be called in parallel with other invocations of do_marking_step() on different tasks (but only one per task, obviously) and concurrently with the mutator threads, or during remark, hence it eliminates the need @@ -3865,7 +3874,7 @@ void CMTask::print_stats() { pauses too, since do_marking_step() ensures that it aborts before it needs to yield. - The data structures that is uses to do marking work are the + The data structures that it uses to do marking work are the following: (1) Marking Bitmap. If there are gray objects that appear only @@ -3951,11 +3960,25 @@ void CMTask::print_stats() { place, it was natural to piggy-back all the other conditions on it too and not constantly check them throughout the code. + If do_termination is true then do_marking_step will enter its + termination protocol. + + The value of is_serial must be true when do_marking_step is being + called serially (i.e. by the VMThread) and do_marking_step should + skip any synchronization in the termination and overflow code. + Examples include the serial remark code and the serial reference + processing closures. + + The value of is_serial must be false when do_marking_step is + being called by any of the worker threads in a work gang. + Examples include the concurrent marking code (CMMarkingTask), + the MT remark code, and the MT reference processing closures. + *****************************************************************************/ void CMTask::do_marking_step(double time_target_ms, - bool do_stealing, - bool do_termination) { + bool do_termination, + bool is_serial) { assert(time_target_ms >= 1.0, "minimum granularity is 1ms"); assert(concurrent() == _cm->concurrent(), "they should be the same"); @@ -3976,6 +3999,12 @@ void CMTask::do_marking_step(double time_target_ms, _start_time_ms = os::elapsedVTime() * 1000.0; statsOnly( _interval_start_time_ms = _start_time_ms ); + // If do_stealing is true then do_marking_step will attempt to + // steal work from the other CMTasks. It only makes sense to + // enable stealing when the termination protocol is enabled + // and do_marking_step() is not being called serially. + bool do_stealing = do_termination && !is_serial; + double diff_prediction_ms = g1_policy->get_new_prediction(&_marking_step_diffs_ms); _time_target_ms = time_target_ms - diff_prediction_ms; @@ -4237,10 +4266,12 @@ void CMTask::do_marking_step(double time_target_ms, } _termination_start_time_ms = os::elapsedVTime() * 1000.0; + // The CMTask class also extends the TerminatorTerminator class, // hence its should_exit_termination() method will also decide // whether to exit the termination protocol or not. - bool finished = _cm->terminator()->offer_termination(this); + bool finished = (is_serial || + _cm->terminator()->offer_termination(this)); double termination_end_time_ms = os::elapsedVTime() * 1000.0; _termination_time_ms += termination_end_time_ms - _termination_start_time_ms; @@ -4320,19 +4351,26 @@ void CMTask::do_marking_step(double time_target_ms, gclog_or_tty->print_cr("[%u] detected overflow", _worker_id); } - _cm->enter_first_sync_barrier(_worker_id); - // When we exit this sync barrier we know that all tasks have - // stopped doing marking work. So, it's now safe to - // re-initialise our data structures. At the end of this method, - // task 0 will clear the global data structures. + if (!is_serial) { + // We only need to enter the sync barrier if being called + // from a parallel context + _cm->enter_first_sync_barrier(_worker_id); + + // When we exit this sync barrier we know that all tasks have + // stopped doing marking work. So, it's now safe to + // re-initialise our data structures. At the end of this method, + // task 0 will clear the global data structures. + } statsOnly( ++_aborted_overflow ); // We clear the local state of this task... clear_region_fields(); - // ...and enter the second barrier. - _cm->enter_second_sync_barrier(_worker_id); + if (!is_serial) { + // ...and enter the second barrier. + _cm->enter_second_sync_barrier(_worker_id); + } // At this point everything has bee re-initialised and we're // ready to restart. } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index 61e64df8b9c..b8dd467b30b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -166,7 +166,7 @@ class CMBitMap : public CMBitMapRO { class CMMarkStack VALUE_OBJ_CLASS_SPEC { VirtualSpace _virtual_space; // Underlying backing store for actual stack ConcurrentMark* _cm; - oop* _base; // bottom of stack + oop* _base; // bottom of stack jint _index; // one more than last occupied index jint _capacity; // max #elements jint _saved_index; // value of _index saved at start of GC @@ -1146,7 +1146,9 @@ public: // trying not to exceed the given duration. However, it might exit // prematurely, according to some conditions (i.e. SATB buffers are // available for processing). - void do_marking_step(double target_ms, bool do_stealing, bool do_termination); + void do_marking_step(double target_ms, + bool do_termination, + bool is_serial); // These two calls start and stop the timer void record_start_time() { From 285ce3709b58f52fa242a9691ae6564afc368e5b Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Mon, 18 Mar 2013 22:10:11 +0400 Subject: [PATCH 039/137] 8000435: [macosx] Button painting error under Java 7 on Mac Reviewed-by: denis, alexsch --- .../com/apple/laf/AquaButtonBorder.java | 9 ++++- .../apple/laf/AquaButtonExtendedTypes.java | 40 +++++++++---------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaButtonBorder.java b/jdk/src/macosx/classes/com/apple/laf/AquaButtonBorder.java index b45b0ce6b98..80ccd72a00b 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaButtonBorder.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaButtonBorder.java @@ -83,14 +83,19 @@ public abstract class AquaButtonBorder extends AquaBorder implements Border, UIR painter.state.set(state); painter.state.set((state != State.DISABLED && state != State.INACTIVE) && b.isFocusPainted() && isFocused(b) ? Focused.YES : Focused.NO); + // Full border size of the component. + // g.setColor(new Color(0, 255, 0, 70)); + // g.drawRect(x, y, width - 1, height - 1); + final Insets subInsets = sizeVariant.insets; x += subInsets.left; y += subInsets.top; width -= (subInsets.left + subInsets.right); height -= (subInsets.top + subInsets.bottom); -// g.setColor(Color.magenta); -// g.drawRect(x, y, width - 1, height - 1); + // Where the native border should start to paint. + // g.setColor(new Color(255, 0, 255, 70)); + // g.drawRect(x, y, width - 1, height - 1); doButtonPaint(b, model, g, x, y, width, height); } diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java b/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java index 14350ada2a1..a370dc59932 100644 --- a/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java +++ b/jdk/src/macosx/classes/com/apple/laf/AquaButtonExtendedTypes.java @@ -184,30 +184,30 @@ public class AquaButtonExtendedTypes { new BorderDefinedTypeSpecifier("round", Widget.BUTTON_ROUND, new SizeVariant().alterInsets(2, 0, 0, 0).alterMinSize(28, 28), -3, -3, -3, -3), new BorderDefinedTypeSpecifier("texturedRound", Widget.BUTTON_ROUND_INSET, new SizeVariant().alterInsets(0, 0, 0, 0).alterMinSize(26, 26), -2, -2, 0, 0), - new SegmentedBorderDefinedTypeSpecifier("segmented-first", Widget.BUTTON_SEGMENTED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 16, 6, 10).alterInsets(5, 3, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmented-middle", Widget.BUTTON_SEGMENTED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 9, 6, 10).alterInsets(5, 0, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmented-last", Widget.BUTTON_SEGMENTED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 9, 6, 16).alterInsets(5, 0, 5, 3).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmented-only", Widget.BUTTON_SEGMENTED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 16, 6, 16).alterInsets(5, 3, 5, 3).alterMinSize(34, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmented-first", Widget.BUTTON_SEGMENTED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 16, 6, 10).alterInsets(2, 3, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmented-middle", Widget.BUTTON_SEGMENTED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 9, 6, 10).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmented-last", Widget.BUTTON_SEGMENTED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 9, 6, 16).alterInsets(2, 0, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmented-only", Widget.BUTTON_SEGMENTED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 16, 6, 16).alterInsets(2, 3, 2, 3).alterMinSize(34, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-first", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(5, 2, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-middle", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(5, 0, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-last", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(5, 0, 5, 2).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-only", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(5, 2, 5, 2).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-first", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-middle", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-last", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-only", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-first", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(5, 2, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-middle", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(5, 0, 5, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-last", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(5, 0, 5, 2).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-only", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(5, 2, 5, 2).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-first", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-middle", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-last", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-only", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-first", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(6, 3, 6, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-middle", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(6, 0, 6, 0).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-last", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(6, 0, 6, 3).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-only", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(6, 3, 6, 3).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-first", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 3, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-middle", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-last", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), + new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-only", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 3, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), - new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-first", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(5, 2, 5, 0).alterMinSize(0, 28), 0, 0, 0, 0), - new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-middle", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(5, 0, 5, 0).alterMinSize(0, 28), 0, 0, 0, 0), - new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-last", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(5, 0, 5, 2).alterMinSize(0, 28), 0, 0, 0, 0), - new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-only", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(5, 2, 5, 2).alterMinSize(34, 28), 0, 0, 0, 0), + new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-first", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, 0, 0, 0), + new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-middle", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, 0, 0, 0), + new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-last", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, 0, 0, 0), + new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-only", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(34, 28), 0, 0, 0, 0), new BorderDefinedTypeSpecifier("segmentedGradient-first", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-0,-2,-0))), new BorderDefinedTypeSpecifier("segmentedGradient-middle", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-1,-2,-0))), From f716ccd343662ac1ea86a20d8b6a3e55e878149f Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Tue, 19 Mar 2013 09:53:36 +0100 Subject: [PATCH 040/137] 8006637: Failure to filter out native frame events on Solaris Test is confused by other threads calling String.intern(). Add a thread filter to avoid this. Reviewed-by: sspitsyn, alanb --- jdk/test/com/sun/jdi/NativeInstanceFilter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/test/com/sun/jdi/NativeInstanceFilter.java b/jdk/test/com/sun/jdi/NativeInstanceFilter.java index eaa501a35fe..79029711190 100644 --- a/jdk/test/com/sun/jdi/NativeInstanceFilter.java +++ b/jdk/test/com/sun/jdi/NativeInstanceFilter.java @@ -57,6 +57,7 @@ public class NativeInstanceFilter extends JDIScaffold { static EventRequestManager requestManager = null; static MethodExitRequest request = null; + static ThreadReference mainThread = null; private void listen() { TargetAdapter adapter = new TargetAdapter() { @@ -77,6 +78,7 @@ public class NativeInstanceFilter extends JDIScaffold { requestManager.deleteEventRequest(request); request = requestManager.createMethodExitRequest(); request.addInstanceFilter(instance); + request.addThreadFilter(mainThread); request.enable(); } else if (instance != null && name.equals("intern")) { // If not for the filter, this will be called twice @@ -101,10 +103,12 @@ public class NativeInstanceFilter extends JDIScaffold { // VM has started, but hasn't started running the test program yet. requestManager = vm().eventRequestManager(); - ReferenceType referenceType = - resumeToPrepareOf("NativeInstanceFilterTarg").referenceType(); + ClassPrepareEvent e = resumeToPrepareOf("NativeInstanceFilterTarg"); + ReferenceType referenceType = e.referenceType(); + mainThread = e.thread(); request = requestManager.createMethodExitRequest(); + request.addThreadFilter(mainThread); request.enable(); listen(); From 8c5749843ce6606870f5437bcb7fa8508c5367db Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 19 Mar 2013 06:01:14 -0400 Subject: [PATCH 041/137] 8009426: "profiles" target fails due to nashorn if "images" is not built first Reviewed-by: alanb --- jdk/makefiles/CreateJars.gmk | 4 ---- jdk/makefiles/Profiles.gmk | 3 +-- jdk/makefiles/profile-includes.txt | 2 ++ 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 685215ae24b..61edcfa783d 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -76,8 +76,6 @@ $(eval $(call SetupArchive,BUILD_DNS_JAR,,\ $(IMAGES_OUTPUTDIR)/lib/tzdb.jar: $(JDK_OUTPUTDIR)/lib/tzdb.jar $(install-file) -JARS += $(IMAGES_OUTPUTDIR)/lib/tzdb.jar - ########################################################################################## LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in is it \ @@ -1120,8 +1118,6 @@ endif $(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar: $(NASHORN_DIST)/nashorn.jar $(install-file) -JARS += $(IMAGES_OUTPUTDIR)/lib/ext/nashorn.jar - ########################################################################################## -include $(CUSTOM_MAKE_DIR)/CreateJars.gmk diff --git a/jdk/makefiles/Profiles.gmk b/jdk/makefiles/Profiles.gmk index b4fb673ddf3..316d2d34329 100644 --- a/jdk/makefiles/Profiles.gmk +++ b/jdk/makefiles/Profiles.gmk @@ -84,7 +84,7 @@ FULL_JRE_JARS := \ # The full set of "jar" files needed for a complete JDK (ct.sym and src.zip # are also included.) # Note we need to add back the regular form of all the custom profile jars e.g. -# rt.jar and resources.jar +# rt.jar and resources.jar that we filtered out above ALL_JARS := $(FULL_JRE_JARS) \ $(IMAGES_OUTPUTDIR)/lib/rt.jar \ @@ -94,7 +94,6 @@ ALL_JARS := $(FULL_JRE_JARS) \ $(IMAGES_OUTPUTDIR)/lib/tools.jar \ $(IMAGES_OUTPUTDIR)/lib/ct.sym \ $(IMAGES_OUTPUTDIR)/src.zip \ - $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar \ $(IMAGES_OUTPUTDIR)/lib/sa-jdi.jar ifeq ($(OPENJDK_TARGET_OS),solaris) diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index de506edfd0a..53453e3ded8 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -178,6 +178,7 @@ FULL_JRE_LIB_FILES := \ cmm/sRGB.pf \ ext/cldrdata.jar \ ext/dnsns.jar \ + ext/nashorn.jar \ ext/sunec.jar \ ext/sunpkcs11.jar \ ext/zipfs.jar \ @@ -251,6 +252,7 @@ FULL_JRE_JAR_FILES := \ charsets.jar \ ext/cldrdata.jar \ ext/dnsns.jar \ + ext/nashorn.jar \ ext/sunec.jar \ ext/sunpkcs11.jar \ ext/zipfs.jar From 08e50cc4ce228d9746ca224f48fc63f94119595c Mon Sep 17 00:00:00 2001 From: John Zavgren Date: Mon, 18 Mar 2013 14:21:13 -0400 Subject: [PATCH 042/137] 8007607: security native code doesn't always use malloc, realloc, and calloc correctly Reviewed-by: chegar, dsamersoff, valeriep --- .../sun/security/jgss/wrapper/GSSLibStub.c | 44 ++++++++++++++++--- .../sun/security/jgss/wrapper/NativeUtil.c | 12 +++++ .../com/sun/security/auth/module/Solaris.c | 17 +++++-- .../com/sun/security/auth/module/Unix.c | 18 ++++++-- .../native/sun/security/smartcardio/pcsc_md.c | 3 -- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c b/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c index 33cd3644e97..541a1d3edc2 100644 --- a/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c +++ b/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c @@ -27,8 +27,22 @@ #include "NativeUtil.h" #include "NativeFunc.h" #include "jlong.h" +#include -/* Constants for indicating what type of info is needed for inqueries */ +/* Throws a Java Exception by name */ + +void throwByName(JNIEnv *env, const char *name, const char *msg) { + jclass cls = (*env)->FindClass(env, name); + + if (cls != 0) /* Otherwise an exception has already been thrown */ + (*env)->ThrowNew(env, cls, msg); +} + +void throwOutOfMemoryError(JNIEnv *env, const char *message) { + throwByName(env, "java/lang/OutOfMemoryError", message); +} + +/* Constants for indicating what type of info is needed for inquiries */ const int TYPE_CRED_NAME = 10; const int TYPE_CRED_TIME = 11; const int TYPE_CRED_USAGE = 12; @@ -117,7 +131,14 @@ gss_channel_bindings_t getGSSCB(JNIEnv *env, jobject jcb) { if (jcb == NULL) { return GSS_C_NO_CHANNEL_BINDINGS; } + cb = malloc(sizeof(struct gss_channel_bindings_struct)); + + if (cb == NULL) { + throwOutOfMemoryError(env,NULL); + return NULL; + } + /* set up initiator address */ jinetAddr = (*env)->CallObjectMethod(env, jcb, @@ -301,12 +322,15 @@ Java_sun_security_jgss_wrapper_GSSLibStub_importName(JNIEnv *env, gss_buffer_desc nameVal; gss_OID nameType; gss_name_t nameHdl; + nameHdl = GSS_C_NO_NAME; debug(env, "[GSSLibStub_importName]"); initGSSBuffer(env, jnameVal, &nameVal); nameType = newGSSOID(env, jnameType); - nameHdl = GSS_C_NO_NAME; + if ((*env)->ExceptionCheck(env)) { + return jlong_zero; + } /* gss_import_name(...) => GSS_S_BAD_NAMETYPE, GSS_S_BAD_NAME, GSS_S_BAD_MECH */ @@ -509,15 +533,18 @@ Java_sun_security_jgss_wrapper_GSSLibStub_acquireCred(JNIEnv *env, gss_cred_usage_t credUsage; gss_name_t nameHdl; gss_cred_id_t credHdl; + credHdl = GSS_C_NO_CREDENTIAL; debug(env, "[GSSLibStub_acquireCred]"); mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech)); mechs = newGSSOIDSet(env, mech); + if ((*env)->ExceptionCheck(env)) { + return jlong_zero; + } credUsage = (gss_cred_usage_t) usage; nameHdl = (gss_name_t) jlong_to_ptr(pName); - credHdl = GSS_C_NO_CREDENTIAL; sprintf(debugBuf, "[GSSLibStub_acquireCred] pName=%ld, usage=%d", (long) pName, usage); @@ -628,7 +655,7 @@ Java_sun_security_jgss_wrapper_GSSLibStub_getCredName(JNIEnv *env, /* return immediately if an exception has occurred */ if ((*env)->ExceptionCheck(env)) { - return 0; + return jlong_zero; } sprintf(debugBuf, "[GSSLibStub_getCredName] pName=%ld", (long) nameHdl); @@ -795,6 +822,10 @@ Java_sun_security_jgss_wrapper_GSSLibStub_initContext(JNIEnv *env, time = getGSSTime((*env)->GetIntField(env, jcontextSpi, FID_NativeGSSContext_lifetime)); cb = getGSSCB(env, jcb); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } + initGSSBuffer(env, jinToken, &inToken); sprintf(debugBuf, @@ -895,6 +926,9 @@ Java_sun_security_jgss_wrapper_GSSLibStub_acceptContext(JNIEnv *env, credHdl = (gss_cred_id_t) jlong_to_ptr(pCred); initGSSBuffer(env, jinToken, &inToken); cb = getGSSCB(env, jcb); + if ((*env)->ExceptionCheck(env)) { + return NULL; + } srcName = GSS_C_NO_NAME; delCred = GSS_C_NO_CREDENTIAL; setTarget = (credHdl == GSS_C_NO_CREDENTIAL); @@ -1130,7 +1164,7 @@ Java_sun_security_jgss_wrapper_GSSLibStub_getContextName(JNIEnv *env, checkStatus(env, jobj, major, minor, "[GSSLibStub_inquireContextAll]"); /* return immediately if an exception has occurred */ if ((*env)->ExceptionCheck(env)) { - return ptr_to_jlong(NULL); + return jlong_zero; } sprintf(debugBuf, "[GSSLibStub_getContextName] pName=%ld", (long) nameHdl); diff --git a/jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c b/jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c index 7c15ed6e1c8..e5edfbcc957 100644 --- a/jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c +++ b/jdk/src/share/native/sun/security/jgss/wrapper/NativeUtil.c @@ -26,6 +26,9 @@ #include "NativeUtil.h" #include "NativeFunc.h" #include "jlong.h" +#include + +extern void throwOutOfMemoryError(JNIEnv *env, const char *message); const int JAVA_DUPLICATE_TOKEN_CODE = 19; /* DUPLICATE_TOKEN */ const int JAVA_OLD_TOKEN_CODE = 20; /* OLD_TOKEN */ @@ -615,8 +618,17 @@ gss_OID newGSSOID(JNIEnv *env, jobject jOid) { (*env)->Throw(env, gssEx); } cOid = malloc(sizeof(struct gss_OID_desc_struct)); + if (cOid == NULL) { + throwOutOfMemoryError(env,NULL); + return GSS_C_NO_OID; + } cOid->length = (*env)->GetArrayLength(env, jbytes) - 2; cOid->elements = malloc(cOid->length); + if (cOid->elements == NULL) { + throwOutOfMemoryError(env,NULL); + free(cOid); + return GSS_C_NO_OID; + } (*env)->GetByteArrayRegion(env, jbytes, 2, cOid->length, cOid->elements); (*env)->DeleteLocalRef(env, jbytes); diff --git a/jdk/src/solaris/native/com/sun/security/auth/module/Solaris.c b/jdk/src/solaris/native/com/sun/security/auth/module/Solaris.c index 169d76bf35e..3e31e7ff125 100644 --- a/jdk/src/solaris/native/com/sun/security/auth/module/Solaris.c +++ b/jdk/src/solaris/native/com/sun/security/auth/module/Solaris.c @@ -31,6 +31,7 @@ #include #include #include + JNIEXPORT void JNICALL Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo (JNIEnv *env, jobject obj) { @@ -39,13 +40,23 @@ Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo char pwd_buf[1024]; struct passwd pwd; jsize numSuppGroups = getgroups(0, NULL); - gid_t *groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); - jfieldID fid; jstring jstr; jlongArray jgroups; jlong *jgroupsAsArray; - jclass cls = (*env)->GetObjectClass(env, obj); + gid_t *groups; + jclass cls; + + groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); + + if (groups == NULL) { + jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError"); + if(cls != 0) + (*env)->ThrowNew(env, cls, NULL); + return; + } + + cls = (*env)->GetObjectClass(env, obj); memset(pwd_buf, 0, sizeof(pwd_buf)); if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) != NULL && diff --git a/jdk/src/solaris/native/com/sun/security/auth/module/Unix.c b/jdk/src/solaris/native/com/sun/security/auth/module/Unix.c index 6af63a2f39e..620e19bb236 100644 --- a/jdk/src/solaris/native/com/sun/security/auth/module/Unix.c +++ b/jdk/src/solaris/native/com/sun/security/auth/module/Unix.c @@ -44,9 +44,6 @@ Java_com_sun_security_auth_module_UnixSystem_getUnixInfo char pwd_buf[1024]; struct passwd *pwd; struct passwd resbuf; - jsize numSuppGroups = getgroups(0, NULL); - gid_t *groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); - jfieldID userNameID; jfieldID userID; jfieldID groupID; @@ -55,7 +52,20 @@ Java_com_sun_security_auth_module_UnixSystem_getUnixInfo jstring jstr; jlongArray jgroups; jlong *jgroupsAsArray; - jclass cls = (*env)->GetObjectClass(env, obj); + jsize numSuppGroups; + gid_t *groups; + jclass cls; + + numSuppGroups = getgroups(0, NULL); + groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); + if (groups == NULL) { + jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError"); + if(cls != 0) + (*env)->ThrowNew(env, cls, NULL); + return; + } + + cls = (*env)->GetObjectClass(env, obj); memset(pwd_buf, 0, sizeof(pwd_buf)); diff --git a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c index 589f3e3dd75..6f1021c7ce4 100644 --- a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c +++ b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c @@ -32,8 +32,6 @@ #include -#include - #include "sun_security_smartcardio_PlatformPCSC.h" #include "pcsc_md.h" @@ -77,7 +75,6 @@ void throwIOException(JNIEnv *env, const char *msg) throwByName(env, "java/io/IOException", msg); } - void *findFunction(JNIEnv *env, void *hModule, char *functionName) { void *fAddress = dlsym(hModule, functionName); if (fAddress == NULL) { From 4bb3e82052380b6d655c33c278db0e813897a142 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 18 Mar 2013 19:34:35 -0400 Subject: [PATCH 043/137] 8008783: Modifications needed to JPRT to allow for building hard float abi and new bundle changes Reviewed-by: twisti, collins, bobv, jwilhelm --- hotspot/make/jprt.properties | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties index fa65aa1bc7d..8bf107758c9 100644 --- a/hotspot/make/jprt.properties +++ b/hotspot/make/jprt.properties @@ -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 @@ -97,15 +97,18 @@ jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6 jprt.my.linux.ppcsflt.jdk7u8=${jprt.my.linux.ppcsflt.jdk7} jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}} -jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6 -jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6 -jprt.my.linux.armvfp.jdk7u8=${jprt.my.linux.armvfp.jdk7} -jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}} +jprt.my.linux.armvfpsflt.jdk8=linux_armvfpsflt_2.6 +jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}} -jprt.my.linux.armv6.jdk8=linux_armv6_2.6 -jprt.my.linux.armv6.jdk7=linux_armv6_2.6 -jprt.my.linux.armv6.jdk7u8=${jprt.my.linux.armv6.jdk7} -jprt.my.linux.armv6=${jprt.my.linux.armv6.${jprt.tools.default.release}} +jprt.my.linux.armvfphflt.jdk8=linux_armvfphflt_2.6 +jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}} + +# The ARM GP vfp-sflt build is not currently supported +#jprt.my.linux.armvs.jdk8=linux_armvs_2.6 +#jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}} + +jprt.my.linux.armvh.jdk8=linux_armvh_2.6 +jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}} jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6 jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6 @@ -139,7 +142,7 @@ jprt.build.targets.standard= \ ${jprt.my.macosx.x64}-{product|fastdebug|debug}, \ ${jprt.my.windows.i586}-{product|fastdebug|debug}, \ ${jprt.my.windows.x64}-{product|fastdebug|debug}, \ - ${jprt.my.linux.armv6}-{product|fastdebug} + ${jprt.my.linux.armvh}-{product|fastdebug} jprt.build.targets.open= \ ${jprt.my.solaris.i586}-{productOpen}, \ @@ -151,7 +154,8 @@ jprt.build.targets.embedded= \ ${jprt.my.linux.ppc}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \ - ${jprt.my.linux.armvfp}-{productEmb|fastdebugEmb}, \ + ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \ + ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}, \ ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb} jprt.build.targets.all=${jprt.build.targets.standard}, \ From 2b3155346ca5efb646354373c871ec964dcaddd7 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 18 Mar 2013 18:34:44 -0700 Subject: [PATCH 044/137] 8007803: Implement javax.lang.model API for Type Annotations Reviewed-by: darcy --- .../internal/jxc/model/nav/ApNavigator.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java index ff450c9a0e7..da1cf800e89 100644 --- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java +++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/model/nav/ApNavigator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -31,7 +31,9 @@ import com.sun.source.util.Trees; import com.sun.xml.internal.bind.v2.model.nav.Navigator; import com.sun.xml.internal.bind.v2.runtime.Location; +import java.lang.annotation.Annotation; import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -372,6 +374,21 @@ public class ApNavigator implements Navigator getAnnotationMirrors() { + throw new IllegalStateException(); + } + + @Override + public A getAnnotation(Class annotationType) { + throw new IllegalStateException(); + } + + @Override + public A[] getAnnotationsByType(Class annotationType) { + throw new IllegalStateException(); + } }; public Location getClassLocation(TypeElement typeElement) { From 9164834d731f0ac504382a29a8f0e1c8d8c6236c Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Tue, 19 Mar 2013 00:57:39 -0700 Subject: [PATCH 045/137] 8009940: G1: assert(_finger == _heap_end) failed, concurrentMark.cpp:809 Skip reference processing if the global marking stack overflows during remark. Refactor and rename set_phase(); move code that sets the concurrency level into its own routine. Do not call set_phase() from within parallel reference processing; use the concurrency level routine instead. The marking state should only set reset by CMTask[0] during the concurrent phase of the marking cycle; if an overflow occurs at any stage during the remark, the marking state will be reset after reference processing. Reviewed-by: brutisso, jmasa --- .../gc_implementation/g1/concurrentMark.cpp | 88 +++++++++++++------ .../gc_implementation/g1/concurrentMark.hpp | 5 +- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 63cb028da1f..d98b06ac705 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -784,7 +784,7 @@ void ConcurrentMark::reset_marking_state(bool clear_overflow) { } } -void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { +void ConcurrentMark::set_concurrency(uint active_tasks) { assert(active_tasks <= _max_worker_id, "we should not have more"); _active_tasks = active_tasks; @@ -793,6 +793,10 @@ void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues); _first_overflow_barrier_sync.set_n_workers((int) active_tasks); _second_overflow_barrier_sync.set_n_workers((int) active_tasks); +} + +void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurrent) { + set_concurrency(active_tasks); _concurrent = concurrent; // We propagate this to all tasks, not just the active ones. @@ -806,7 +810,9 @@ void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { // false before we start remark. At this point we should also be // in a STW phase. assert(!concurrent_marking_in_progress(), "invariant"); - assert(_finger == _heap_end, "only way to get here"); + assert(_finger == _heap_end, + err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, + _finger, _heap_end)); update_g1_committed(true); } } @@ -974,20 +980,28 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) { gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); } - // let the task associated with with worker 0 do this - if (worker_id == 0) { - // task 0 is responsible for clearing the global data structures - // We should be here because of an overflow. During STW we should - // not clear the overflow flag since we rely on it being true when - // we exit this method to abort the pause and restart concurent - // marking. - reset_marking_state(concurrent() /* clear_overflow */); - force_overflow()->update(); + // If we're executing the concurrent phase of marking, reset the marking + // state; otherwise the marking state is reset after reference processing, + // during the remark pause. + // If we reset here as a result of an overflow during the remark we will + // see assertion failures from any subsequent set_concurrency_and_phase() + // calls. + if (concurrent()) { + // let the task associated with with worker 0 do this + if (worker_id == 0) { + // task 0 is responsible for clearing the global data structures + // We should be here because of an overflow. During STW we should + // not clear the overflow flag since we rely on it being true when + // we exit this method to abort the pause and restart concurent + // marking. + reset_marking_state(true /* clear_overflow */); + force_overflow()->update(); - if (G1Log::fine()) { - gclog_or_tty->date_stamp(PrintGCDateStamps); - gclog_or_tty->stamp(PrintGCTimeStamps); - gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); + if (G1Log::fine()) { + gclog_or_tty->date_stamp(PrintGCDateStamps); + gclog_or_tty->stamp(PrintGCTimeStamps); + gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); + } } } @@ -1007,7 +1021,7 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) { if (concurrent()) { ConcurrentGCThread::stsJoin(); } - // at this point everything should be re-initialised and ready to go + // at this point everything should be re-initialized and ready to go if (verbose_low()) { gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); @@ -1222,8 +1236,8 @@ void ConcurrentMark::markFromRoots() { uint active_workers = MAX2(1U, parallel_marking_threads()); - // Parallel task terminator is set in "set_phase()" - set_phase(active_workers, true /* concurrent */); + // Parallel task terminator is set in "set_concurrency_and_phase()" + set_concurrency_and_phase(active_workers, true /* concurrent */); CMConcurrentMarkingTask markingTask(this, cmThread()); if (use_parallel_marking_threads()) { @@ -2349,9 +2363,11 @@ void G1CMRefProcTaskExecutor::execute(ProcessTask& proc_task) { G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm); - // We need to reset the phase for each task execution so that - // the termination protocol of CMTask::do_marking_step works. - _cm->set_phase(_active_workers, false /* concurrent */); + // We need to reset the concurrency level before each + // proxy task execution, so that the termination protocol + // and overflow handling in CMTask::do_marking_step() knows + // how many workers to wait for. + _cm->set_concurrency(_active_workers); _g1h->set_par_threads(_active_workers); _workers->run_task(&proc_task_proxy); _g1h->set_par_threads(0); @@ -2377,12 +2393,29 @@ void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) { G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); + // Not strictly necessary but... + // + // We need to reset the concurrency level before each + // proxy task execution, so that the termination protocol + // and overflow handling in CMTask::do_marking_step() knows + // how many workers to wait for. + _cm->set_concurrency(_active_workers); _g1h->set_par_threads(_active_workers); _workers->run_task(&enq_task_proxy); _g1h->set_par_threads(0); } void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { + if (has_overflown()) { + // Skip processing the discovered references if we have + // overflown the global marking stack. Reference objects + // only get discovered once so it is OK to not + // de-populate the discovered reference lists. We could have, + // but the only benefit would be that, when marking restarts, + // less reference objects are discovered. + return; + } + ResourceMark rm; HandleMark hm; @@ -2438,6 +2471,10 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { g1h->workers(), active_workers); AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL); + // Set the concurrency level. The phase was already set prior to + // executing the remark task. + set_concurrency(active_workers); + // Set the degree of MT processing here. If the discovery was done MT, // the number of threads involved during discovery could differ from // the number of active workers. This is OK as long as the discovered @@ -2527,7 +2564,7 @@ void ConcurrentMark::checkpointRootsFinalWork() { active_workers = (uint) ParallelGCThreads; g1h->workers()->set_active_workers(active_workers); } - set_phase(active_workers, false /* concurrent */); + set_concurrency_and_phase(active_workers, false /* concurrent */); // Leave _parallel_marking_threads at it's // value originally calculated in the ConcurrentMark // constructor and pass values of the active workers @@ -2543,7 +2580,7 @@ void ConcurrentMark::checkpointRootsFinalWork() { } else { G1CollectedHeap::StrongRootsScope srs(g1h); uint active_workers = 1; - set_phase(active_workers, false /* concurrent */); + set_concurrency_and_phase(active_workers, false /* concurrent */); // Note - if there's no work gang then the VMThread will be // the thread to execute the remark - serially. We have @@ -3923,7 +3960,7 @@ void CMTask::print_stats() { (2) When a global overflow (on the global stack) has been triggered. Before the task aborts, it will actually sync up with the other tasks to ensure that all the marking data structures - (local queues, stacks, fingers etc.) are re-initialised so that + (local queues, stacks, fingers etc.) are re-initialized so that when do_marking_step() completes, the marking phase can immediately restart. @@ -4371,7 +4408,8 @@ void CMTask::do_marking_step(double time_target_ms, // ...and enter the second barrier. _cm->enter_second_sync_barrier(_worker_id); } - // At this point everything has bee re-initialised and we're + // At this point, if we're during the concurrent phase of + // marking, everything has been re-initialized and we're // ready to restart. } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp index b8dd467b30b..43554a5c991 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp @@ -491,9 +491,12 @@ protected: // structures are initialised to a sensible and predictable state. void set_non_marking_state(); + // Called to indicate how many threads are currently active. + void set_concurrency(uint active_tasks); + // It should be called to indicate which phase we're in (concurrent // mark or remark) and how many threads are currently active. - void set_phase(uint active_tasks, bool concurrent); + void set_concurrency_and_phase(uint active_tasks, bool concurrent); // prints all gathered CM-related statistics void print_stats(); From e6e67652d9bfe057d241c368e84bdfba0e110c87 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Tue, 19 Mar 2013 10:31:16 +0100 Subject: [PATCH 046/137] 8010121: Remove definition of ShouldNotReachHere2(msg) Reviewed-by: kvn, stefank, rbackman, twisti --- hotspot/src/share/vm/memory/sharedHeap.cpp | 2 +- hotspot/src/share/vm/oops/fieldInfo.hpp | 26 +++++++++++----------- hotspot/src/share/vm/utilities/debug.cpp | 4 ---- hotspot/src/share/vm/utilities/debug.hpp | 7 ------ 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index be641d304ba..caef7ac7ad0 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -178,7 +178,7 @@ void SharedHeap::process_strong_roots(bool activate_scope, SystemDictionary::always_strong_oops_do(roots); ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging); } else { - ShouldNotReachHere2("We should always have selected either SO_AllClasses or SO_SystemClasses"); + fatal("We should always have selected either SO_AllClasses or SO_SystemClasses"); } } diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp index 331dc05f37c..5da8ed9628a 100644 --- a/hotspot/src/share/vm/oops/fieldInfo.hpp +++ b/hotspot/src/share/vm/oops/fieldInfo.hpp @@ -108,11 +108,11 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE; #ifndef PRODUCT case FIELDINFO_TAG_TYPE_PLAIN: - ShouldNotReachHere2("Asking offset for the plain type field"); + fatal("Asking offset for the plain type field"); case FIELDINFO_TAG_TYPE_CONTENDED: - ShouldNotReachHere2("Asking offset for the contended type field"); + fatal("Asking offset for the contended type field"); case FIELDINFO_TAG_BLANK: - ShouldNotReachHere2("Asking offset for the blank field"); + fatal("Asking offset for the blank field"); #endif } ShouldNotReachHere(); @@ -128,9 +128,9 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return true; #ifndef PRODUCT case FIELDINFO_TAG_OFFSET: - ShouldNotReachHere2("Asking contended flag for the field with offset"); + fatal("Asking contended flag for the field with offset"); case FIELDINFO_TAG_BLANK: - ShouldNotReachHere2("Asking contended flag for the blank field"); + fatal("Asking contended flag for the blank field"); #endif } ShouldNotReachHere(); @@ -146,9 +146,9 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return _shorts[high_packed_offset]; #ifndef PRODUCT case FIELDINFO_TAG_OFFSET: - ShouldNotReachHere2("Asking the contended group for the field with offset"); + fatal("Asking the contended group for the field with offset"); case FIELDINFO_TAG_BLANK: - ShouldNotReachHere2("Asking the contended group for the blank field"); + fatal("Asking the contended group for the blank field"); #endif } ShouldNotReachHere(); @@ -163,9 +163,9 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return (lo >> FIELDINFO_TAG_SIZE); #ifndef PRODUCT case FIELDINFO_TAG_OFFSET: - ShouldNotReachHere2("Asking the field type for field with offset"); + fatal("Asking the field type for field with offset"); case FIELDINFO_TAG_BLANK: - ShouldNotReachHere2("Asking the field type for the blank field"); + fatal("Asking the field type for the blank field"); #endif } ShouldNotReachHere(); @@ -211,7 +211,7 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { case FIELDINFO_TAG_TYPE_PLAIN: case FIELDINFO_TAG_TYPE_CONTENDED: case FIELDINFO_TAG_OFFSET: - ShouldNotReachHere2("Setting the field type with overwriting"); + fatal("Setting the field type with overwriting"); #endif } ShouldNotReachHere(); @@ -226,11 +226,11 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return; #ifndef PRODUCT case FIELDINFO_TAG_TYPE_CONTENDED: - ShouldNotReachHere2("Overwriting contended group"); + fatal("Overwriting contended group"); case FIELDINFO_TAG_BLANK: - ShouldNotReachHere2("Setting contended group for the blank field"); + fatal("Setting contended group for the blank field"); case FIELDINFO_TAG_OFFSET: - ShouldNotReachHere2("Setting contended group for field with offset"); + fatal("Setting contended group for field with offset"); #endif } ShouldNotReachHere(); diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp index 131f08d44bd..e74475fc3c9 100644 --- a/hotspot/src/share/vm/utilities/debug.cpp +++ b/hotspot/src/share/vm/utilities/debug.cpp @@ -248,10 +248,6 @@ void report_should_not_reach_here(const char* file, int line) { report_vm_error(file, line, "ShouldNotReachHere()"); } -void report_should_not_reach_here2(const char* file, int line, const char* message) { - report_vm_error(file, line, "ShouldNotReachHere()", message); -} - void report_unimplemented(const char* file, int line) { report_vm_error(file, line, "Unimplemented()"); } diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp index 515b1286b98..0c718a2fe2f 100644 --- a/hotspot/src/share/vm/utilities/debug.hpp +++ b/hotspot/src/share/vm/utilities/debug.hpp @@ -192,12 +192,6 @@ do { \ BREAKPOINT; \ } while (0) -#define ShouldNotReachHere2(message) \ -do { \ - report_should_not_reach_here2(__FILE__, __LINE__, message); \ - BREAKPOINT; \ -} while (0) - #define Unimplemented() \ do { \ report_unimplemented(__FILE__, __LINE__); \ @@ -218,7 +212,6 @@ void report_vm_out_of_memory(const char* file, int line, size_t size, const char* message); void report_should_not_call(const char* file, int line); void report_should_not_reach_here(const char* file, int line); -void report_should_not_reach_here2(const char* file, int line, const char* message); void report_unimplemented(const char* file, int line); void report_untested(const char* file, int line, const char* message); From 4fdb8216ace06c4edab01be5ab0860a7eae472ed Mon Sep 17 00:00:00 2001 From: Yunda Date: Tue, 19 Mar 2013 13:41:05 +0100 Subject: [PATCH 047/137] 8009456: SA: typeToVtbl of BasicTypeDataBase should not be static Reviewed-by: coleenp, sla --- .../jvm/hotspot/types/basic/BasicTypeDataBase.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java index f88335c1bff..12325863163 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java @@ -24,10 +24,15 @@ package sun.jvm.hotspot.types.basic; -import java.util.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.types.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.debugger.MachineDescription; import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; /**

This is a basic implementation of the TypeDataBase interface. It allows an external type database builder to add types to be @@ -150,7 +155,7 @@ public class BasicTypeDataBase implements TypeDataBase { return VM.getVM().getOopSize(); } - static HashMap typeToVtbl = new HashMap(); + HashMap typeToVtbl = new HashMap(); private Address vtblForType(Type type) { Address vtblAddr = (Address)typeToVtbl.get(type); From 3630c6a127918a7b0a4d02140bcd7e66debf866e Mon Sep 17 00:00:00 2001 From: Yunda Date: Tue, 19 Mar 2013 13:44:26 +0100 Subject: [PATCH 048/137] 8009457: SA: A small fix on "scanoops" command in CLHSDB Reviewed-by: sla, coleenp, kmo --- .../sun/jvm/hotspot/CommandProcessor.java | 99 ++++++++++++++----- 1 file changed, 74 insertions(+), 25 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 8c73ca4d0fd..2233844267c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -24,36 +24,81 @@ package sun.jvm.hotspot; -import java.io.*; -import java.math.*; -import java.util.*; -import java.util.regex.*; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import sun.jvm.hotspot.types.Type; -import sun.jvm.hotspot.types.Field; -import sun.jvm.hotspot.HotSpotTypeDataBase; -import sun.jvm.hotspot.types.basic.BasicType; -import sun.jvm.hotspot.types.basic.BasicTypeDataBase; -import sun.jvm.hotspot.types.CIntegerType; -import sun.jvm.hotspot.code.*; -import sun.jvm.hotspot.compiler.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.interpreter.*; -import sun.jvm.hotspot.memory.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.opto.*; -import sun.jvm.hotspot.ci.*; -import sun.jvm.hotspot.asm.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.utilities.*; -import sun.jvm.hotspot.utilities.soql.*; -import sun.jvm.hotspot.ui.classbrowser.*; -import sun.jvm.hotspot.ui.tree.*; -import sun.jvm.hotspot.tools.*; +import sun.jvm.hotspot.ci.ciEnv; +import sun.jvm.hotspot.code.CodeBlob; +import sun.jvm.hotspot.code.CodeCacheVisitor; +import sun.jvm.hotspot.code.NMethod; +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.debugger.OopHandle; +import sun.jvm.hotspot.memory.SymbolTable; +import sun.jvm.hotspot.memory.SystemDictionary; +import sun.jvm.hotspot.memory.Universe; +import sun.jvm.hotspot.oops.DefaultHeapVisitor; +import sun.jvm.hotspot.oops.HeapVisitor; +import sun.jvm.hotspot.oops.InstanceKlass; +import sun.jvm.hotspot.oops.Klass; +import sun.jvm.hotspot.oops.Metadata; +import sun.jvm.hotspot.oops.Method; +import sun.jvm.hotspot.oops.MethodData; +import sun.jvm.hotspot.oops.Oop; +import sun.jvm.hotspot.oops.RawHeapVisitor; +import sun.jvm.hotspot.oops.Symbol; +import sun.jvm.hotspot.oops.UnknownOopException; +import sun.jvm.hotspot.opto.Compile; +import sun.jvm.hotspot.opto.InlineTree; +import sun.jvm.hotspot.runtime.CompiledVFrame; +import sun.jvm.hotspot.runtime.CompilerThread; +import sun.jvm.hotspot.runtime.JavaThread; +import sun.jvm.hotspot.runtime.JavaVFrame; +import sun.jvm.hotspot.runtime.Threads; +import sun.jvm.hotspot.runtime.VM; import sun.jvm.hotspot.tools.ObjectHistogram; +import sun.jvm.hotspot.tools.PMap; +import sun.jvm.hotspot.tools.PStack; import sun.jvm.hotspot.tools.StackTrace; import sun.jvm.hotspot.tools.jcore.ClassDump; import sun.jvm.hotspot.tools.jcore.ClassFilter; +import sun.jvm.hotspot.types.CIntegerType; +import sun.jvm.hotspot.types.Field; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.basic.BasicType; +import sun.jvm.hotspot.ui.classbrowser.HTMLGenerator; +import sun.jvm.hotspot.ui.tree.CTypeTreeNodeAdapter; +import sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter; +import sun.jvm.hotspot.ui.tree.SimpleTreeNode; +import sun.jvm.hotspot.utilities.AddressOps; +import sun.jvm.hotspot.utilities.Assert; +import sun.jvm.hotspot.utilities.HeapProgressThunk; +import sun.jvm.hotspot.utilities.LivenessPathElement; +import sun.jvm.hotspot.utilities.MethodArray; +import sun.jvm.hotspot.utilities.ObjectReader; +import sun.jvm.hotspot.utilities.PointerFinder; +import sun.jvm.hotspot.utilities.PointerLocation; +import sun.jvm.hotspot.utilities.ReversePtrs; +import sun.jvm.hotspot.utilities.ReversePtrsAnalysis; +import sun.jvm.hotspot.utilities.RobustOopDeterminator; +import sun.jvm.hotspot.utilities.SystemDictionaryHelper; +import sun.jvm.hotspot.utilities.soql.JSJavaFactory; +import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl; +import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine; public class CommandProcessor { public abstract static class DebuggerInterface { @@ -1132,6 +1177,10 @@ public class CommandProcessor { Klass klass = null; if (t.countTokens() == 1) { klass = SystemDictionaryHelper.findInstanceKlass(t.nextToken()); + if (klass == null) { + out.println("No such type."); + return; + } } while (base != null && base.lessThan(end)) { long step = stride; From 57215b19389fce3d544d9fd0a78eead3f3788a6b Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Tue, 19 Mar 2013 17:51:52 +0400 Subject: [PATCH 049/137] 8009881: TEST_BUG: javax/swing/JTree/8004298/bug8004298.java should be modified Reviewed-by: serb, alexsch --- jdk/test/javax/swing/JTree/8004298/bug8004298.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/jdk/test/javax/swing/JTree/8004298/bug8004298.java b/jdk/test/javax/swing/JTree/8004298/bug8004298.java index 3d0ca5c00bc..bafdee7d3e3 100644 --- a/jdk/test/javax/swing/JTree/8004298/bug8004298.java +++ b/jdk/test/javax/swing/JTree/8004298/bug8004298.java @@ -48,8 +48,13 @@ public class bug8004298 { Robot robot = new Robot(); robot.setAutoDelay(50); SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); - UIManager.setLookAndFeel(new WindowsLookAndFeel()); - + try { + UIManager.setLookAndFeel(new WindowsLookAndFeel()); + } catch (javax.swing.UnsupportedLookAndFeelException ulafe) { + System.out.println(ulafe.getMessage()); + System.out.println("The test is considered PASSED"); + return; + } SwingUtilities.invokeAndWait(new Runnable() { @Override @@ -113,4 +118,4 @@ public class bug8004298 { return super.getPathBounds(tree, path); } } -} \ No newline at end of file +} From e4b8273cc6a18cb960999dce8d1d3e4e91e71da2 Mon Sep 17 00:00:00 2001 From: Pavel Stepanov Date: Tue, 19 Mar 2013 11:03:24 -0300 Subject: [PATCH 050/137] 8009969: CodeCoverage should use template Reviewed-by: jlaskey, sundar --- nashorn/make/build.xml | 2 +- nashorn/make/code_coverage.xml | 60 +++++++++++++++++++++++++++++---- nashorn/make/project.properties | 4 ++- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index e2d8f0ccb31..945ccaa27f1 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -124,7 +124,7 @@ - + diff --git a/nashorn/make/code_coverage.xml b/nashorn/make/code_coverage.xml index 41d85ff3ef1..33980bdfdf6 100644 --- a/nashorn/make/code_coverage.xml +++ b/nashorn/make/code_coverage.xml @@ -36,7 +36,12 @@ + + + + + @@ -51,25 +56,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + - + + + + - + @@ -81,12 +127,12 @@ - + - + diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index c4d0b943cd7..60444de766b 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -235,10 +235,12 @@ jcov=dynamic #naming of CC results #NB directory specified in the cc.dir will be cleaned up!!! cc.dir=${basedir}/../Codecoverage_Nashorn -cc.result.file.name=cc_nashorn.xml +cc.result.file.name=CC_${jcov}_nashorn.xml #dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties jcov2.lib.dir=${basedir}/../jcov2/lib jcov.jar=${jcov2.lib.dir}/jcov.jar cc.include=jdk\.nashorn\.* cc.exclude=jdk\.nashorn\.internal\.scripts\.* +cc.dynamic.genereate.template=true +cc.template=${cc.dir}/CC_template.xml cc.dynamic.args=-javaagent:${jcov.jar}=include=${cc.include},exclude=${cc.exclude},type=all,verbose=0,file=${cc.dir}/${cc.result.file.name} From 887dd2634cdb9cea8f8bc158c75b988f2de9bd55 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Tue, 19 Mar 2013 07:20:15 -0700 Subject: [PATCH 051/137] 8009172: [parfait] Null pointer deference in hotspot/src/share/vm/opto/output.cpp Add guarantee() to DoScheduling() Reviewed-by: twisti, kvn --- hotspot/src/share/vm/opto/output.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index b0d7a9948ea..c77b9f60c5e 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -2518,6 +2518,7 @@ void Scheduling::DoScheduling() { // Schedule the remaining instructions in the block while ( _available.size() > 0 ) { Node *n = ChooseNodeToBundle(); + guarantee(n != NULL, "no nodes available"); AddNodeToBundle(n,bb); } From 7e6a92e08b8c52109154ca371a287720a2dd96c2 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Tue, 19 Mar 2013 07:23:29 -0700 Subject: [PATCH 052/137] 8008663: [parfait] Null pointer deference in hotspot/src/share/vm/compiler/compileBroker.cpp Add NULL checks for compiler name Reviewed-by: twisti, kvn --- .../src/share/vm/compiler/compileBroker.cpp | 77 +++++++++++-------- .../src/share/vm/compiler/compileBroker.hpp | 3 + 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 9214166e905..1b1e2d1cdd5 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -65,9 +65,8 @@ HS_DTRACE_PROBE_DECL8(hotspot, method__compile__begin, HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end, char*, intptr_t, char*, intptr_t, char*, intptr_t, char*, intptr_t, bool); -#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \ +#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name) \ { \ - char* comp_name = (char*)(compiler)->name(); \ Symbol* klass_name = (method)->klass_name(); \ Symbol* name = (method)->name(); \ Symbol* signature = (method)->signature(); \ @@ -78,9 +77,9 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end, signature->bytes(), signature->utf8_length()); \ } -#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \ +#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, \ + comp_name, success) \ { \ - char* comp_name = (char*)(compiler)->name(); \ Symbol* klass_name = (method)->klass_name(); \ Symbol* name = (method)->name(); \ Symbol* signature = (method)->signature(); \ @@ -93,22 +92,21 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end, #else /* USDT2 */ -#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) \ +#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name) \ { \ - char* comp_name = (char*)(compiler)->name(); \ Symbol* klass_name = (method)->klass_name(); \ Symbol* name = (method)->name(); \ Symbol* signature = (method)->signature(); \ - HOTSPOT_METHOD_COMPILE_BEGIN( \ + HOTSPOT_METHOD_COMPILE_BEGIN( \ comp_name, strlen(comp_name), \ - (char *) klass_name->bytes(), klass_name->utf8_length(), \ + (char *) klass_name->bytes(), klass_name->utf8_length(), \ (char *) name->bytes(), name->utf8_length(), \ (char *) signature->bytes(), signature->utf8_length()); \ } -#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) \ +#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, \ + comp_name, success) \ { \ - char* comp_name = (char*)(compiler)->name(); \ Symbol* klass_name = (method)->klass_name(); \ Symbol* name = (method)->name(); \ Symbol* signature = (method)->signature(); \ @@ -122,8 +120,8 @@ HS_DTRACE_PROBE_DECL9(hotspot, method__compile__end, #else // ndef DTRACE_ENABLED -#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method) -#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, success) +#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler, method, comp_name) +#define DTRACE_METHOD_COMPILE_END_PROBE(compiler, method, comp_name, success) #endif // ndef DTRACE_ENABLED @@ -359,7 +357,7 @@ void CompileTask::print() { // void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) { // print compiler name - st->print("%s:", CompileBroker::compiler(comp_level())->name()); + st->print("%s:", CompileBroker::compiler_name(comp_level())); print_compilation(st); } @@ -368,7 +366,7 @@ void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) { void CompileTask::print_line() { ttyLocker ttyl; // keep the following output all in one block // print compiler name if requested - if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler(comp_level())->name()); + if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler_name(comp_level())); print_compilation(); } @@ -1217,8 +1215,9 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci, // lock, make sure that the compilation // isn't prohibited in a straightforward way. - - if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) { + AbstractCompiler *comp = CompileBroker::compiler(comp_level); + if (comp == NULL || !comp->can_compile_method(method) || + compilation_is_prohibited(method, osr_bci, comp_level)) { return NULL; } @@ -1255,7 +1254,7 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci, assert(!HAS_PENDING_EXCEPTION, "No exception should be present"); // some prerequisites that are compiler specific - if (compiler(comp_level)->is_c2() || compiler(comp_level)->is_shark()) { + if (comp->is_c2() || comp->is_shark()) { method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL); // Resolve all classes seen in the signature of the method // we are compiling. @@ -1372,8 +1371,9 @@ bool CompileBroker::compilation_is_in_queue(methodHandle method, bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level) { bool is_native = method->is_native(); // Some compilers may not support the compilation of natives. + AbstractCompiler *comp = compiler(comp_level); if (is_native && - (!CICompileNatives || !compiler(comp_level)->supports_native())) { + (!CICompileNatives || comp == NULL || !comp->supports_native())) { method->set_not_compilable_quietly(comp_level); return true; } @@ -1381,7 +1381,7 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, bool is_osr = (osr_bci != standard_entry_bci); // Some compilers may not support on stack replacement. if (is_osr && - (!CICompileOSR || !compiler(comp_level)->supports_osr())) { + (!CICompileOSR || comp == NULL || !comp->supports_osr())) { method->set_not_osr_compilable(comp_level); return true; } @@ -1753,6 +1753,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { bool is_osr = (osr_bci != standard_entry_bci); bool should_log = (thread->log() != NULL); bool should_break = false; + int task_level = task->comp_level(); { // create the handle inside it's own block so it can't // accidentally be referenced once the thread transitions to @@ -1766,9 +1767,10 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { assert(!method->is_native(), "no longer compile natives"); // Save information about this method in case of failure. - set_last_compile(thread, method, is_osr, task->comp_level()); + set_last_compile(thread, method, is_osr, task_level); - DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler(task->comp_level()), method); + DTRACE_METHOD_COMPILE_BEGIN_PROBE(compiler(task_level), method, + compiler_name(task_level)); } // Allocate a new set of JNI handles. @@ -1805,7 +1807,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { TraceTime t1("compilation", &time); - compiler(task->comp_level())->compile_method(&ci_env, target, osr_bci); + AbstractCompiler *comp = compiler(task_level); + if (comp == NULL) { + ci_env.record_method_not_compilable("no compiler", !TieredCompilation); + } else { + comp->compile_method(&ci_env, target, osr_bci); + } if (!ci_env.failing() && task->code() == NULL) { //assert(false, "compiler should always document failure"); @@ -1843,7 +1850,8 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { methodHandle method(thread, task->method()); - DTRACE_METHOD_COMPILE_END_PROBE(compiler(task->comp_level()), method, task->is_success()); + DTRACE_METHOD_COMPILE_END_PROBE(compiler(task_level), method, + compiler_name(task_level), task->is_success()); collect_statistics(thread, time, task); @@ -1868,9 +1876,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { break; case ciEnv::MethodCompilable_not_at_tier: if (is_osr) - method->set_not_osr_compilable_quietly(task->comp_level()); + method->set_not_osr_compilable_quietly(task_level); else - method->set_not_compilable_quietly(task->comp_level()); + method->set_not_compilable_quietly(task_level); break; } @@ -2128,7 +2136,14 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time if (UsePerfData) counters->set_current_method(""); } - +const char* CompileBroker::compiler_name(int comp_level) { + AbstractCompiler *comp = CompileBroker::compiler(comp_level); + if (comp == NULL) { + return "no compiler"; + } else { + return (comp->name()); + } +} void CompileBroker::print_times() { tty->cr(); @@ -2142,11 +2157,13 @@ void CompileBroker::print_times() { CompileBroker::_t_standard_compilation.seconds() / CompileBroker::_total_standard_compile_count); tty->print_cr(" On stack replacement : %6.3f s, Average : %2.3f", CompileBroker::_t_osr_compilation.seconds(), CompileBroker::_t_osr_compilation.seconds() / CompileBroker::_total_osr_compile_count); - if (compiler(CompLevel_simple) != NULL) { - compiler(CompLevel_simple)->print_timers(); + AbstractCompiler *comp = compiler(CompLevel_simple); + if (comp != NULL) { + comp->print_timers(); } - if (compiler(CompLevel_full_optimization) != NULL) { - compiler(CompLevel_full_optimization)->print_timers(); + comp = compiler(CompLevel_full_optimization); + if (comp != NULL) { + comp->print_timers(); } tty->cr(); int tcb = CompileBroker::_sum_osr_bytes_compiled + CompileBroker::_sum_standard_bytes_compiled; diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp index 7ba448b804a..27fe52851d3 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.hpp +++ b/hotspot/src/share/vm/compiler/compileBroker.hpp @@ -418,6 +418,9 @@ class CompileBroker: AllStatic { static void print_last_compile(); static void print_compiler_threads_on(outputStream* st); + + // compiler name for debugging + static const char* compiler_name(int comp_level); }; #endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP From a8087d1cb647e7d7ff4410e091378de7b7ce76d6 Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Tue, 19 Mar 2013 09:38:37 -0700 Subject: [PATCH 053/137] 8008301: G1: guarantee(satb_mq_set.completed_buffers_num() == 0) failure If the marking stack overflows while the marking tasks are draining the SATB buffers, remark will exit with some SATB buffers left unprocessed. Relax the guarantee to allow for overflow. Reviewed-by: jmasa, brutisso --- .../gc_implementation/g1/concurrentMark.cpp | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index d98b06ac705..d9d70620e47 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -1289,12 +1289,22 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { if (has_overflown()) { // Oops. We overflowed. Restart concurrent marking. _restart_for_overflow = true; - // Clear the marking state because we will be restarting - // marking due to overflowing the global mark stack. - reset_marking_state(); if (G1TraceMarkStackOverflow) { gclog_or_tty->print_cr("\nRemark led to restart for overflow."); } + + // Verify the heap w.r.t. the previous marking bitmap. + if (VerifyDuringGC) { + HandleMark hm; // handle scope + gclog_or_tty->print(" VerifyDuringGC:(overflow)"); + Universe::heap()->prepare_for_verify(); + Universe::verify(/* silent */ false, + /* option */ VerifyOption_G1UsePrevMarking); + } + + // Clear the marking state because we will be restarting + // marking due to overflowing the global mark stack. + reset_marking_state(); } else { // Aggregate the per-task counting data that we have accumulated // while marking. @@ -2593,7 +2603,11 @@ void ConcurrentMark::checkpointRootsFinalWork() { remarkTask.work(0); } SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); - guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant"); + guarantee(has_overflown() || + satb_mq_set.completed_buffers_num() == 0, + err_msg("Invariant: has_overflown = %s, num buffers = %d", + BOOL_TO_STR(has_overflown()), + satb_mq_set.completed_buffers_num())); print_stats(); } From 3679ebdd7d81e1eed90b06421584b842ed8ca2e4 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 19 Mar 2013 10:56:33 -0700 Subject: [PATCH 054/137] 8010222: 8007439 disabled inlining of cold accessor methods Added missing parenthesis Reviewed-by: jrose --- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 155bc47e9cf..6d8f1b3da91 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -157,9 +157,10 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, } else { // Not hot. Check for medium-sized pre-existing nmethod at cold sites. if (callee_method->has_compiled_code() && - callee_method->instructions_size() > inline_small_code_size) + callee_method->instructions_size() > inline_small_code_size) { set_msg("already compiled into a medium method"); return false; + } } if (size > max_inline_size) { if (max_inline_size > default_max_inline_size) { From f4bcfd04cae624d5f47425e4ae47763305ae0bf5 Mon Sep 17 00:00:00 2001 From: Ron Durbin Date: Tue, 19 Mar 2013 11:33:11 -0700 Subject: [PATCH 055/137] 7030610: runtime/6878713/Test6878713.sh fails Error. failed to clean up files after test 7123945: runtime/6878713/Test6878713.sh require about 2G of native memory, swaps and times out Add new diagnostic option -XX:MallocMaxTestWords=NNN and fix Test6878713.sh. Reviewed-by: dcubed, coleenp, dholmes, iklam --- hotspot/src/share/vm/runtime/globals.hpp | 4 + hotspot/src/share/vm/runtime/os.cpp | 39 +++++- hotspot/test/runtime/6878713/Test6878713.sh | 131 +++++++++++++++++--- 3 files changed, 157 insertions(+), 17 deletions(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 9645f625a85..489999f6c4a 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2905,6 +2905,10 @@ class CommandLineFlags { "if non-zero, start verifying C heap after Nth call to " \ "malloc/realloc/free") \ \ + diagnostic(uintx, MallocMaxTestWords, 0, \ + "if non-zero, max # of Words that malloc/realloc can allocate " \ + "(for testing only)") \ + \ product(intx, TypeProfileWidth, 2, \ "number of receiver types to record in call/cast profile") \ \ diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index b4090680395..05fa2d07e73 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -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 @@ -80,6 +80,8 @@ julong os::num_frees = 0; // # of calls to free julong os::free_bytes = 0; // # of bytes freed #endif +static juint cur_malloc_words = 0; // current size for MallocMaxTestWords + void os_init_globals() { // Called from init_globals(). // See Threads::create_vm() in thread.cpp, and init.cpp. @@ -570,6 +572,26 @@ void verify_block(void* memblock) { } #endif +// +// This function supports testing of the malloc out of memory +// condition without really running the system out of memory. +// +static u_char* testMalloc(size_t alloc_size) { + + if (MallocMaxTestWords > 0 && + (cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) { + return NULL; + } + + u_char* ptr = (u_char*)::malloc(alloc_size); + + if (MallocMaxTestWords > 0 && (ptr != NULL)) { + Atomic::add(((jint) (alloc_size / BytesPerWord)), + (volatile jint *) &cur_malloc_words); + } + return ptr; +} + void* os::malloc(size_t size, MEMFLAGS memflags, address caller) { NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1)); NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size)); @@ -579,11 +601,22 @@ void* os::malloc(size_t size, MEMFLAGS memflags, address caller) { // if NULL is returned the calling functions assume out of memory. size = 1; } - if (size > size + space_before + space_after) { // Check for rollover. + + const size_t alloc_size = size + space_before + space_after; + + if (size > alloc_size) { // Check for rollover. return NULL; } + NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap()); - u_char* ptr = (u_char*)::malloc(size + space_before + space_after); + + u_char* ptr; + + if (MallocMaxTestWords > 0) { + ptr = testMalloc(alloc_size); + } else { + ptr = (u_char*)::malloc(alloc_size); + } #ifdef ASSERT if (ptr == NULL) return NULL; diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh index a452ad58fcd..c66c95b0ec8 100644 --- a/hotspot/test/runtime/6878713/Test6878713.sh +++ b/hotspot/test/runtime/6878713/Test6878713.sh @@ -1,10 +1,38 @@ #!/bin/sh +# +# 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. +# +# 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 6878713 +## @bug 7030610 +## @bug 7037122 +## @bug 7123945 ## @summary Verifier heap corruption, relating to backward jsrs -## @run shell/timeout=120 Test6878713.sh +## @run shell Test6878713.sh ## if [ "${TESTSRC}" = "" ] @@ -49,23 +77,98 @@ case "$OS" in ;; esac -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` +CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version -${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar +TARGET_CLASS=OOMCrashClass1960_2 -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass1960_2 > test.out 2>&1 +echo "INFO: extracting the target class." +${TESTJAVA}${FS}bin${FS}jar xvf \ + ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class -if [ -s core -o -s "hs_*.log" ] -then - cat hs*.log - echo "Test Failed" - exit 1 +# remove any hs_err_pid that might exist here +rm -f hs_err_pid*.log + +echo "INFO: checking for 32-bit versus 64-bit VM." +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \ + | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1 +status="$?" +if [ "$status" = 0 ]; then + echo "INFO: testing a 64-bit VM." + is_64_bit=true else - echo "Test Passed" - exit 0 + echo "INFO: testing a 32-bit VM." fi + +if [ "$is_64_bit" = true ]; then + # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296 + MALLOC_MAX=100663296 +else + # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592 + MALLOC_MAX=201326592 +fi +echo "INFO: MALLOC_MAX=$MALLOC_MAX" + +echo "INFO: executing the target class." +# -XX:+PrintCommandLineFlags for debugging purposes +# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without +# the new -XX:MallocMaxTestWords option +# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords +# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX +${TESTJAVA}${FS}bin${FS}java \ + -XX:+PrintCommandLineFlags \ + -XX:+IgnoreUnrecognizedVMOptions \ + -XX:+UnlockDiagnosticVMOptions \ + -XX:MallocMaxTestWords=$MALLOC_MAX \ + ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1 + +echo "INFO: begin contents of test.out:" +cat test.out +echo "INFO: end contents of test.out." + +echo "INFO: checking for memory allocation error message." +# We are looking for this specific memory allocation failure mesg so +# we know we exercised the right allocation path with the test class: +MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes" +grep "$MESG1" test.out +status="$?" +if [ "$status" = 0 ]; then + echo "INFO: found expected memory allocation error message." +else + echo "INFO: did not find expected memory allocation error message." + + # If we didn't find MESG1 above, then there are several scenarios: + # 1) -XX:MallocMaxTestWords is not supported by the current VM and we + # didn't fail TARGET_CLASS's memory allocation attempt; instead + # we failed to find TARGET_CLASS's main() method. The TARGET_CLASS + # is designed to provoke a memory allocation failure during class + # loading; we actually don't care about running the class which is + # why it doesn't have a main() method. + # 2) we failed a memory allocation, but not the one we were looking + # so it might be that TARGET_CLASS no longer tickles the same + # memory allocation code path + # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by + # 6878713 because the test is running on a pre-fix VM. + echo "INFO: checking for no main() method message." + MESG2="Error: Main method not found in class" + grep "$MESG2" test.out + status="$?" + if [ "$status" = 0 ]; then + echo "INFO: found no main() method message." + else + echo "FAIL: did not find no main() method message." + # status is non-zero for exit below + + if [ -s hs_err_pid*.log ]; then + echo "INFO: begin contents of hs_err_pid file:" + cat hs_err_pid*.log + echo "INFO: end contents of hs_err_pid file." + fi + fi +fi + +if [ "$status" = 0 ]; then + echo "PASS: test found one of the expected messages." +fi +exit "$status" From c6d91fa2d9610fd922247d778d3124df2facc360 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Tue, 19 Mar 2013 11:49:36 -0700 Subject: [PATCH 056/137] 8009022: [parfait] Null pointer deference in hotspot/src/share/vm/oops/generateOopMap.cpp Add guarantee() checks to merge_state_into_bb() Reviewed-by: kvn --- hotspot/src/share/vm/oops/generateOopMap.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hotspot/src/share/vm/oops/generateOopMap.cpp b/hotspot/src/share/vm/oops/generateOopMap.cpp index 96572a64e23..8c12b7ac77d 100644 --- a/hotspot/src/share/vm/oops/generateOopMap.cpp +++ b/hotspot/src/share/vm/oops/generateOopMap.cpp @@ -762,6 +762,7 @@ void GenerateOopMap::copy_state(CellTypeState *dst, CellTypeState *src) { // monitor matching is purely informational and doesn't say anything // about the correctness of the code. void GenerateOopMap::merge_state_into_bb(BasicBlock *bb) { + guarantee(bb != NULL, "null basicblock"); assert(bb->is_alive(), "merging state into a dead basicblock"); if (_stack_top == bb->_stack_top) { @@ -1189,6 +1190,7 @@ void GenerateOopMap::do_exception_edge(BytecodeStream* itr) { if (start_pc <= bci && bci < end_pc) { BasicBlock *excBB = get_basic_block_at(handler_pc); + guarantee(excBB != NULL, "no basic block for exception"); CellTypeState *excStk = excBB->stack(); CellTypeState *cOpStck = stack(); CellTypeState cOpStck_0 = cOpStck[0]; @@ -1803,6 +1805,7 @@ void GenerateOopMap::do_monitorexit(int bci) { // possibility that this bytecode will throw an // exception. BasicBlock* bb = get_basic_block_containing(bci); + guarantee(bb != NULL, "no basic block for bci"); bb->set_changed(true); bb->_monitor_top = bad_monitors; @@ -2190,6 +2193,7 @@ void GenerateOopMap::result_for_basicblock(int bci) { // Find basicblock and report results BasicBlock* bb = get_basic_block_containing(bci); + guarantee(bb != NULL, "no basic block for bci"); assert(bb->is_reachable(), "getting result from unreachable basicblock"); bb->set_changed(true); interp_bb(bb); From 25c4a7fccdbdaa9da0a7aa5e04e80966138fe42c Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Tue, 19 Mar 2013 12:15:35 -0700 Subject: [PATCH 057/137] 8008811: [parfait] Null pointer deference in hotspot/src/share/vm/opto/loopopts.cpp Add guarantee() checks Reviewed-by: kvn --- hotspot/src/share/vm/opto/loopnode.hpp | 8 ++++++-- hotspot/src/share/vm/opto/loopopts.cpp | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 104d7b78722..c45ea8421f1 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -603,7 +603,10 @@ class PhaseIdealLoop : public PhaseTransform { } public: - bool has_node( Node* n ) const { return _nodes[n->_idx] != NULL; } + bool has_node( Node* n ) const { + guarantee(n != NULL, "No Node."); + return _nodes[n->_idx] != NULL; + } // check if transform created new nodes that need _ctrl recorded Node *get_late_ctrl( Node *n, Node *early ); Node *get_early_ctrl( Node *n ); @@ -737,7 +740,8 @@ private: return n; } uint dom_depth(Node* d) const { - assert(d->_idx < _idom_size, ""); + guarantee(d != NULL, "Null dominator info."); + guarantee(d->_idx < _idom_size, ""); return _dom_depth[d->_idx]; } void set_idom(Node* d, Node* n, uint dom_depth); diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 31f080dbf7b..1db82d4ceb1 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -232,7 +232,11 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip, bool exc // Loop predicates may have depending checks which should not // be skipped. For example, range check predicate has two checks // for lower and upper bounds. - ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp->as_Proj()->_con)->as_Proj(); + if (dp == NULL) + return; + + ProjNode* dp_proj = dp->as_Proj(); + ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp_proj->_con)->as_Proj(); if (exclude_loop_predicate && is_uncommon_trap_proj(unc_proj, Deoptimization::Reason_predicate)) return; // Let IGVN transformation change control dependence. @@ -866,8 +870,11 @@ void PhaseIdealLoop::split_if_with_blocks_post( Node *n ) { // Now split the bool up thru the phi Node *bolphi = split_thru_phi( bol, n_ctrl, -1 ); + guarantee(bolphi != NULL, "null boolean phi node"); + _igvn.replace_node( bol, bolphi ); assert( iff->in(1) == bolphi, "" ); + if( bolphi->Value(&_igvn)->singleton() ) return; @@ -1628,6 +1635,7 @@ ProjNode* PhaseIdealLoop::proj_clone(ProjNode* p, IfNode* iff) { //------------------------------ short_circuit_if ------------------------------------- // Force the iff control output to be the live_proj Node* PhaseIdealLoop::short_circuit_if(IfNode* iff, ProjNode* live_proj) { + guarantee(live_proj != NULL, "null projection"); int proj_con = live_proj->_con; assert(proj_con == 0 || proj_con == 1, "false or true projection"); Node *con = _igvn.intcon(proj_con); @@ -1686,6 +1694,7 @@ ProjNode* PhaseIdealLoop::insert_if_before_proj(Node* left, bool Signed, BoolTes set_idom(proj, new_if, ddepth); ProjNode* new_exit = proj_clone(other_proj, new_if)->as_Proj(); + guarantee(new_exit != NULL, "null exit node"); register_node(new_exit, get_loop(other_proj), new_if, ddepth); return new_exit; @@ -1793,7 +1802,10 @@ IfNode* PhaseIdealLoop::insert_cmpi_loop_exit(IfNode* if_cmpu, IdealLoopTree *lo int stride = stride_of_possible_iv(if_cmpu); if (stride == 0) return NULL; - ProjNode* lp_continue = stay_in_loop(if_cmpu, loop)->as_Proj(); + Node* lp_proj = stay_in_loop(if_cmpu, loop); + guarantee(lp_proj != NULL, "null loop node"); + + ProjNode* lp_continue = lp_proj->as_Proj(); ProjNode* lp_exit = if_cmpu->proj_out(!lp_continue->is_IfTrue())->as_Proj(); Node* limit = NULL; @@ -1805,6 +1817,7 @@ IfNode* PhaseIdealLoop::insert_cmpi_loop_exit(IfNode* if_cmpu, IdealLoopTree *lo } // Create a new region on the exit path RegionNode* reg = insert_region_before_proj(lp_exit); + guarantee(reg != NULL, "null region node"); // Clone the if-cmpu-true-false using a signed compare BoolTest::mask rel_i = stride > 0 ? bol->_test._test : BoolTest::ge; From 5b1cca1b966e3b57a34d5c5d0ab64e87f75bafbe Mon Sep 17 00:00:00 2001 From: Brian Goetz Date: Tue, 19 Mar 2013 16:05:34 -0700 Subject: [PATCH 058/137] 8001642: Add Optional, OptionalDouble, OptionalInt, OptionalLong Reviewed-by: mduigou, darcy, alanb, jjb --- jdk/src/share/classes/java/util/Optional.java | 243 +++++++++++++++++ .../classes/java/util/OptionalDouble.java | 245 ++++++++++++++++++ .../share/classes/java/util/OptionalInt.java | 245 ++++++++++++++++++ .../share/classes/java/util/OptionalLong.java | 245 ++++++++++++++++++ jdk/test/java/util/Optional/Basic.java | 122 +++++++++ jdk/test/java/util/Optional/BasicDouble.java | 115 ++++++++ jdk/test/java/util/Optional/BasicInt.java | 115 ++++++++ jdk/test/java/util/Optional/BasicLong.java | 115 ++++++++ 8 files changed, 1445 insertions(+) create mode 100644 jdk/src/share/classes/java/util/Optional.java create mode 100644 jdk/src/share/classes/java/util/OptionalDouble.java create mode 100644 jdk/src/share/classes/java/util/OptionalInt.java create mode 100644 jdk/src/share/classes/java/util/OptionalLong.java create mode 100644 jdk/test/java/util/Optional/Basic.java create mode 100644 jdk/test/java/util/Optional/BasicDouble.java create mode 100644 jdk/test/java/util/Optional/BasicInt.java create mode 100644 jdk/test/java/util/Optional/BasicLong.java diff --git a/jdk/src/share/classes/java/util/Optional.java b/jdk/src/share/classes/java/util/Optional.java new file mode 100644 index 00000000000..b51a4d26122 --- /dev/null +++ b/jdk/src/share/classes/java/util/Optional.java @@ -0,0 +1,243 @@ +/* + * 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. 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 java.util; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * A container object which may or may not contain a non-null value. + * If a value is present, {@code isPresent()} will return {@code true} and + * {@code get()} will return the value. + * + *

Additional methods that depend on the presence or absence of a contained + * value are provided, such as {@link #orElse(java.lang.Object) orElse()} + * (return a default value if value not present) and + * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block + * of code if the value is present). + * + * @since 1.8 + */ +public final class Optional { + /** + * Common instance for {@code empty()}. + */ + private static final Optional EMPTY = new Optional<>(); + + /** + * If non-null, the value; if null, indicates no value is present + */ + private final T value; + + /** + * Construct an empty instance. + * + * @implNote Generally only one empty instance, {@link Optional#EMPTY}, + * should exist per VM. + */ + private Optional() { + this.value = null; + } + + /** + * Returns an empty {@code Optional} instance. No value is present for this + * Optional. + * + * @apiNote Though it may be tempting to do so, avoid testing if an object + * is empty by comparing with {@code ==} against instances returned by + * {@code Option.empty()}. There is no guarantee that it is a singleton. + * Instead, use {@link #isPresent()}. + * + * @param Type of the non-existent value + * @return an empty {@code Optional} + */ + public static Optional empty() { + @SuppressWarnings("unchecked") + Optional t = (Optional) EMPTY; + return t; + } + + /** + * Construct an instance with the value present. + * + * @param value the non-null value to be present + */ + private Optional(T value) { + this.value = Objects.requireNonNull(value); + } + + /** + * Return an {@code Optional} with the specified present value. + * + * @param value the value to be present, which must be non-null + * @return an {@code Optional} with the value present + */ + public static Optional of(T value) { + return new Optional<>(value); + } + + /** + * If a value is present in this {@code Optional}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the non-null value held by this {@code Optional} + * @throws NoSuchElementException if there is no value present + * + * @see Optional#isPresent() + */ + public T get() { + if (value == null) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** + * Return {@code true} if there is a value present, otherwise {@code false}. + * + * @return {@code true} if there is a value present, otherwise {@code false} + */ + public boolean isPresent() { + return value != null; + } + + /** + * Have the specified consumer accept the value if a value is present, + * otherwise do nothing. + * + * @param consumer block to be executed if a value is present + * @throws NullPointerException if value is present and {@code consumer} is + * null + */ + public void ifPresent(Consumer consumer) { + if (value != null) + consumer.accept(value); + } + + /** + * Return the value if present, otherwise return {@code other}. + * + * @param other the value to be returned if there is no value present, may + * be null + * @return the value, if present, otherwise {@code other} + */ + public T orElse(T other) { + return value != null ? value : other; + } + + /** + * Return the value if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code Supplier} whose result is returned if no value + * is present + * @return the value if present otherwise the result of {@code other.get()} + * @throws NullPointerException if value is not present and {@code other} is + * null + */ + public T orElseGet(Supplier other) { + return value != null ? value : other.get(); + } + + /** + * Return the contained value, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present value + * @throws X if there is no value present + * @throws NullPointerException if no value is present and + * {@code exceptionSupplier} is null + */ + public T orElseThrow(Supplier exceptionSupplier) throws X { + if (value != null) { + return value; + } else { + throw exceptionSupplier.get(); + } + } + + /** + * Indicates whether some other object is "equal to" this Optional. The + * other object is considered equal if: + *

    + *
  • it is also an {@code Optional} and; + *
  • both instances have no value present or; + *
  • the present values are "equal to" each other via {@code equals()}. + *
+ * + * @param obj an object to be tested for equality + * @return {code true} if the other object is "equal to" this object + * otherwise {@code false} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof Optional)) { + return false; + } + + Optional other = (Optional) obj; + return Objects.equals(value, other.value); + } + + /** + * Returns the hash code value of the present value, if any, or 0 (zero) if + * no value is present. + * + * @return hash code value of the present value or 0 if no value is present + */ + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + /** + * Returns a non-empty string representation of this Optional suitable for + * debugging. The exact presentation format is unspecified and may vary + * between implementations and versions. + * + * @implSpec If a value is present the result must include its string + * representation in the result. Empty and present Optionals must be + * unambiguously differentiable. + * + * @return the string representation of this instance + */ + @Override + public String toString() { + return value != null + ? String.format("Optional[%s]", value) + : "Optional.empty"; + } +} diff --git a/jdk/src/share/classes/java/util/OptionalDouble.java b/jdk/src/share/classes/java/util/OptionalDouble.java new file mode 100644 index 00000000000..118a4b8d017 --- /dev/null +++ b/jdk/src/share/classes/java/util/OptionalDouble.java @@ -0,0 +1,245 @@ +/* + * 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. 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 java.util; + +import java.util.function.DoubleConsumer; +import java.util.function.DoubleSupplier; +import java.util.function.Supplier; + +/** + * A container object which may or may not contain a {@code double} value. + * If a value is present, {@code isPresent()} will return {@code true} and + * {@code get()} will return the value. + * + *

Additional methods that depend on the presence or absence of a contained + * value are provided, such as {@link #orElse(double) orElse()} + * (return a default value if value not present) and + * {@link #ifPresent(java.util.function.DoubleConsumer) ifPresent()} (execute a block + * of code if the value is present). + * + * @since 1.8 + */ +public final class OptionalDouble { + /** + * Common instance for {@code empty()}. + */ + private static final OptionalDouble EMPTY = new OptionalDouble(); + + /** + * If true then the value is present, otherwise indicates no value is present + */ + private final boolean isPresent; + private final double value; + + /** + * Construct an empty instance. + * + * @implNote generally only one empty instance, {@link OptionalDouble#EMPTY}, + * should exist per VM. + */ + private OptionalDouble() { + this.isPresent = false; + this.value = Double.NaN; + } + + /** + * Returns an empty {@code OptionalDouble} instance. No value is present for this + * OptionalDouble. + * + * @apiNote Though it may be tempting to do so, avoid testing if an object + * is empty by comparing with {@code ==} against instances returned by + * {@code Option.empty()}. There is no guarantee that it is a singleton. + * Instead, use {@link #isPresent()}. + * + * @return an empty {@code OptionalDouble}. + */ + public static OptionalDouble empty() { + return EMPTY; + } + + /** + * Construct an instance with the value present. + * + * @param value the double value to be present. + */ + private OptionalDouble(double value) { + this.isPresent = true; + this.value = value; + } + + /** + * Return an {@code OptionalDouble} with the specified value present. + * + * @param value the value to be present + * @return an {@code OptionalDouble} with the value present + */ + public static OptionalDouble of(double value) { + return new OptionalDouble(value); + } + + /** + * If a value is present in this {@code OptionalDouble}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the value held by this {@code OptionalDouble} + * @throws NoSuchElementException if there is no value present + * + * @see OptionalDouble#isPresent() + */ + public double getAsDouble() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** + * Return {@code true} if there is a value present, otherwise {@code false}. + * + * @return {@code true} if there is a value present, otherwise {@code false} + */ + public boolean isPresent() { + return isPresent; + } + + /** + * Have the specified consumer accept the value if a value is present, + * otherwise do nothing. + * + * @param consumer block to be executed if a value is present + * @throws NullPointerException if value is present and {@code consumer} is + * null + */ + public void ifPresent(DoubleConsumer consumer) { + if (isPresent) + consumer.accept(value); + } + + /** + * Return the value if present, otherwise return {@code other}. + * + * @param other the value to be returned if there is no value present + * @return the value, if present, otherwise {@code other} + */ + public double orElse(double other) { + return isPresent ? value : other; + } + + /** + * Return the value if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code DoubleSupplier} whose result is returned if no value + * is present + * @return the value if present otherwise the result of {@code other.getAsDouble()} + * @throws NullPointerException if value is not present and {@code other} is + * null + */ + public double orElseGet(DoubleSupplier other) { + return isPresent ? value : other.getAsDouble(); + } + + /** + * Return the contained value, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present value + * @throws X if there is no value present + * @throws NullPointerException if no value is present and + * {@code exceptionSupplier} is null + */ + public double orElseThrow(Supplier exceptionSupplier) throws X { + if (isPresent) { + return value; + } else { + throw exceptionSupplier.get(); + } + } + + /** + * Indicates whether some other object is "equal to" this Optional. The + * other object is considered equal if: + *

    + *
  • it is also an {@code OptionalInt} and; + *
  • both instances have no value present or; + *
  • the present values are "equal to" each other via {@code Double.compare() == 0}. + *
+ * + * @param obj an object to be tested for equality + * @return {code true} if the other object is "equal to" this object + * otherwise {@code false} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof OptionalDouble)) { + return false; + } + + OptionalDouble other = (OptionalDouble) obj; + return (isPresent && other.isPresent) + ? Double.compare(value, other.value) == 0 + : isPresent == other.isPresent; + } + + /** + * Returns the hash code value of the present value, if any, or 0 (zero) if + * no value is present. + * + * @return hash code value of the present value or 0 if no value is present + */ + @Override + public int hashCode() { + return isPresent ? Double.hashCode(value) : 0; + } + + /** + * Returns a non-empty string representation of this OptionalDouble suitable for + * debugging. The exact presentation format is unspecified and may vary + * between implementations and versions. + * + * @implSpec If a value is present the result must include its string + * representation in the result. Empty and present OptionalDoubless must be + * unambiguously differentiable. + * + * @return the string representation of this instance + */ + @Override + public String toString() { + return isPresent + ? String.format("OptionalDouble[%s]", value) + : "OptionalDouble.empty"; + } +} diff --git a/jdk/src/share/classes/java/util/OptionalInt.java b/jdk/src/share/classes/java/util/OptionalInt.java new file mode 100644 index 00000000000..755c2870b73 --- /dev/null +++ b/jdk/src/share/classes/java/util/OptionalInt.java @@ -0,0 +1,245 @@ +/* + * 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. 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 java.util; + +import java.util.function.IntConsumer; +import java.util.function.IntSupplier; +import java.util.function.Supplier; + +/** + * A container object which may or may not contain a {@code int} value. + * If a value is present, {@code isPresent()} will return {@code true} and + * {@code get()} will return the value. + * + *

Additional methods that depend on the presence or absence of a contained + * value are provided, such as {@link #orElse(int) orElse()} + * (return a default value if value not present) and + * {@link #ifPresent(java.util.function.IntConsumer) ifPresent()} (execute a block + * of code if the value is present). + * + * @since 1.8 + */ +public final class OptionalInt { + /** + * Common instance for {@code empty()}. + */ + private static final OptionalInt EMPTY = new OptionalInt(); + + /** + * If true then the value is present, otherwise indicates no value is present + */ + private final boolean isPresent; + private final int value; + + /** + * Construct an empty instance. + * + * @implNote Generally only one empty instance, {@link OptionalInt#EMPTY}, + * should exist per VM. + */ + private OptionalInt() { + this.isPresent = false; + this.value = 0; + } + + /** + * Returns an empty {@code OptionalInt} instance. No value is present for this + * OptionalInt. + * + * @apiNote Though it may be tempting to do so, avoid testing if an object + * is empty by comparing with {@code ==} against instances returned by + * {@code Option.empty()}. There is no guarantee that it is a singleton. + * Instead, use {@link #isPresent()}. + * + * @return an empty {@code OptionalInt} + */ + public static OptionalInt empty() { + return EMPTY; + } + + /** + * Construct an instance with the value present. + * + * @param value the int value to be present + */ + private OptionalInt(int value) { + this.isPresent = true; + this.value = value; + } + + /** + * Return an {@code OptionalInt} with the specified value present. + * + * @param value the value to be present + * @return an {@code OptionalInt} with the value present + */ + public static OptionalInt of(int value) { + return new OptionalInt(value); + } + + /** + * If a value is present in this {@code OptionalInt}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the value held by this {@code OptionalInt} + * @throws NoSuchElementException if there is no value present + * + * @see OptionalInt#isPresent() + */ + public int getAsInt() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** + * Return {@code true} if there is a value present, otherwise {@code false}. + * + * @return {@code true} if there is a value present, otherwise {@code false} + */ + public boolean isPresent() { + return isPresent; + } + + /** + * Have the specified consumer accept the value if a value is present, + * otherwise do nothing. + * + * @param consumer block to be executed if a value is present + * @throws NullPointerException if value is present and {@code consumer} is + * null + */ + public void ifPresent(IntConsumer consumer) { + if (isPresent) + consumer.accept(value); + } + + /** + * Return the value if present, otherwise return {@code other}. + * + * @param other the value to be returned if there is no value present + * @return the value, if present, otherwise {@code other} + */ + public int orElse(int other) { + return isPresent ? value : other; + } + + /** + * Return the value if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code IntSupplier} whose result is returned if no value + * is present + * @return the value if present otherwise the result of {@code other.getAsInt()} + * @throws NullPointerException if value is not present and {@code other} is + * null + */ + public int orElseGet(IntSupplier other) { + return isPresent ? value : other.getAsInt(); + } + + /** + * Return the contained value, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present value + * @throws X if there is no value present + * @throws NullPointerException if no value is present and + * {@code exceptionSupplier} is null + */ + public int orElseThrow(Supplier exceptionSupplier) throws X { + if (isPresent) { + return value; + } else { + throw exceptionSupplier.get(); + } + } + + /** + * Indicates whether some other object is "equal to" this Optional. The + * other object is considered equal if: + *

    + *
  • it is also an {@code OptionalInt} and; + *
  • both instances have no value present or; + *
  • the present values are "equal to" each other via {@code ==}. + *
+ * + * @param obj an object to be tested for equality + * @return {code true} if the other object is "equal to" this object + * otherwise {@code false} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof OptionalInt)) { + return false; + } + + OptionalInt other = (OptionalInt) obj; + return (isPresent && other.isPresent) + ? value == other.value + : isPresent == other.isPresent; + } + + /** + * Returns the hash code value of the present value, if any, or 0 (zero) if + * no value is present. + * + * @return hash code value of the present value or 0 if no value is present + */ + @Override + public int hashCode() { + return isPresent ? Integer.hashCode(value) : 0; + } + + /** + * Returns a non-empty string representation of this OptionalInt suitable for + * debugging. The exact presentation format is unspecified and may vary + * between implementations and versions. + * + * @implSpec If a value is present the result must include its string + * representation in the result. Empty and present OptionalInts must be + * unambiguously differentiable. + * + * @return the string representation of this instance + */ + @Override + public String toString() { + return isPresent + ? String.format("OptionalInt[%s]", value) + : "OptionalInt.empty"; + } +} diff --git a/jdk/src/share/classes/java/util/OptionalLong.java b/jdk/src/share/classes/java/util/OptionalLong.java new file mode 100644 index 00000000000..fbb1661cc25 --- /dev/null +++ b/jdk/src/share/classes/java/util/OptionalLong.java @@ -0,0 +1,245 @@ +/* + * 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. 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 java.util; + +import java.util.function.LongConsumer; +import java.util.function.LongSupplier; +import java.util.function.Supplier; + +/** + * A container object which may or may not contain a {@code long} value. + * If a value is present, {@code isPresent()} will return {@code true} and + * {@code get()} will return the value. + * + *

Additional methods that depend on the presence or absence of a contained + * value are provided, such as {@link #orElse(long) orElse()} + * (return a default value if value not present) and + * {@link #ifPresent(java.util.function.LongConsumer) ifPresent()} (execute a block + * of code if the value is present). + * + * @since 1.8 + */ +public final class OptionalLong { + /** + * Common instance for {@code empty()}. + */ + private static final OptionalLong EMPTY = new OptionalLong(); + + /** + * If true then the value is present, otherwise indicates no value is present + */ + private final boolean isPresent; + private final long value; + + /** + * Construct an empty instance. + * + * @implNote generally only one empty instance, {@link OptionalLong#EMPTY}, + * should exist per VM. + */ + private OptionalLong() { + this.isPresent = false; + this.value = 0; + } + + /** + * Returns an empty {@code OptionalLong} instance. No value is present for this + * OptionalLong. + * + * @apiNote Though it may be tempting to do so, avoid testing if an object + * is empty by comparing with {@code ==} against instances returned by + * {@code Option.empty()}. There is no guarantee that it is a singleton. + * Instead, use {@link #isPresent()}. + * + * @return an empty {@code OptionalLong}. + */ + public static OptionalLong empty() { + return EMPTY; + } + + /** + * Construct an instance with the value present. + * + * @param value the long value to be present + */ + private OptionalLong(long value) { + this.isPresent = true; + this.value = value; + } + + /** + * Return an {@code OptionalLong} with the specified value present. + * + * @param value the value to be present + * @return an {@code OptionalLong} with the value present + */ + public static OptionalLong of(long value) { + return new OptionalLong(value); + } + + /** + * If a value is present in this {@code OptionalLong}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the value held by this {@code OptionalLong} + * @throws NoSuchElementException if there is no value present + * + * @see OptionalLong#isPresent() + */ + public long getAsLong() { + if (!isPresent) { + throw new NoSuchElementException("No value present"); + } + return value; + } + + /** + * Return {@code true} if there is a value present, otherwise {@code false}. + * + * @return {@code true} if there is a value present, otherwise {@code false} + */ + public boolean isPresent() { + return isPresent; + } + + /** + * Have the specified consumer accept the value if a value is present, + * otherwise do nothing. + * + * @param consumer block to be executed if a value is present + * @throws NullPointerException if value is present and {@code consumer} is + * null + */ + public void ifPresent(LongConsumer consumer) { + if (isPresent) + consumer.accept(value); + } + + /** + * Return the value if present, otherwise return {@code other}. + * + * @param other the value to be returned if there is no value present + * @return the value, if present, otherwise {@code other} + */ + public long orElse(long other) { + return isPresent ? value : other; + } + + /** + * Return the value if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code LongSupplier} whose result is returned if no value + * is present + * @return the value if present otherwise the result of {@code other.getAsLong()} + * @throws NullPointerException if value is not present and {@code other} is + * null + */ + public long orElseGet(LongSupplier other) { + return isPresent ? value : other.getAsLong(); + } + + /** + * Return the contained value, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present value + * @throws X if there is no value present + * @throws NullPointerException if no value is present and + * {@code exceptionSupplier} is null + */ + public long orElseThrow(Supplier exceptionSupplier) throws X { + if (isPresent) { + return value; + } else { + throw exceptionSupplier.get(); + } + } + + /** + * Indicates whether some other object is "equal to" this Optional. The + * other object is considered equal if: + *

    + *
  • it is also an {@code OptionalInt} and; + *
  • both instances have no value present or; + *
  • the present values are "equal to" each other via {@code ==}. + *
+ * + * @param obj an object to be tested for equality + * @return {code true} if the other object is "equal to" this object + * otherwise {@code false} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof OptionalLong)) { + return false; + } + + OptionalLong other = (OptionalLong) obj; + return (isPresent && other.isPresent) + ? value == other.value + : isPresent == other.isPresent; + } + + /** + * Returns the hash code value of the present value, if any, or 0 (zero) if + * no value is present. + * + * @return hash code value of the present value or 0 if no value is present + */ + @Override + public int hashCode() { + return isPresent ? Long.hashCode(value) : 0; + } + + /** + * Returns a non-empty string representation of this OptionalLong suitable for + * debugging. The exact presentation format is unspecified and may vary + * between implementations and versions. + * + * @implSpec If a value is present the result must include its string + * representation in the result. Empty and present OptionalLongs must be + * unambiguously differentiable. + * + * @return the string representation of this instance + */ + @Override + public String toString() { + return isPresent + ? String.format("OptionalLong[%s]", value) + : "OptionalLong.empty"; + } +} diff --git a/jdk/test/java/util/Optional/Basic.java b/jdk/test/java/util/Optional/Basic.java new file mode 100644 index 00000000000..099e0455985 --- /dev/null +++ b/jdk/test/java/util/Optional/Basic.java @@ -0,0 +1,122 @@ +/* + * 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 + * @summary Basic functional test of Optional + * @author Mike Duigou + * @run testng Basic + */ + +import java.util.NoSuchElementException; +import java.util.Optional; + +import static org.testng.Assert.*; +import org.testng.annotations.Test; + + +public class Basic { + + @Test(groups = "unit") + public void testEmpty() { + Optional empty = Optional.empty(); + Optional presentEmptyString = Optional.of(""); + Optional present = Optional.of(Boolean.TRUE); + + // empty + assertTrue(empty.equals(empty)); + assertTrue(empty.equals(Optional.empty())); + assertTrue(!empty.equals(present)); + assertTrue(0 == empty.hashCode()); + assertTrue(!empty.toString().isEmpty()); + assertTrue(!empty.toString().equals(presentEmptyString.toString())); + assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + assertSame(null, empty.orElse(null)); + RuntimeException orElse = new RuntimeException() { }; + assertSame(Boolean.FALSE, empty.orElse(Boolean.FALSE)); + assertSame(null, empty.orElseGet(()-> null)); + assertSame(Boolean.FALSE, empty.orElseGet(()-> Boolean.FALSE)); + } + + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + Optional empty = Optional.empty(); + + Boolean got = empty.get(); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + Optional empty = Optional.empty(); + + Boolean got = empty.orElseGet(null); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + Optional empty = Optional.empty(); + + Boolean got = empty.orElseThrow(null); + } + + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + Optional empty = Optional.empty(); + + Boolean got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { + Optional empty = Optional.empty(); + Optional presentEmptyString = Optional.of(""); + Optional present = Optional.of(Boolean.TRUE); + + // present + assertTrue(present.equals(present)); + assertTrue(present.equals(Optional.of(Boolean.TRUE))); + assertTrue(!present.equals(empty)); + assertTrue(Boolean.TRUE.hashCode() == present.hashCode()); + assertTrue(!present.toString().isEmpty()); + assertTrue(!present.toString().equals(presentEmptyString.toString())); + assertTrue(-1 != present.toString().indexOf(Boolean.TRUE.toString())); + assertSame(Boolean.TRUE, present.get()); + try { + present.ifPresent(v -> { throw new ObscureException(); }); + fail(); + } catch(ObscureException expected) { + + } + assertSame(Boolean.TRUE, present.orElse(null)); + assertSame(Boolean.TRUE, present.orElse(Boolean.FALSE)); + assertSame(Boolean.TRUE, present.orElseGet(null)); + assertSame(Boolean.TRUE, present.orElseGet(()-> null)); + assertSame(Boolean.TRUE, present.orElseGet(()-> Boolean.FALSE)); + assertSame(Boolean.TRUE, present.orElseThrow( null)); + assertSame(Boolean.TRUE, present.orElseThrow(ObscureException::new)); + } + + private static class ObscureException extends RuntimeException { + + } +} diff --git a/jdk/test/java/util/Optional/BasicDouble.java b/jdk/test/java/util/Optional/BasicDouble.java new file mode 100644 index 00000000000..741137c38a8 --- /dev/null +++ b/jdk/test/java/util/Optional/BasicDouble.java @@ -0,0 +1,115 @@ +/* + * 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.0 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.0 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.0 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 + * @summary Basic functional test of OptionalDouble + * @author Mike Duigou + * @run testng BasicDouble + */ + +import java.util.NoSuchElementException; +import java.util.OptionalDouble; + +import static org.testng.Assert.*; +import org.testng.annotations.Test; + + +public class BasicDouble { + + @Test(groups = "unit") + public void testEmpty() { + OptionalDouble empty = OptionalDouble.empty(); + OptionalDouble present = OptionalDouble.of(1.0); + + // empty + assertTrue(empty.equals(empty)); + assertTrue(empty.equals(OptionalDouble.empty())); + assertTrue(!empty.equals(present)); + assertTrue(0 == empty.hashCode()); + assertTrue(!empty.toString().isEmpty()); + assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + assertEquals(2.0, empty.orElse(2.0)); + assertEquals(2.0, empty.orElseGet(()-> 2.0)); + } + + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.getAsDouble(); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.orElseGet(null); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.orElseThrow(null); + } + + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + OptionalDouble empty = OptionalDouble.empty(); + + double got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { + OptionalDouble empty = OptionalDouble.empty(); + OptionalDouble present = OptionalDouble.of(1.0); + + // present + assertTrue(present.equals(present)); + assertFalse(present.equals(OptionalDouble.of(0.0))); + assertTrue(present.equals(OptionalDouble.of(1.0))); + assertTrue(!present.equals(empty)); + assertTrue(Double.hashCode(1.0) == present.hashCode()); + assertFalse(present.toString().isEmpty()); + assertTrue(-1 != present.toString().indexOf(Double.toString(present.getAsDouble()).toString())); + assertEquals(1.0, present.getAsDouble()); + try { + present.ifPresent(v -> { throw new ObscureException(); }); + fail(); + } catch(ObscureException expected) { + + } + assertEquals(1.0, present.orElse(2.0)); + assertEquals(1.0, present.orElseGet(null)); + assertEquals(1.0, present.orElseGet(()-> 2.0)); + assertEquals(1.0, present.orElseGet(()-> 3.0)); + assertEquals(1.0, present.orElseThrow(null)); + assertEquals(1.0, present.orElseThrow(ObscureException::new)); + } + + private static class ObscureException extends RuntimeException { + + } +} diff --git a/jdk/test/java/util/Optional/BasicInt.java b/jdk/test/java/util/Optional/BasicInt.java new file mode 100644 index 00000000000..fa29f95208a --- /dev/null +++ b/jdk/test/java/util/Optional/BasicInt.java @@ -0,0 +1,115 @@ +/* + * 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 + * @summary Basic functional test of OptionalInt + * @author Mike Duigou + * @run testng BasicInt + */ + +import java.util.NoSuchElementException; +import java.util.OptionalInt; + +import static org.testng.Assert.*; +import org.testng.annotations.Test; + + +public class BasicInt { + + @Test(groups = "unit") + public void testEmpty() { + OptionalInt empty = OptionalInt.empty(); + OptionalInt present = OptionalInt.of(1); + + // empty + assertTrue(empty.equals(empty)); + assertTrue(empty.equals(OptionalInt.empty())); + assertTrue(!empty.equals(present)); + assertTrue(0 == empty.hashCode()); + assertTrue(!empty.toString().isEmpty()); + assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + assertEquals(2, empty.orElse(2)); + assertEquals(2, empty.orElseGet(()-> 2)); + } + + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + OptionalInt empty = OptionalInt.empty(); + + int got = empty.getAsInt(); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + OptionalInt empty = OptionalInt.empty(); + + int got = empty.orElseGet(null); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + OptionalInt empty = OptionalInt.empty(); + + int got = empty.orElseThrow(null); + } + + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + OptionalInt empty = OptionalInt.empty(); + + int got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { + OptionalInt empty = OptionalInt.empty(); + OptionalInt present = OptionalInt.of(1); + + // present + assertTrue(present.equals(present)); + assertFalse(present.equals(OptionalInt.of(0))); + assertTrue(present.equals(OptionalInt.of(1))); + assertFalse(present.equals(empty)); + assertTrue(Integer.hashCode(1) == present.hashCode()); + assertFalse(present.toString().isEmpty()); + assertTrue(-1 != present.toString().indexOf(Integer.toString(present.getAsInt()).toString())); + assertEquals(1, present.getAsInt()); + try { + present.ifPresent(v -> { throw new ObscureException(); }); + fail(); + } catch(ObscureException expected) { + + } + assertEquals(1, present.orElse(2)); + assertEquals(1, present.orElseGet(null)); + assertEquals(1, present.orElseGet(()-> 2)); + assertEquals(1, present.orElseGet(()-> 3)); + assertEquals(1, present.orElseThrow(null)); + assertEquals(1, present.orElseThrow(ObscureException::new)); + } + + private static class ObscureException extends RuntimeException { + + } +} diff --git a/jdk/test/java/util/Optional/BasicLong.java b/jdk/test/java/util/Optional/BasicLong.java new file mode 100644 index 00000000000..85bf689ad46 --- /dev/null +++ b/jdk/test/java/util/Optional/BasicLong.java @@ -0,0 +1,115 @@ +/* + * 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 + * @summary Basic functional test of OptionalLong + * @author Mike Duigou + * @run testng BasicLong + */ + +import java.util.NoSuchElementException; +import java.util.OptionalLong; + +import static org.testng.Assert.*; +import org.testng.annotations.Test; + + +public class BasicLong { + + @Test(groups = "unit") + public void testEmpty() { + OptionalLong empty = OptionalLong.empty(); + OptionalLong present = OptionalLong.of(1); + + // empty + assertTrue(empty.equals(empty)); + assertTrue(empty.equals(OptionalLong.empty())); + assertTrue(!empty.equals(present)); + assertTrue(0 == empty.hashCode()); + assertTrue(!empty.toString().isEmpty()); + assertTrue(!empty.isPresent()); + empty.ifPresent(v -> { fail(); }); + assertEquals(2, empty.orElse(2)); + assertEquals(2, empty.orElseGet(()-> 2)); + } + + @Test(expectedExceptions=NoSuchElementException.class) + public void testEmptyGet() { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.getAsLong(); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseGetNull() { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.orElseGet(null); + } + + @Test(expectedExceptions=NullPointerException.class) + public void testEmptyOrElseThrowNull() throws Throwable { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.orElseThrow(null); + } + + @Test(expectedExceptions=ObscureException.class) + public void testEmptyOrElseThrow() throws Exception { + OptionalLong empty = OptionalLong.empty(); + + long got = empty.orElseThrow(ObscureException::new); + } + + @Test(groups = "unit") + public void testPresent() { + OptionalLong empty = OptionalLong.empty(); + OptionalLong present = OptionalLong.of(1L); + + // present + assertTrue(present.equals(present)); + assertFalse(present.equals(OptionalLong.of(0L))); + assertTrue(present.equals(OptionalLong.of(1L))); + assertFalse(present.equals(empty)); + assertTrue(Long.hashCode(1) == present.hashCode()); + assertFalse(present.toString().isEmpty()); + assertTrue(-1 != present.toString().indexOf(Long.toString(present.getAsLong()).toString())); + assertEquals(1L, present.getAsLong()); + try { + present.ifPresent(v -> { throw new ObscureException(); }); + fail(); + } catch(ObscureException expected) { + + } + assertEquals(1, present.orElse(2)); + assertEquals(1, present.orElseGet(null)); + assertEquals(1, present.orElseGet(()-> 2)); + assertEquals(1, present.orElseGet(()-> 3)); + assertEquals(1, present.orElseThrow(null)); + assertEquals(1, present.orElseThrow(ObscureException::new)); + } + + private static class ObscureException extends RuntimeException { + + } +} From 3277de9dad1b2565f3242516552073afec749ee9 Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 20 Mar 2013 08:17:55 +0100 Subject: [PATCH 059/137] 8010084: Race in runtime/NMT/BaselineWithParameter.java Added a waitFor() on the process Reviewed-by: mgerdin, sla, zgu --- hotspot/test/runtime/NMT/BaselineWithParameter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/runtime/NMT/BaselineWithParameter.java b/hotspot/test/runtime/NMT/BaselineWithParameter.java index 594bd7165ed..ff10b28a060 100644 --- a/hotspot/test/runtime/NMT/BaselineWithParameter.java +++ b/hotspot/test/runtime/NMT/BaselineWithParameter.java @@ -43,7 +43,7 @@ public class BaselineWithParameter { // Run 'jcmd VM.native_memory baseline=false' pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=false"}); - pb.start(); + pb.start().waitFor(); // Run 'jcmd VM.native_memory summary=false' pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary=false"}); From 97927be30a39a4bea8465d21351f0f97711fb7b4 Mon Sep 17 00:00:00 2001 From: Alexey Utkin Date: Wed, 20 Mar 2013 13:21:53 +0400 Subject: [PATCH 060/137] 8006193: (process) Clean-up java.lang.ProcessImpl.finalize, does not need to be public Reviewed-by: alanb --- jdk/src/windows/classes/java/lang/ProcessImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java index d4cdc6c7eec..151ab0f9091 100644 --- a/jdk/src/windows/classes/java/lang/ProcessImpl.java +++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java @@ -234,7 +234,7 @@ final class ProcessImpl extends Process { return stderr_stream; } - public void finalize() { + protected void finalize() { closeHandle(handle); } From f61a46ce67f54ab935490e0eef71c53abfb60aaf Mon Sep 17 00:00:00 2001 From: Konstantin Shefov Date: Wed, 20 Mar 2013 14:02:25 +0400 Subject: [PATCH 061/137] 8009880: TEST_BUG: Test java/beans/Introspector/TestTypeResolver.java should be modified again Reviewed-by: malenkov, alexsch --- .../beans/Introspector/TestTypeResolver.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/beans/Introspector/TestTypeResolver.java b/jdk/test/java/beans/Introspector/TestTypeResolver.java index e6915192776..1b4535f506d 100644 --- a/jdk/test/java/beans/Introspector/TestTypeResolver.java +++ b/jdk/test/java/beans/Introspector/TestTypeResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 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 @@ -30,6 +30,7 @@ import com.sun.beans.TypeResolver; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedType; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; @@ -199,6 +200,19 @@ public class TestTypeResolver { public Annotation[] getDeclaredAnnotations() { return null; // not used } + + public AnnotatedType[] getAnnotatedBounds() { + return null; // not used + } + + public T[] getAnnotationsByType(Class annotationClass) { + return null; // not used + } + + public T[] getDeclaredAnnotationsByType(Class annotationClass) { + return null; // not used + } + } private static class ClassTypeVariable extends TypeVariableImpl> { From e21f2d67e197983e6b35652b206dbbd068a26a31 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 20 Mar 2013 08:04:54 -0400 Subject: [PATCH 062/137] 8008217: CDS: Class data sharing limits the malloc heap on Solaris In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address. Reviewed-by: kvn, dcubed, zgu, hseigel --- .../src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp | 2 +- .../os_cpu/bsd_zero/vm/globals_bsd_zero.hpp | 2 +- .../linux_sparc/vm/globals_linux_sparc.hpp | 2 +- .../os_cpu/linux_x86/vm/globals_linux_x86.hpp | 2 +- .../linux_zero/vm/globals_linux_zero.hpp | 2 +- .../vm/globals_solaris_sparc.hpp | 2 +- .../solaris_x86/vm/globals_solaris_x86.hpp | 2 +- .../windows_x86/vm/globals_windows_x86.hpp | 2 +- hotspot/src/share/vm/memory/filemap.cpp | 2 +- hotspot/src/share/vm/memory/metaspace.cpp | 23 +++++-------------- hotspot/src/share/vm/runtime/globals.hpp | 5 ++-- 11 files changed, 18 insertions(+), 28 deletions(-) diff --git a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp index 1144115bc5e..0da430230a8 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp @@ -46,7 +46,7 @@ define_pd_global(uintx, SurvivorRatio, 8); define_pd_global(uintx, JVMInvokeMethodSlack, 8192); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP diff --git a/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp b/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp index 9c988eb743b..44f72df22cf 100644 --- a/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp +++ b/hotspot/src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp @@ -41,7 +41,7 @@ define_pd_global(intx, VMThreadStackSize, 512); define_pd_global(intx, CompilerThreadStackSize, 0); define_pd_global(uintx, JVMInvokeMethodSlack, 8192); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP diff --git a/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp b/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp index 4ac5ead1946..844279e41e0 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp +++ b/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp @@ -33,7 +33,7 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 12288); define_pd_global(intx, CompilerThreadStackSize, 0); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G); #endif // OS_CPU_LINUX_SPARC_VM_GLOBALS_LINUX_SPARC_HPP diff --git a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp index b11a6f3aa27..622928aa17b 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp @@ -44,7 +44,7 @@ define_pd_global(intx, CompilerThreadStackSize, 0); define_pd_global(uintx,JVMInvokeMethodSlack, 8192); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx,HeapBaseMinAddress, 2*G); #endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP diff --git a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp index 56495d176d1..4e0be5c79f3 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp +++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp @@ -41,7 +41,7 @@ define_pd_global(intx, VMThreadStackSize, 512); define_pd_global(intx, CompilerThreadStackSize, 0); define_pd_global(uintx, JVMInvokeMethodSlack, 8192); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif // OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp index e6cb0dddb01..595cd781447 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp @@ -33,7 +33,7 @@ define_pd_global(uintx, JVMInvokeMethodSlack, 12288); define_pd_global(intx, CompilerThreadStackSize, 0); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address #ifdef _LP64 define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G); #else diff --git a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp index 5d99a09c447..91a4336d903 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp @@ -43,7 +43,7 @@ define_pd_global(uintx,JVMInvokeMethodSlack, 10*K); define_pd_global(intx, CompilerThreadStackSize, 0); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx,HeapBaseMinAddress, 256*M); #endif // OS_CPU_SOLARIS_X86_VM_GLOBALS_SOLARIS_X86_HPP diff --git a/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp index f4167f5eb5c..10e0aaff747 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/globals_windows_x86.hpp @@ -45,7 +45,7 @@ define_pd_global(intx, CompilerThreadStackSize, 0); define_pd_global(uintx, JVMInvokeMethodSlack, 8192); -// Used on 64 bit platforms for UseCompressedOops base address or CDS +// Used on 64 bit platforms for UseCompressedOops base address define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif // OS_CPU_WINDOWS_X86_VM_GLOBALS_WINDOWS_X86_HPP diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index fec0957f145..133685932fd 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -372,7 +372,7 @@ ReservedSpace FileMapInfo::reserve_shared_memory() { // other reserved memory (like the code cache). ReservedSpace rs(size, alignment, false, requested_addr); if (!rs.is_reserved()) { - fail_continue(err_msg("Unable to reserved shared space at required address " INTPTR_FORMAT, requested_addr)); + fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr)); return rs; } // the reserved virtual memory is for mapping class data sharing archive diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 6e3145dfac5..47cbeaa19ed 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -337,27 +337,16 @@ VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), // align up to vm allocation granularity byte_size = align_size_up(byte_size, os::vm_allocation_granularity()); - // This allocates memory with mmap. For DumpSharedspaces, allocate the - // space at low memory so that other shared images don't conflict. - // This is the same address as memory needed for UseCompressedOops but - // compressed oops don't work with CDS (offsets in metadata are wrong), so - // borrow the same address. + // This allocates memory with mmap. For DumpSharedspaces, try to reserve + // configurable address, generally at the top of the Java heap so other + // memory addresses don't conflict. if (DumpSharedSpaces) { - char* shared_base = (char*)HeapBaseMinAddress; + char* shared_base = (char*)SharedBaseAddress; _rs = ReservedSpace(byte_size, 0, false, shared_base, 0); if (_rs.is_reserved()) { - assert(_rs.base() == shared_base, "should match"); + assert(shared_base == 0 || _rs.base() == shared_base, "should match"); } else { - // If we are dumping the heap, then allocate a wasted block of address - // space in order to push the heap to a lower address. This extra - // address range allows for other (or larger) libraries to be loaded - // without them occupying the space required for the shared spaces. - uintx reserved = 0; - uintx block_size = 64*1024*1024; - while (reserved < SharedDummyBlockSize) { - char* dummy = os::reserve_memory(block_size); - reserved += block_size; - } + // Get a mmap region anywhere if the SharedBaseAddress fails. _rs = ReservedSpace(byte_size); } MetaspaceShared::set_shared_rs(&_rs); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 489999f6c4a..7a8dd4a436e 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3573,8 +3573,9 @@ class CommandLineFlags { product(uintx, SharedMiscCodeSize, 120*K, \ "Size of the shared miscellaneous code area (in bytes)") \ \ - product(uintx, SharedDummyBlockSize, 0, \ - "Size of dummy block used to shift heap addresses (in bytes)") \ + product(uintx, SharedBaseAddress, LP64_ONLY(32*G) \ + NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \ + "Address to allocate shared memory region for class data") \ \ diagnostic(bool, EnableInvokeDynamic, true, \ "support JSR 292 (method handles, invokedynamic, " \ From eaa8ade37a0826faac1690434df6ff9f34487105 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Wed, 20 Mar 2013 06:32:49 -0700 Subject: [PATCH 063/137] 8009248: [parfait] Null pointer deference in hotspot/src/share/vm/code/compiledIC.cpp Add guarantee() to set_to_interpreted() Reviewed-by: kvn --- hotspot/src/share/vm/code/compiledIC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index 7677dae57c5..85eeda47056 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -552,7 +552,7 @@ bool CompiledStaticCall::is_call_to_interpreted() const { void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) { address stub=find_stub(); - assert(stub!=NULL, "stub not found"); + guarantee(stub != NULL, "stub not found"); if (TraceICs) { ResourceMark rm; From 5082c639fd4c03ffb2951883db6f35e1ad073d12 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Wed, 20 Mar 2013 06:36:04 -0700 Subject: [PATCH 064/137] 8009565: [partfait] Null pointer deference in hotspot/src/share/vm/ci/ciEnv.cpp Add guarantee() to get_instance_klass_for_declared_method_holder() Reviewed-by: kvn --- hotspot/src/share/vm/ci/ciEnv.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index a9a3706df32..6dff1e9396e 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -802,6 +802,7 @@ ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* m // require checks to make sure the expected type was found. Given that this // only occurs for clone() the more extensive fix seems like overkill so // instead we simply smear the array type into Object. + guarantee(method_holder != NULL, "no method holder"); if (method_holder->is_instance_klass()) { return method_holder->as_instance_klass(); } else if (method_holder->is_array_klass()) { From 09098aff2f60f34fdbd70f82a6c2e911286a9dc2 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Wed, 20 Mar 2013 06:38:27 -0700 Subject: [PATCH 065/137] 8009578: [parfait] Null pointer deference in hotspot/src/share/vm/classfile/defaultMethods.cpp Add guarantee() to disqualify_method() Reviewed-by: kvn --- hotspot/src/share/vm/classfile/defaultMethods.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 4e43d7fd323..1977b07ea10 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -348,7 +348,7 @@ class MethodFamily : public ResourceObj { void disqualify_method(Method* method) { int* index = _member_index.get(method); - assert(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); + guarantee(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); _members.at(*index).second = DISQUALIFIED; } From b799726f352399bf9c5d0397f176fe5648f81049 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 20 Mar 2013 09:42:48 -0400 Subject: [PATCH 066/137] 8009298: NMT: Special version of class loading/unloading with runThese stresses out NMT 8009777: NMT: add new NMT dcmd to control auto shutdown option Added diagnostic VM option and DCmd command to allow NMT stay alive under stress situation Reviewed-by: dcubed, coleenp --- hotspot/src/share/vm/runtime/globals.hpp | 5 ++++ hotspot/src/share/vm/services/memTracker.cpp | 15 ++++++++++++ hotspot/src/share/vm/services/memTracker.hpp | 15 ++++++++++++ hotspot/src/share/vm/services/nmtDCmd.cpp | 24 +++++++++++++------- hotspot/src/share/vm/services/nmtDCmd.hpp | 1 + 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 489999f6c4a..8b1db90bdee 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -869,6 +869,11 @@ class CommandLineFlags { diagnostic(bool, PrintNMTStatistics, false, \ "Print native memory tracking summary data if it is on") \ \ + diagnostic(bool, AutoShutdownNMT, true, \ + "Automatically shutdown native memory tracking under stress " \ + "situation. When set to false, native memory tracking tries to " \ + "stay alive at the expense of JVM performance") \ + \ diagnostic(bool, LogCompilation, false, \ "Log compilation activity in detail to hotspot.log or LogFile") \ \ diff --git a/hotspot/src/share/vm/services/memTracker.cpp b/hotspot/src/share/vm/services/memTracker.cpp index 4c110d584ac..8172f67ad4a 100644 --- a/hotspot/src/share/vm/services/memTracker.cpp +++ b/hotspot/src/share/vm/services/memTracker.cpp @@ -68,6 +68,7 @@ int MemTracker::_thread_count = 255; volatile jint MemTracker::_pooled_recorder_count = 0; volatile unsigned long MemTracker::_processing_generation = 0; volatile bool MemTracker::_worker_thread_idle = false; +volatile bool MemTracker::_slowdown_calling_thread = false; debug_only(intx MemTracker::_main_thread_tid = 0;) NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;) @@ -364,6 +365,12 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags, } if (thread != NULL) { + // slow down all calling threads except NMT worker thread, so it + // can catch up. + if (_slowdown_calling_thread && thread != _worker_thread) { + os::yield_all(); + } + if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) { JavaThread* java_thread = (JavaThread*)thread; JavaThreadState state = java_thread->thread_state(); @@ -442,6 +449,7 @@ void MemTracker::enqueue_pending_recorder(MemRecorder* rec) { #define MAX_SAFEPOINTS_TO_SKIP 128 #define SAFE_SEQUENCE_THRESHOLD 30 #define HIGH_GENERATION_THRESHOLD 60 +#define MAX_RECORDER_THREAD_RATIO 30 void MemTracker::sync() { assert(_tracking_level > NMT_off, "NMT is not enabled"); @@ -487,6 +495,13 @@ void MemTracker::sync() { pending_recorders = _global_recorder; _global_recorder = NULL; } + + // see if NMT has too many outstanding recorder instances, it usually + // means that worker thread is lagging behind in processing them. + if (!AutoShutdownNMT) { + _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count); + } + // check _worker_thread with lock to avoid racing condition if (_worker_thread != NULL) { _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes()); diff --git a/hotspot/src/share/vm/services/memTracker.hpp b/hotspot/src/share/vm/services/memTracker.hpp index 764b2950543..934daf06ab9 100644 --- a/hotspot/src/share/vm/services/memTracker.hpp +++ b/hotspot/src/share/vm/services/memTracker.hpp @@ -84,6 +84,7 @@ class MemTracker : AllStatic { static inline bool baseline() { return false; } static inline bool has_baseline() { return false; } + static inline void set_autoShutdown(bool value) { } static void shutdown(ShutdownReason reason) { } static inline bool shutdown_in_progress() { } static bool print_memory_usage(BaselineOutputer& out, size_t unit, @@ -238,6 +239,16 @@ class MemTracker : AllStatic { // if native memory tracking tracks callsite static inline bool track_callsite() { return _tracking_level == NMT_detail; } + // NMT automatically shuts itself down under extreme situation by default. + // When the value is set to false, NMT will try its best to stay alive, + // even it has to slow down VM. + static inline void set_autoShutdown(bool value) { + AutoShutdownNMT = value; + if (AutoShutdownNMT && _slowdown_calling_thread) { + _slowdown_calling_thread = false; + } + } + // shutdown native memory tracking capability. Native memory tracking // can be shutdown by VM when it encounters low memory scenarios. // Memory tracker should gracefully shutdown itself, and preserve the @@ -507,6 +518,10 @@ class MemTracker : AllStatic { // although NMT is still procesing current generation, but // there is not more recorder to process, set idle state static volatile bool _worker_thread_idle; + + // if NMT should slow down calling thread to allow + // worker thread to catch up + static volatile bool _slowdown_calling_thread; }; #endif // !INCLUDE_NMT diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp index 83b7d7e4b8a..62bd72b8158 100644 --- a/hotspot/src/share/vm/services/nmtDCmd.cpp +++ b/hotspot/src/share/vm/services/nmtDCmd.cpp @@ -49,6 +49,9 @@ NMTDCmd::NMTDCmd(outputStream* output, _shutdown("shutdown", "request runtime to shutdown itself and free the " \ "memory used by runtime.", "BOOLEAN", false, "false"), + _auto_shutdown("autoShutdown", "automatically shutdown itself under " \ + "stress situation", + "BOOLEAN", true, "true"), #ifndef PRODUCT _debug("debug", "print tracker statistics. Debug only, not thread safe", \ "BOOLEAN", false, "false"), @@ -61,6 +64,7 @@ NMTDCmd::NMTDCmd(outputStream* output, _dcmdparser.add_dcmd_option(&_summary_diff); _dcmdparser.add_dcmd_option(&_detail_diff); _dcmdparser.add_dcmd_option(&_shutdown); + _dcmdparser.add_dcmd_option(&_auto_shutdown); #ifndef PRODUCT _dcmdparser.add_dcmd_option(&_debug); #endif @@ -84,17 +88,19 @@ void NMTDCmd::execute(TRAPS) { } int nopt = 0; - if(_summary.is_set() && _summary.value()) { ++nopt; } - if(_detail.is_set() && _detail.value()) { ++nopt; } - if(_baseline.is_set() && _baseline.value()) { ++nopt; } - if(_summary_diff.is_set() && _summary_diff.value()) { ++nopt; } - if(_detail_diff.is_set() && _detail_diff.value()) { ++nopt; } - if(_shutdown.is_set() && _shutdown.value()) { ++nopt; } + if (_summary.is_set() && _summary.value()) { ++nopt; } + if (_detail.is_set() && _detail.value()) { ++nopt; } + if (_baseline.is_set() && _baseline.value()) { ++nopt; } + if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; } + if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; } + if (_shutdown.is_set() && _shutdown.value()) { ++nopt; } + if (_auto_shutdown.is_set()) { ++nopt; } + #ifndef PRODUCT - if(_debug.is_set() && _debug.value()) { ++nopt; } + if (_debug.is_set() && _debug.value()) { ++nopt; } #endif - if(nopt > 1) { + if (nopt > 1) { output()->print_cr("At most one of the following option can be specified: " \ "summary, detail, baseline, summary.diff, detail.diff, shutdown" #ifndef PRODUCT @@ -156,6 +162,8 @@ void NMTDCmd::execute(TRAPS) { MemTracker::shutdown(MemTracker::NMT_shutdown_user); output()->print_cr("Shutdown is in progress, it will take a few moments to " \ "completely shutdown"); + } else if (_auto_shutdown.is_set()) { + MemTracker::set_autoShutdown(_auto_shutdown.value()); } else { ShouldNotReachHere(); output()->print_cr("Unknown command"); diff --git a/hotspot/src/share/vm/services/nmtDCmd.hpp b/hotspot/src/share/vm/services/nmtDCmd.hpp index 0c8c8657a72..4f6dd83f03d 100644 --- a/hotspot/src/share/vm/services/nmtDCmd.hpp +++ b/hotspot/src/share/vm/services/nmtDCmd.hpp @@ -39,6 +39,7 @@ class NMTDCmd: public DCmdWithParser { DCmdArgument _summary_diff; DCmdArgument _detail_diff; DCmdArgument _shutdown; + DCmdArgument _auto_shutdown; #ifndef PRODUCT DCmdArgument _debug; #endif From a62f572a50d8df67c95dbb7a7d1c3beacfba3d90 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Wed, 20 Mar 2013 07:05:40 -0700 Subject: [PATCH 067/137] 8009181: [parfait] Null pointer deference in hotspot/src/share/vm/opto/loopTransform.cpp Add guarantee() to insert_pre_post_loops() Reviewed-by: kvn --- hotspot/src/share/vm/opto/loopTransform.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index b405bbcf6ba..c438cf9b880 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -888,6 +888,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_ CountedLoopNode *main_head = loop->_head->as_CountedLoop(); assert( main_head->is_normal_loop(), "" ); CountedLoopEndNode *main_end = main_head->loopexit(); + guarantee(main_end != NULL, "no loop exit node"); assert( main_end->outcnt() == 2, "1 true, 1 false path only" ); uint dd_main_head = dom_depth(main_head); uint max = main_head->outcnt(); @@ -2554,13 +2555,16 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st ok.set(store->_idx); ok.set(store->in(MemNode::Memory)->_idx); + CountedLoopEndNode* loop_exit = head->loopexit(); + guarantee(loop_exit != NULL, "no loop exit node"); + // Loop structure is ok ok.set(head->_idx); - ok.set(head->loopexit()->_idx); + ok.set(loop_exit->_idx); ok.set(head->phi()->_idx); ok.set(head->incr()->_idx); - ok.set(head->loopexit()->cmp_node()->_idx); - ok.set(head->loopexit()->in(1)->_idx); + ok.set(loop_exit->cmp_node()->_idx); + ok.set(loop_exit->in(1)->_idx); // Address elements are ok if (con) ok.set(con->_idx); @@ -2572,7 +2576,7 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st if (n->outcnt() == 0) continue; // Ignore dead if (ok.test(n->_idx)) continue; // Backedge projection is ok - if (n->is_IfTrue() && n->in(0) == head->loopexit()) continue; + if (n->is_IfTrue() && n->in(0) == loop_exit) continue; if (!n->is_AddP()) { msg = "unhandled node"; msg_node = n; @@ -2585,7 +2589,7 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st Node* n = lpt->_body.at(i); // These values can be replaced with other nodes if they are used // outside the loop. - if (n == store || n == head->loopexit() || n == head->incr() || n == store->in(MemNode::Memory)) continue; + if (n == store || n == loop_exit || n == head->incr() || n == store->in(MemNode::Memory)) continue; for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) { Node* use = iter.get(); if (!lpt->_body.contains(use)) { From 9df17fd446c8e9043734f21d2c7ada301a5b3358 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Wed, 20 Mar 2013 14:39:20 +0000 Subject: [PATCH 068/137] 8010282: sun.net.www.protocol.jar.JarFileFactory.close(JarFile) should be thread-safe Reviewed-by: khazra, alanb --- .../www/protocol/jar/JarURLConnection.java | 2 +- .../net/www/protocol/jar/JarFileFactory.java | 32 +++++++++++++------ .../net/www/protocol/jar/JarFileFactory.java | 31 ++++++++++++------ 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 7ea642764b3..4c5dc87bdea 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -51,7 +51,7 @@ public class JarURLConnection extends java.net.JarURLConnection { /* the Jar file factory. It handles both retrieval and caching. */ - private static JarFileFactory factory = new JarFileFactory(); + private static final JarFileFactory factory = JarFileFactory.getInstance(); /* the url for the Jar file */ private URL jarFileURL; diff --git a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java index 2a001a7f381..ae86964155c 100644 --- a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -43,13 +43,24 @@ import sun.net.util.URLUtil; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static final HashMap fileCache = new HashMap<>(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static final HashMap urlCache = new HashMap<>(); + + private static final JarFileFactory instance = new JarFileFactory(); + + private JarFileFactory() { } + + public static JarFileFactory getInstance() { + return instance; + } URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = urlCache.get(jarFile); + URL u; + synchronized (instance) { + u = urlCache.get(jarFile); + } if (u != null) return u.openConnection(); @@ -62,16 +73,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { JarFile get(URL url, boolean useCaches) throws IOException { - JarFile result = null; - JarFile local_result = null; + JarFile result; + JarFile local_result; if (useCaches) { - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); } if (result == null) { local_result = URLJarFile.getJarFile(url, this); - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); if (result == null) { fileCache.put(URLUtil.urlNoFragString(url), local_result); @@ -99,14 +110,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = urlCache.remove(jarFile); - if( urlRemoved != null) { + synchronized (instance) { + URL urlRemoved = urlCache.remove(jarFile); + if (urlRemoved != null) fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } - private JarFile getCachedJarFile(URL url) { + assert Thread.holdsLock(instance); JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ diff --git a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java index 80bd9d1a66a..3bc98eb45af 100644 --- a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -43,13 +43,24 @@ import sun.net.util.URLUtil; class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static final HashMap fileCache = new HashMap<>(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static final HashMap urlCache = new HashMap<>(); + + private static final JarFileFactory instance = new JarFileFactory(); + + private JarFileFactory() { } + + public static JarFileFactory getInstance() { + return instance; + } URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = urlCache.get(jarFile); + URL u; + synchronized (instance) { + u = urlCache.get(jarFile); + } if (u != null) return u.openConnection(); @@ -72,16 +83,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { } } - JarFile result = null; - JarFile local_result = null; + JarFile result; + JarFile local_result; if (useCaches) { - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); } if (result == null) { local_result = URLJarFile.getJarFile(url, this); - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); if (result == null) { fileCache.put(URLUtil.urlNoFragString(url), local_result); @@ -109,13 +120,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = urlCache.remove(jarFile); - if( urlRemoved != null) { + synchronized (instance) { + URL urlRemoved = urlCache.remove(jarFile); + if (urlRemoved != null) fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { + assert Thread.holdsLock(instance); JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ From 198ae0916d182039f965e0a000e0b15468e001f3 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Wed, 20 Mar 2013 10:58:20 -0400 Subject: [PATCH 069/137] 8010112: NullPointerException in sun.security.provider.certpath.CertId() Reviewed-by: vinnie --- .../sun/security/provider/certpath/CertId.java | 17 +++++++++++++---- .../certpath/DistributionPointFetcher.java | 10 ++++------ .../provider/certpath/RevocationChecker.java | 11 +++++++++-- .../classes/sun/security/x509/X509CertImpl.java | 14 +++++++++++++- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java index 731111e14b8..ff7be695d5b 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.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 @@ -29,8 +29,10 @@ import java.io.IOException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.Arrays; +import javax.security.auth.x500.X500Principal; import sun.misc.HexDumpEncoder; import sun.security.x509.*; import sun.security.util.*; @@ -70,6 +72,13 @@ public class CertId { public CertId(X509Certificate issuerCert, SerialNumber serialNumber) throws IOException { + this(issuerCert.getSubjectX500Principal(), + issuerCert.getPublicKey(), serialNumber); + } + + public CertId(X500Principal issuerName, PublicKey issuerKey, + SerialNumber serialNumber) throws IOException { + // compute issuerNameHash MessageDigest md = null; try { @@ -78,11 +87,11 @@ public class CertId { throw new IOException("Unable to create CertId", nsae); } hashAlgId = SHA1_ALGID; - md.update(issuerCert.getSubjectX500Principal().getEncoded()); + md.update(issuerName.getEncoded()); issuerNameHash = md.digest(); // compute issuerKeyHash (remove the tag and length) - byte[] pubKey = issuerCert.getPublicKey().getEncoded(); + byte[] pubKey = issuerKey.getEncoded(); DerValue val = new DerValue(pubKey); DerValue[] seq = new DerValue[2]; seq[0] = val.data.getDerValue(); // AlgorithmID @@ -94,7 +103,7 @@ public class CertId { if (debug) { HexDumpEncoder encoder = new HexDumpEncoder(); - System.out.println("Issuer Certificate is " + issuerCert); + System.out.println("Issuer Name is " + issuerName); System.out.println("issuerNameHash is " + encoder.encodeBuffer(issuerNameHash)); System.out.println("issuerKeyHash is " + diff --git a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java index 136aacdfee2..ab784524546 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -345,10 +345,8 @@ class DistributionPointFetcher { return false; } else { // in case of self-issued indirect CRL issuer. - byte[] certAKID = certImpl.getExtensionValue( - AuthorityKey_Id.toString()); - byte[] crlAKID = crlImpl.getExtensionValue( - AuthorityKey_Id.toString()); + KeyIdentifier certAKID = certImpl.getAuthKeyId(); + KeyIdentifier crlAKID = crlImpl.getAuthKeyId(); if (certAKID == null || crlAKID == null) { // cannot recognize indirect CRL without AKID @@ -359,7 +357,7 @@ class DistributionPointFetcher { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } - } else if (!Arrays.equals(certAKID, crlAKID)) { + } else if (!certAKID.equals(crlAKID)) { // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { diff --git a/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.java index b65b6df1eb4..98d8a9d2272 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/RevocationChecker.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 @@ -643,7 +643,14 @@ class RevocationChecker extends PKIXRevocationChecker { OCSPResponse response = null; CertId certId = null; try { - certId = new CertId(issuerCert, currCert.getSerialNumberObject()); + if (issuerCert != null) { + certId = new CertId(issuerCert, + currCert.getSerialNumberObject()); + } else { + // must be an anchor name and key + certId = new CertId(anchor.getCA(), anchor.getCAPublicKey(), + currCert.getSerialNumberObject()); + } // check if there is a cached OCSP response available byte[] responseBytes = ocspResponses.get(cert); diff --git a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java index 1593e5ed4ab..bd59b62811a 100644 --- a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java +++ b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1095,6 +1095,18 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { } } + public KeyIdentifier getAuthKeyId() { + AuthorityKeyIdentifierExtension aki + = getAuthorityKeyIdentifierExtension(); + if (aki != null) { + try { + return (KeyIdentifier)aki.get( + AuthorityKeyIdentifierExtension.KEY_ID); + } catch (IOException ioe) {} // not possible + } + return null; + } + /** * Get AuthorityKeyIdentifier extension * @return AuthorityKeyIdentifier object or null (if no such object From cfb7431cca4ce9ff8bb679b82b9c84188d574811 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Wed, 20 Mar 2013 11:43:56 -0400 Subject: [PATCH 070/137] 8010017: lambda: reflection get(Declared)Methods support for default methods Don't expose vm generated overpass (bridges to default methods). Reviewed-by: dholmes, fparain --- hotspot/src/share/vm/prims/jvm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 1c277b76ccc..ce66961269f 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1722,7 +1722,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, int i; for (i = 0; i < methods_length; i++) { methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer()) { + if (!method->is_initializer() && !method->is_overpass()) { if (!publicOnly || method->is_public()) { ++num_methods; } @@ -1736,7 +1736,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, int out_idx = 0; for (i = 0; i < methods_length; i++) { methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer()) { + if (!method->is_initializer() && !method->is_overpass()) { if (!publicOnly || method->is_public()) { oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); result->obj_at_put(out_idx, m); From 58a945da1c5cec4978aa5055198f3e542737edaa Mon Sep 17 00:00:00 2001 From: Anton Litvinov Date: Wed, 20 Mar 2013 20:41:03 +0400 Subject: [PATCH 071/137] 6550588: java.awt.Desktop cannot open file with Windows UNC filename Reviewed-by: art, uta --- .../classes/sun/awt/windows/WDesktopPeer.java | 17 +++- .../native/sun/windows/awt_Desktop.cpp | 10 +- .../OpenByUNCPathNameTest.java | 98 +++++++++++++++++++ 3 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java diff --git a/jdk/src/windows/classes/sun/awt/windows/WDesktopPeer.java b/jdk/src/windows/classes/sun/awt/windows/WDesktopPeer.java index a7ddc1425ec..8661f61cc23 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDesktopPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDesktopPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 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 @@ -51,15 +51,15 @@ public class WDesktopPeer implements DesktopPeer { } public void open(File file) throws IOException { - this.ShellExecute(file.toURI(), ACTION_OPEN_VERB); + this.ShellExecute(file, ACTION_OPEN_VERB); } public void edit(File file) throws IOException { - this.ShellExecute(file.toURI(), ACTION_EDIT_VERB); + this.ShellExecute(file, ACTION_EDIT_VERB); } public void print(File file) throws IOException { - this.ShellExecute(file.toURI(), ACTION_PRINT_VERB); + this.ShellExecute(file, ACTION_PRINT_VERB); } public void mail(URI uri) throws IOException { @@ -70,6 +70,13 @@ public class WDesktopPeer implements DesktopPeer { this.ShellExecute(uri, ACTION_OPEN_VERB); } + private void ShellExecute(File file, String verb) throws IOException { + String errMsg = ShellExecute(file.getAbsolutePath(), verb); + if (errMsg != null) { + throw new IOException("Failed to " + verb + " " + file + ". Error message: " + errMsg); + } + } + private void ShellExecute(URI uri, String verb) throws IOException { String errmsg = ShellExecute(uri.toString(), verb); @@ -79,6 +86,6 @@ public class WDesktopPeer implements DesktopPeer { } } - private static native String ShellExecute(String uri, String verb); + private static native String ShellExecute(String fileOrUri, String verb); } diff --git a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp index 5db6c4bbcec..623718e42e1 100644 --- a/jdk/src/windows/native/sun/windows/awt_Desktop.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Desktop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, 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 @@ -38,17 +38,17 @@ extern "C" { * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_windows_WDesktopPeer_ShellExecute - (JNIEnv *env, jclass cls, jstring uri_j, jstring verb_j) + (JNIEnv *env, jclass cls, jstring fileOrUri_j, jstring verb_j) { - LPCWSTR uri_c = JNU_GetStringPlatformChars(env, uri_j, JNI_FALSE); + LPCWSTR fileOrUri_c = JNU_GetStringPlatformChars(env, fileOrUri_j, JNI_FALSE); LPCWSTR verb_c = JNU_GetStringPlatformChars(env, verb_j, JNI_FALSE); // 6457572: ShellExecute possibly changes FPU control word - saving it here unsigned oldcontrol87 = _control87(0, 0); - HINSTANCE retval = ::ShellExecute(NULL, verb_c, uri_c, NULL, NULL, SW_SHOWNORMAL); + HINSTANCE retval = ::ShellExecute(NULL, verb_c, fileOrUri_c, NULL, NULL, SW_SHOWNORMAL); _control87(oldcontrol87, 0xffffffff); - JNU_ReleaseStringPlatformChars(env, uri_j, uri_c); + JNU_ReleaseStringPlatformChars(env, fileOrUri_j, fileOrUri_c); JNU_ReleaseStringPlatformChars(env, verb_j, verb_c); if ((int)retval <= 32) { diff --git a/jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java b/jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java new file mode 100644 index 00000000000..052f36f7453 --- /dev/null +++ b/jdk/test/java/awt/Desktop/OpenByUNCPathNameTest/OpenByUNCPathNameTest.java @@ -0,0 +1,98 @@ +/* + * 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 6550588 + @summary java.awt.Desktop cannot open file with Windows UNC filename + @author Anton Litvinov +*/ + +import java.awt.*; +import java.awt.event.*; +import java.io.*; + +public class OpenByUNCPathNameTest { + private static boolean validatePlatform() { + String osName = System.getProperty("os.name"); + if (osName == null) { + throw new RuntimeException("Name of the current OS could not be retrieved."); + } + return osName.startsWith("Windows"); + } + + private static void openFile() throws IOException { + if (!Desktop.isDesktopSupported()) { + System.out.println("java.awt.Desktop is not supported on this platform."); + } else { + Desktop desktop = Desktop.getDesktop(); + File file = File.createTempFile("Read Me File", ".txt"); + try { + // Test opening of the file with Windows local file path. + desktop.open(file); + Robot robot = null; + try { + Thread.sleep(5000); + robot = new Robot(); + } catch (Exception e) { + e.printStackTrace(); + } + pressAltF4Keys(robot); + + // Test opening of the file with Windows UNC pathname. + String uncFilePath = "\\\\127.0.0.1\\" + file.getAbsolutePath().replace(':', '$'); + File uncFile = new File(uncFilePath); + if (!uncFile.exists()) { + throw new RuntimeException(String.format( + "File with UNC pathname '%s' does not exist.", uncFilePath)); + } + desktop.open(uncFile); + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + pressAltF4Keys(robot); + } finally { + file.delete(); + } + } + } + + private static void pressAltF4Keys(Robot robot) { + if (robot != null) { + robot.keyPress(KeyEvent.VK_ALT); + robot.keyPress(KeyEvent.VK_F4); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_F4); + robot.keyRelease(KeyEvent.VK_ALT); + } + } + + public static void main(String[] args) throws IOException { + if (!validatePlatform()) { + System.out.println("This test is only for MS Windows OS."); + } else { + openFile(); + } + } +} From c9e6a41b99860e7147e1c07d60933fbb7735a5fd Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Wed, 20 Mar 2013 09:50:07 -0700 Subject: [PATCH 072/137] 8006104: Improve tests to test ".useParentHandlers" property set in the logging configuration Reviewed-by: alanb --- .../java/util/logging/CustomLogManager.java | 38 +++++++++++++++++-- .../util/logging/CustomLogManagerTest.java | 2 +- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/jdk/test/java/util/logging/CustomLogManager.java b/jdk/test/java/util/logging/CustomLogManager.java index 9542e54ec02..4598449423d 100644 --- a/jdk/test/java/util/logging/CustomLogManager.java +++ b/jdk/test/java/util/logging/CustomLogManager.java @@ -43,6 +43,20 @@ public class CustomLogManager extends LogManager { INSTANCE = this; } + private boolean useParentHandlers(String loggerName) { + String s = props.getProperty(loggerName + ".useParentHandlers"); + if (s == null) + return true; // default is true + + s = s.toLowerCase(); + if (s.equals("true") || s.equals("1")) { + return true; + } else if (s.equals("false") || s.equals("0")) { + return false; + } + return true; + } + public synchronized boolean addLogger(Logger logger) { String name = logger.getName(); if (namedLoggers.containsKey(name)) { @@ -57,6 +71,9 @@ public class CustomLogManager extends LogManager { if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) { logger.addHandler(new CustomHandler()); } + if (!useParentHandlers(name)) { + logger.setUseParentHandlers(false); + } // add parent loggers int ix = 1; for (;;) { @@ -72,7 +89,10 @@ public class CustomLogManager extends LogManager { // // The test doesn't set the parent for simplicity. if (!namedLoggers.containsKey(pname)) { - Logger.getLogger(pname); + Logger parent = Logger.getLogger(pname); + if (!useParentHandlers(pname)) { + parent.setUseParentHandlers(false); + } } } ix = ix2 + 1; @@ -110,14 +130,16 @@ public class CustomLogManager extends LogManager { props.put("CustomLogManager$CustomHandler.level", "WARNING"); props.put(".handlers", "CustomLogManager$CustomHandler"); props.put("org.foo.bar.level", "SEVERE"); + props.put("org.foo.bar.useParentHandlers", "true"); props.put("org.foo.handlers", "CustomLogManager$CustomHandler"); + props.put("org.foo.useParentHandlers", "false"); props.put("org.openjdk.level", "SEVERE"); props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler"); props.put("org.openjdk.core.level", "INFO"); + props.put("org.openjdk.core.useParentHandlers", "false"); return props; } - public static void checkLogger(String name) { checkLogger(name, null); } @@ -127,10 +149,11 @@ public class CustomLogManager extends LogManager { if (logger == null) { throw new RuntimeException("Logger \"" + name + "\" not exist"); } - System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s%n", + System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s useParentHandlers=%s%n", name, logger.getLevel(), Arrays.toString(logger.getHandlers()), - logger.getResourceBundleName()); + logger.getResourceBundleName(), + logger.getUseParentHandlers()); String rb = logger.getResourceBundleName(); if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) { throw new RuntimeException("Logger \"" + name + @@ -150,6 +173,13 @@ public class CustomLogManager extends LogManager { throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " + Arrays.toString(handlers)); } + + String s = INSTANCE.getProperty(name + ".useParentHandlers"); + boolean uph = (s != null && s.equals("false")) ? false : true; + if (logger.getUseParentHandlers() != uph) { + throw new RuntimeException("Logger \"" + name + "\" unexpected useParentHandlers: " + + logger.getUseParentHandlers()); + } checkParents(name); } diff --git a/jdk/test/java/util/logging/CustomLogManagerTest.java b/jdk/test/java/util/logging/CustomLogManagerTest.java index 2fa89a9a47b..b8f0bfa7f3c 100644 --- a/jdk/test/java/util/logging/CustomLogManagerTest.java +++ b/jdk/test/java/util/logging/CustomLogManagerTest.java @@ -29,7 +29,7 @@ import sun.util.logging.PlatformLogger; /* * @test - * @bug 8005615 + * @bug 8005615 8006104 * @summary Add loggers to custom log manager * * @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java From 0268771fc45a2c9a4ec0d6cc421f3b87421538b2 Mon Sep 17 00:00:00 2001 From: Tao Mao Date: Wed, 20 Mar 2013 12:27:03 -0700 Subject: [PATCH 073/137] 7196080: assert(max_heap >= InitialHeapSize) in arguments.cpp Remove the related assertions becasue they do not hold here. Reviewed-by: jmasa, tschatzl --- hotspot/src/share/vm/runtime/arguments.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index a2bcb956249..7fccf4be754 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1169,7 +1169,6 @@ void Arguments::set_cms_and_parnew_gc_flags() { set_parnew_gc_flags(); } - // MaxHeapSize is aligned down in collectorPolicy size_t max_heap = align_size_down(MaxHeapSize, CardTableRS::ct_max_alignment_constraint()); @@ -1207,10 +1206,6 @@ void Arguments::set_cms_and_parnew_gc_flags() { } // Code along this path potentially sets NewSize and OldSize - - assert(max_heap >= InitialHeapSize, "Error"); - assert(max_heap >= NewSize, "Error"); - if (PrintGCDetails && Verbose) { // Too early to use gclog_or_tty tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT From b7d738913e361409d5d443fa2456aa1ca3a8642f Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 20 Mar 2013 20:40:57 +0100 Subject: [PATCH 074/137] 8007982: some runtime/CommandLine/ tests fail on 32-bit platforms Changed tests to use platform independent flags Reviewed-by: collins, hseigel, zgu --- .../runtime/CommandLine/BooleanFlagWithInvalidValue.java | 8 ++++---- .../test/runtime/CommandLine/FlagWithInvalidValue.java | 4 ++-- .../NonBooleanFlagWithInvalidBooleanPrefix.java | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java index 85f533a88e3..be035e2ca43 100644 --- a/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java +++ b/hotspot/test/runtime/CommandLine/BooleanFlagWithInvalidValue.java @@ -33,17 +33,17 @@ import com.oracle.java.testlibrary.*; public class BooleanFlagWithInvalidValue { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseLargePages=8", "-version"); + "-XX:+PrintWarnings=8", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Improperly specified VM option 'UseLargePages=8'"); + output.shouldContain("Improperly specified VM option 'PrintWarnings=8'"); output.shouldHaveExitValue(1); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseLargePages=8", "-version"); + "-XX:-PrintWarnings=8", "-version"); output = new OutputAnalyzer(pb.start()); - output.shouldContain("Improperly specified VM option 'UseLargePages=8'"); + output.shouldContain("Improperly specified VM option 'PrintWarnings=8'"); output.shouldHaveExitValue(1); } } diff --git a/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java index 9d475c21951..22abc53c50d 100644 --- a/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java +++ b/hotspot/test/runtime/CommandLine/FlagWithInvalidValue.java @@ -33,10 +33,10 @@ import com.oracle.java.testlibrary.*; public class FlagWithInvalidValue { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:ObjectAlignmentInBytes=v", "-version"); + "-XX:MaxRAMFraction=v", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Improperly specified VM option 'ObjectAlignmentInBytes=v'"); + output.shouldContain("Improperly specified VM option 'MaxRAMFraction=v'"); output.shouldHaveExitValue(1); } } diff --git a/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java index d84570eb734..7933aef1a0a 100644 --- a/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java +++ b/hotspot/test/runtime/CommandLine/NonBooleanFlagWithInvalidBooleanPrefix.java @@ -33,17 +33,17 @@ import com.oracle.java.testlibrary.*; public class NonBooleanFlagWithInvalidBooleanPrefix { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:-ObjectAlignmentInBytes=16", "-version"); + "-XX:-MaxRAMFraction=16", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'"); + output.shouldContain("Unexpected +/- setting in VM option 'MaxRAMFraction=16'"); output.shouldHaveExitValue(1); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+ObjectAlignmentInBytes=16", "-version"); + "-XX:+MaxRAMFraction=16", "-version"); output = new OutputAnalyzer(pb.start()); - output.shouldContain("Unexpected +/- setting in VM option 'ObjectAlignmentInBytes=16'"); + output.shouldContain("Unexpected +/- setting in VM option 'MaxRAMFraction=16'"); output.shouldHaveExitValue(1); } From e91d6c8f4daf838fbbf5f3e6c2ca48800082350b Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 20 Mar 2013 15:21:14 -0700 Subject: [PATCH 075/137] 8010427: Refine Method.isDefault implementation Reviewed-by: acorn, dlsmith --- jdk/src/share/classes/java/lang/reflect/Method.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java index 30e764694d0..09438fbebe0 100644 --- a/jdk/src/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/share/classes/java/lang/reflect/Method.java @@ -522,16 +522,19 @@ public final class Method extends Executable { * Returns {@code true} if this method is a default * method; returns {@code false} otherwise. * - * A default method is a non-abstract method, that is, a method - * with a body, declared in an interface type. + * A default method is a public non-abstract instance method, that + * is, a non-static method with a body, declared in an interface + * type. * * @return true if and only if this method is a default * method as defined by the Java Language Specification. * @since 1.8 */ public boolean isDefault() { - return (getModifiers() & Modifier.ABSTRACT) == 0 && - getDeclaringClass().isInterface(); + // Default methods are public non-abstract instance methods + // declared in an interface. + return ((getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) == + Modifier.PUBLIC) && getDeclaringClass().isInterface(); } // NOTE that there is no synchronization used here. It is correct From 2f4ecb86a2957248fd76e0b383cc8c038f32451c Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Wed, 20 Mar 2013 17:04:45 -0700 Subject: [PATCH 076/137] 8006965: remove test_gamma and add dedicated test_* targets instead Reviewed-by: kvn, jcoomes --- hotspot/make/Makefile | 33 +++++ hotspot/make/bsd/Makefile | 21 --- hotspot/make/bsd/makefiles/buildtree.make | 124 +---------------- hotspot/make/defs.make | 5 +- hotspot/make/linux/Makefile | 21 --- hotspot/make/linux/makefiles/buildtree.make | 124 +---------------- hotspot/make/solaris/Makefile | 12 -- hotspot/make/solaris/makefiles/buildtree.make | 131 +----------------- hotspot/make/test/Queens.java | 86 ------------ 9 files changed, 45 insertions(+), 512 deletions(-) delete mode 100644 hotspot/make/test/Queens.java diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile index c55574d8247..8dad67f074e 100644 --- a/hotspot/make/Makefile +++ b/hotspot/make/Makefile @@ -532,6 +532,39 @@ $(JDK_IMAGE_DIR)/jre/lib/rt.jar: $(TAR) -cf - *) | \ ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -) + +# Testing the built JVM +RUN_JVM=JAVA_HOME=$(JDK_IMPORT_PATH) $(JDK_IMPORT_PATH)/bin/java -d$(ARCH_DATA_MODEL) -Dsun.java.launcher=gamma +generic_test: + @$(ECHO) "Running with: $(ALTJVM_DIR)" + @$(RUN_JVM) -XXaltjvm=$(ALTJVM_DIR) -Xinternalversion + @$(RUN_JVM) -XXaltjvm=$(ALTJVM_DIR) -showversion -help + +# C2 test targets +test_product test_optimized test_fastdebug test_jvmg: + @$(MAKE) generic_test ALTJVM_DIR="$(C2_DIR)/$(@:test_%=%)" + +# C1 test targets +test_product1 test_optimized1 test_fastdebug1 test_jvmg1: + ifeq ($(ARCH_DATA_MODEL), 32) + @$(MAKE) generic_test ALTJVM_DIR="$(C1_DIR)/$(@:test_%1=%)" + else + @$(ECHO) "No compiler1 ($(@:test_%=%)) for ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" + endif + +# Zero test targets +test_productzero test_optimizedzero test_fastdebugzero test_jvmgzero: + @$(MAKE) generic_test ALTJVM_DIR="$(ZERO_DIR)/$(@:test_%zero=%)" + +# Shark test targets +test_productshark test_optimizedshark test_fastdebugshark test_jvmgshark: + @$(MAKE) generic_test ALTJVM_DIR="$(SHARK_DIR)/$(@:test_%shark=%)" + +# Minimal1 test targets +test_productminimal1 test_optimizedminimal1 test_fastdebugminimal1 test_jvmgminimal1: + @$(MAKE) generic_test ALTJVM_DIR="$(MINIMAL1_DIR)/$(@:test_%minimal1=%)" + + test_jdk: ifeq ($(JVM_VARIANT_CLIENT), true) $(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -Xinternalversion diff --git a/hotspot/make/bsd/Makefile b/hotspot/make/bsd/Makefile index e95bb05502d..024aef9cba6 100644 --- a/hotspot/make/bsd/Makefile +++ b/hotspot/make/bsd/Makefile @@ -299,63 +299,42 @@ platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in $(TARGETS_C2): $(SUBDIRS_C2) cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install endif $(TARGETS_TIERED): $(SUBDIRS_TIERED) cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_C1): $(SUBDIRS_C1) cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_CORE): $(SUBDIRS_CORE) cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_ZERO): $(SUBDIRS_ZERO) cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_SHARK): $(SUBDIRS_SHARK) cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_MINIMAL1): $(SUBDIRS_MINIMAL1) cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) install endif diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make index b8d92f6a4fc..71bb04b9811 100644 --- a/hotspot/make/bsd/makefiles/buildtree.make +++ b/hotspot/make/bsd/makefiles/buildtree.make @@ -50,7 +50,6 @@ # jvmti.make - generate JVMTI bindings from the spec (JSR-163) # sa.make - generate SA jar file and natives # env.[ck]sh - environment settings -# test_gamma - script to run the Queens program # # The makefiles are split this way so that "make foo" will run faster by not # having to read the dependency files for the vm. @@ -67,9 +66,6 @@ include $(GAMMADIR)/make/altsrc.make # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details. QUIETLY$(MAKE_VERBOSE) = @ -# For now, until the compiler is less wobbly: -TESTFLAGS = -Xbatch -showversion - ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true) PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero else @@ -135,7 +131,7 @@ BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make # dtrace.make is used on BSD versions that implement Dtrace (like MacOS X) BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make \ jvmti.make sa.make dtrace.make \ - env.sh env.csh jdkpath.sh .dbxrc test_gamma + env.sh env.csh jdkpath.sh BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \ SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT) @@ -352,7 +348,7 @@ env.sh: $(BUILDTREE_MAKE) @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \ + { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \ { \ echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \ } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \ @@ -364,8 +360,7 @@ env.csh: env.sh @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && \ - { echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \ + { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \ ) > $@ @@ -376,119 +371,6 @@ jdkpath.sh: $(BUILDTREE_MAKE) echo "JDK=${JAVA_HOME}"; \ ) > $@ -.dbxrc: $(BUILDTREE_MAKE) - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \ - echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \ - echo "then"; \ - echo " source \"\$${HOTSPOT_DBXWARE}\""; \ - echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \ - echo "then"; \ - echo " source \"\$$HOME/.dbxrc\""; \ - echo "fi"; \ - ) > $@ - -# Skip the test for product builds (which only work when installed in a JDK), to -# avoid exiting with an error and causing make to halt. -NO_TEST_MSG = \ - echo "$@: skipping the test--this build must be tested in a JDK." - -NO_JAVA_HOME_MSG = \ - echo "JAVA_HOME must be set to run this test." - -DATA_MODE = $(DATA_MODE/$(BUILDARCH)) -JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE)) - -DATA_MODE/i486 = 32 -DATA_MODE/sparc = 32 -DATA_MODE/sparcv9 = 64 -DATA_MODE/amd64 = 64 -DATA_MODE/ia64 = 64 -DATA_MODE/zero = $(ARCH_DATA_MODEL) - -JAVA_FLAG/32 = -d32 -JAVA_FLAG/64 = -d64 - -WRONG_DATA_MODE_MSG = \ - echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK." - -CROSS_COMPILING_MSG = \ - echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run." - -test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "#!/bin/sh"; \ - echo ""; \ - $(BUILDTREE_COMMENT); \ - echo ""; \ - echo "# Include environment settings for gamma run"; \ - echo ""; \ - echo ". ./env.sh"; \ - echo ""; \ - echo "# Do not run gamma test for cross compiles"; \ - echo ""; \ - echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \ - echo " $(CROSS_COMPILING_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Make sure JAVA_HOME is set as it is required for gamma"; \ - echo ""; \ - echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \ - echo " $(NO_JAVA_HOME_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Check JAVA_HOME version to be used for the test"; \ - echo ""; \ - echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \ - echo "if [ \$$? -ne 0 ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "GAMMA_PROG=gamma"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \ - echo " # NOTE: gamma assumes the OpenJDK directory layout."; \ - echo ""; \ - echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " if [ ! -f \$${JVM_LIB} ]; then"; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " fi"; \ - echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo " fi"; \ - echo "fi"; \ - echo ""; \ - echo "# Compile Queens program for test"; \ - echo ""; \ - echo "rm -f Queens.class"; \ - echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \ - echo ""; \ - echo "# Set library path solely for gamma launcher test run"; \ - echo ""; \ - echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo "export LD_LIBRARY_PATH"; \ - echo "unset LD_LIBRARY_PATH_32"; \ - echo "unset LD_LIBRARY_PATH_64"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo " export DYLD_LIBRARY_PATH"; \ - echo "fi"; \ - echo ""; \ - echo "# Use the gamma launcher and JAVA_HOME to run the test"; \ - echo ""; \ - echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \ - ) > $@ - $(QUIETLY) chmod +x $@ - FORCE: .PHONY: all FORCE diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make index 3d86ed70e6c..4e4c2cb0120 100644 --- a/hotspot/make/defs.make +++ b/hotspot/make/defs.make @@ -302,7 +302,7 @@ ifneq ($(OSNAME),windows) endif # Required make macro settings for all platforms -MAKE_ARGS += JAVA_HOME=$(ABS_BOOTDIR) +MAKE_ARGS += BOOTDIR=$(ABS_BOOTDIR) MAKE_ARGS += OUTPUTDIR=$(ABS_OUTPUTDIR) MAKE_ARGS += GAMMADIR=$(ABS_GAMMADIR) MAKE_ARGS += MAKE_VERBOSE=$(MAKE_VERBOSE) @@ -337,9 +337,6 @@ EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h -# By default, run Queens test after building -TEST_IN_BUILD ?= true - ifndef JAVASE_EMBEDDED EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h endif diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile index e8ef90718a4..04d0b8e5c64 100644 --- a/hotspot/make/linux/Makefile +++ b/hotspot/make/linux/Makefile @@ -300,63 +300,42 @@ platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in $(TARGETS_C2): $(SUBDIRS_C2) cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install endif $(TARGETS_TIERED): $(SUBDIRS_TIERED) cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_C1): $(SUBDIRS_C1) cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_CORE): $(SUBDIRS_CORE) cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_ZERO): $(SUBDIRS_ZERO) cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_SHARK): $(SUBDIRS_SHARK) cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_MINIMAL1): $(SUBDIRS_MINIMAL1) cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_minimal1/$(patsubst %minimal1,%,$@) && $(MAKE) $(MFLAGS) install endif diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make index 960b8f316fb..b75b4d57876 100644 --- a/hotspot/make/linux/makefiles/buildtree.make +++ b/hotspot/make/linux/makefiles/buildtree.make @@ -50,7 +50,6 @@ # jvmti.make - generate JVMTI bindings from the spec (JSR-163) # sa.make - generate SA jar file and natives # env.[ck]sh - environment settings -# test_gamma - script to run the Queens program # # The makefiles are split this way so that "make foo" will run faster by not # having to read the dependency files for the vm. @@ -64,9 +63,6 @@ include $(GAMMADIR)/make/altsrc.make # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details. QUIETLY$(MAKE_VERBOSE) = @ -# For now, until the compiler is less wobbly: -TESTFLAGS = -Xbatch -showversion - ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true) PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero else @@ -128,7 +124,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \ - env.sh env.csh jdkpath.sh .dbxrc test_gamma + env.sh env.csh jdkpath.sh BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \ SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT) @@ -345,7 +341,7 @@ env.sh: $(BUILDTREE_MAKE) @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \ + { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \ { \ echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \ } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \ @@ -357,8 +353,7 @@ env.csh: env.sh @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && \ - { echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \ + { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \ ) > $@ @@ -369,119 +364,6 @@ jdkpath.sh: $(BUILDTREE_MAKE) echo "JDK=${JAVA_HOME}"; \ ) > $@ -.dbxrc: $(BUILDTREE_MAKE) - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \ - echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \ - echo "then"; \ - echo " source \"\$${HOTSPOT_DBXWARE}\""; \ - echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \ - echo "then"; \ - echo " source \"\$$HOME/.dbxrc\""; \ - echo "fi"; \ - ) > $@ - -# Skip the test for product builds (which only work when installed in a JDK), to -# avoid exiting with an error and causing make to halt. -NO_TEST_MSG = \ - echo "$@: skipping the test--this build must be tested in a JDK." - -NO_JAVA_HOME_MSG = \ - echo "JAVA_HOME must be set to run this test." - -DATA_MODE = $(DATA_MODE/$(BUILDARCH)) -JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE)) - -DATA_MODE/i486 = 32 -DATA_MODE/sparc = 32 -DATA_MODE/sparcv9 = 64 -DATA_MODE/amd64 = 64 -DATA_MODE/ia64 = 64 -DATA_MODE/zero = $(ARCH_DATA_MODEL) - -JAVA_FLAG/32 = -d32 -JAVA_FLAG/64 = -d64 - -WRONG_DATA_MODE_MSG = \ - echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK." - -CROSS_COMPILING_MSG = \ - echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run." - -test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "#!/bin/sh"; \ - echo ""; \ - $(BUILDTREE_COMMENT); \ - echo ""; \ - echo "# Include environment settings for gamma run"; \ - echo ""; \ - echo ". ./env.sh"; \ - echo ""; \ - echo "# Do not run gamma test for cross compiles"; \ - echo ""; \ - echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \ - echo " $(CROSS_COMPILING_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Make sure JAVA_HOME is set as it is required for gamma"; \ - echo ""; \ - echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \ - echo " $(NO_JAVA_HOME_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Check JAVA_HOME version to be used for the test"; \ - echo ""; \ - echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \ - echo "if [ \$$? -ne 0 ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "GAMMA_PROG=gamma"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \ - echo " # NOTE: gamma assumes the OpenJDK directory layout."; \ - echo ""; \ - echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " if [ ! -f \$${JVM_LIB} ]; then"; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " fi"; \ - echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo " fi"; \ - echo "fi"; \ - echo ""; \ - echo "# Compile Queens program for test"; \ - echo ""; \ - echo "rm -f Queens.class"; \ - echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \ - echo ""; \ - echo "# Set library path solely for gamma launcher test run"; \ - echo ""; \ - echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo "export LD_LIBRARY_PATH"; \ - echo "unset LD_LIBRARY_PATH_32"; \ - echo "unset LD_LIBRARY_PATH_64"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo " export DYLD_LIBRARY_PATH"; \ - echo "fi"; \ - echo ""; \ - echo "# Use the gamma launcher and JAVA_HOME to run the test"; \ - echo ""; \ - echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \ - ) > $@ - $(QUIETLY) chmod +x $@ - FORCE: .PHONY: all FORCE diff --git a/hotspot/make/solaris/Makefile b/hotspot/make/solaris/Makefile index 83e4df66579..7ae82d856f3 100644 --- a/hotspot/make/solaris/Makefile +++ b/hotspot/make/solaris/Makefile @@ -231,36 +231,24 @@ $(SUBDIRS_CORE): $(BUILDTREE_MAKE) $(TARGETS_C2): $(SUBDIRS_C2) cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler2/$@ && $(MAKE) $(MFLAGS) install endif $(TARGETS_TIERED): $(SUBDIRS_TIERED) cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_tiered/$(patsubst %tiered,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_C1): $(SUBDIRS_C1) cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_compiler1/$(patsubst %1,%,$@) && $(MAKE) $(MFLAGS) install endif $(TARGETS_CORE): $(SUBDIRS_CORE) cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) -ifeq ($(TEST_IN_BUILD),true) - cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && ./test_gamma -endif ifdef INSTALL cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install endif diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make index a9e5a401c00..707d5f36a8d 100644 --- a/hotspot/make/solaris/makefiles/buildtree.make +++ b/hotspot/make/solaris/makefiles/buildtree.make @@ -50,21 +50,19 @@ # jvmti.make - generate JVMTI bindings from the spec (JSR-163) # sa.make - generate SA jar file and natives # env.[ck]sh - environment settings -# test_gamma - script to run the Queens program # # The makefiles are split this way so that "make foo" will run faster by not # having to read the dependency files for the vm. -include $(SPEC) include $(GAMMADIR)/make/scm.make +include $(GAMMADIR)/make/defs.make include $(GAMMADIR)/make/altsrc.make + # 'gmake MAKE_VERBOSE=y' or 'gmake QUIETLY=' gives all the gory details. QUIETLY$(MAKE_VERBOSE) = @ -# For now, until the compiler is less wobbly: -TESTFLAGS = -Xbatch -Xmx32m -showversion - ### maye ARCH_XXX instead? ifdef USE_GCC PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).gcc @@ -119,7 +117,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS)) BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \ - env.sh env.csh jdkpath.sh .dbxrc test_gamma + env.sh env.csh jdkpath.sh BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \ ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT) @@ -334,7 +332,7 @@ env.sh: $(BUILDTREE_MAKE) @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && { echo ": \$${JAVA_HOME:=$${JAVA_HOME}}"; }; \ + { echo "JAVA_HOME=$(JDK_IMPORT_PATH)"; }; \ { \ echo "CLASSPATH=$${CLASSPATH:+$$CLASSPATH:}.:\$${JAVA_HOME}/jre/lib/rt.jar:\$${JAVA_HOME}/jre/lib/i18n.jar"; \ } | sed s:$${JAVA_HOME:--------}:\$${JAVA_HOME}:g; \ @@ -346,8 +344,7 @@ env.csh: env.sh @echo Creating $@ ... $(QUIETLY) ( \ $(BUILDTREE_COMMENT); \ - [ -n "$$JAVA_HOME" ] && \ - { echo "if (! \$$?JAVA_HOME) setenv JAVA_HOME \"$$JAVA_HOME\""; }; \ + { echo "setenv JAVA_HOME \"$(JDK_IMPORT_PATH)\""; }; \ sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \ ) > $@ @@ -358,124 +355,6 @@ jdkpath.sh: $(BUILDTREE_MAKE) echo "JDK=${JAVA_HOME}"; \ ) > $@ -.dbxrc: $(BUILDTREE_MAKE) - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "echo '# Loading $(PLATFORM_DIR)/$(TARGET)/.dbxrc'"; \ - echo "if [ -f \"\$${HOTSPOT_DBXWARE}\" ]"; \ - echo "then"; \ - echo " source \"\$${HOTSPOT_DBXWARE}\""; \ - echo "elif [ -f \"\$$HOME/.dbxrc\" ]"; \ - echo "then"; \ - echo " source \"\$$HOME/.dbxrc\""; \ - echo "fi"; \ - ) > $@ - -# Skip the test for product builds (which only work when installed in a JDK), to -# avoid exiting with an error and causing make to halt. -NO_TEST_MSG = \ - echo "$@: skipping the test--this build must be tested in a JDK." - -NO_JAVA_HOME_MSG = \ - echo "JAVA_HOME must be set to run this test." - -DATA_MODE = $(DATA_MODE/$(BUILDARCH)) -JAVA_FLAG = $(JAVA_FLAG/$(DATA_MODE)) - -DATA_MODE/i486 = 32 -DATA_MODE/sparc = 32 -DATA_MODE/sparcv9 = 64 -DATA_MODE/amd64 = 64 -DATA_MODE/ia64 = 64 - -# This bit is needed to enable local rebuilds. -# Unless the makefile itself sets LP64, any environmental -# setting of LP64 will interfere with the build. -LP64_SETTING/32 = LP64 = \#empty -LP64_SETTING/64 = LP64 = 1 - -JAVA_FLAG/32 = -d32 -JAVA_FLAG/64 = -d64 - -WRONG_DATA_MODE_MSG = \ - echo "JAVA_HOME must point to a $(DATA_MODE)-bit OpenJDK." - -CROSS_COMPILING_MSG = \ - echo "Cross compiling for ARCH $(CROSS_COMPILE_ARCH), skipping gamma run." - -test_gamma: $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java - @echo Creating $@ ... - $(QUIETLY) ( \ - echo "#!/bin/sh"; \ - echo ""; \ - $(BUILDTREE_COMMENT); \ - echo ""; \ - echo "# Include environment settings for gamma run"; \ - echo ""; \ - echo ". ./env.sh"; \ - echo ""; \ - echo "# Do not run gamma test for cross compiles"; \ - echo ""; \ - echo "if [ -n \"$(CROSS_COMPILE_ARCH)\" ]; then "; \ - echo " $(CROSS_COMPILING_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Make sure JAVA_HOME is set as it is required for gamma"; \ - echo ""; \ - echo "if [ -z \"\$${JAVA_HOME}\" ]; then "; \ - echo " $(NO_JAVA_HOME_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "# Check JAVA_HOME version to be used for the test"; \ - echo ""; \ - echo "\$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion > /dev/null 2>&1"; \ - echo "if [ \$$? -ne 0 ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo "fi"; \ - echo ""; \ - echo "GAMMA_PROG=gamma"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " # Ensure architecture for gamma and JAVA_HOME is the same."; \ - echo " # NOTE: gamma assumes the OpenJDK directory layout."; \ - echo ""; \ - echo " GAMMA_ARCH=\"\`file \$${GAMMA_PROG} | awk '{print \$$NF}'\`\""; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " if [ ! -f \$${JVM_LIB} ]; then"; \ - echo " JVM_LIB=\"\$${JAVA_HOME}/jre/lib/$${LIBARCH}/libjava.$(LIBRARY_SUFFIX)\""; \ - echo " fi"; \ - echo " if [ ! -f \$${JVM_LIB} ] || [ -z \"\`file \$${JVM_LIB} | grep \$${GAMMA_ARCH}\`\" ]; then "; \ - echo " $(WRONG_DATA_MODE_MSG)"; \ - echo " exit 0"; \ - echo " fi"; \ - echo "fi"; \ - echo ""; \ - echo "# Compile Queens program for test"; \ - echo ""; \ - echo "rm -f Queens.class"; \ - echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \ - echo ""; \ - echo "# Set library path solely for gamma launcher test run"; \ - echo ""; \ - echo "LD_LIBRARY_PATH=.:$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo "export LD_LIBRARY_PATH"; \ - echo "unset LD_LIBRARY_PATH_32"; \ - echo "unset LD_LIBRARY_PATH_64"; \ - echo ""; \ - echo "if [ \"$(OS_VENDOR)\" = \"Darwin\" ]; then "; \ - echo " DYLD_LIBRARY_PATH=.:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/native_threads:\$${JAVA_HOME}/jre/lib:$${DYLD_LIBRARY_PATH:+$$DYLD_LIBRARY_PATH:}\$${JAVA_HOME}/jre/lib/${LIBARCH}/native_threads:\$${JAVA_HOME}/jre/lib/${LIBARCH}:${GCC_LIB}"; \ - echo " export DYLD_LIBRARY_PATH"; \ - echo "fi"; \ - echo ""; \ - echo "# Use the gamma launcher and JAVA_HOME to run the test"; \ - echo ""; \ - echo "./\$${GAMMA_PROG} $(TESTFLAGS) Queens < /dev/null"; \ - ) > $@ - $(QUIETLY) chmod +x $@ - FORCE: .PHONY: all FORCE diff --git a/hotspot/make/test/Queens.java b/hotspot/make/test/Queens.java deleted file mode 100644 index ab7a9e2c135..00000000000 --- a/hotspot/make/test/Queens.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2006, 2008, 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.util.*; - -// Copyright 1996, Animorphic Systems -// gri 28 Aug 92 / 15 Jan 93 / 8 Dec 95 - -class Queens { - - static void try_i(boolean a[], boolean b[], boolean c[], int x[], int i) { - int adj = 7; - - for (int j = 1; j <= 8; j++) { - if (b[j] && a[i+j] && c[adj+i-j]) { - x[i] = j; - b[j] = false; - a[i+j] = false; - c[adj+i-j] = false; - if (i < 8) try_i(a, b, c, x, i+1); - else print(x); - b[j] = true; - a[i+j] = true; - c[adj+i-j] = true; - } - } - } - - public static void main(String s[]) { - boolean a[] = new boolean[16+1]; - boolean b[] = new boolean[ 8+1]; - boolean c[] = new boolean[14+1]; - int x[] = new int[8+1]; - int adj = 7; - - for (int i = -7; i <= 16; i++) { - if (i >= 1 && i <= 8) b[i] = true; - if (i >= 2) a[i] = true; - if (i <= 7) c[adj+i] = true; - } - - x[0] = 0; // solution counter - - try_i(a, b, c, x, 1); - } - - static void print(int x[]) { - // first correct solution: A1 B5 C8 D6 E3 F7 G2 H4 - - char LF = (char)0xA; - char CR = (char)0xD; - - x[0]++; - if (x[0] < 10) - System.out.print(" "); - System.out.print(x[0] + ". "); - for (int i = 1; i <= 8; i++) { - char p = (char)('A' + i - 1); - System.out.print(p); - System.out.print (x[i] + " "); - } - System.out.println(); - } - -}; From 1f24cdd86cbbd8244c0f6e33cdbf60d02a8ef22a Mon Sep 17 00:00:00 2001 From: Jen Dority Date: Wed, 20 Mar 2013 22:39:51 -0400 Subject: [PATCH 077/137] 8006818: SunEC and SunPKCS11 providers should be in all profiles Reviewed-by: dholmes, alanb, valeriep --- jdk/makefiles/profile-includes.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index 53453e3ded8..b4eb6f83fb3 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -27,6 +27,7 @@ PROFILE_1_JRE_BIN_FILES := \ keytool$(EXE_SUFFIX) PROFILE_1_JRE_LIB_FILES := \ + $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pkcs11$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)java$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jsig.diz \ @@ -34,6 +35,7 @@ PROFILE_1_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)nio$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)npt.diz \ + $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sunec$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)verify.diz \ @@ -61,7 +63,9 @@ PROFILE_1_JRE_LIB_FILES := \ currency.data \ ext/localedata.jar \ ext/meta-index \ + ext/sunec.jar \ ext/sunjce_provider.jar \ + ext/sunpkcs11.jar \ jce.jar \ jsse.jar \ logging.properties \ @@ -88,7 +92,9 @@ PROFILE_1_JRE_OTHER_FILES := \ PROFILE_1_JRE_JAR_FILES := \ ext/localedata.jar \ + ext/sunec.jar \ ext/sunjce_provider.jar \ + ext/sunpkcs11.jar \ jce.jar \ jsse.jar \ resources.jar \ @@ -158,7 +164,6 @@ FULL_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)dt_socket.diz \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)fontmanager$(SHARED_LIBRARY_SUFFIX) \ - $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)j2pkcs11$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jawt$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jdwp$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)jpeg$(SHARED_LIBRARY_SUFFIX) \ @@ -167,7 +172,6 @@ FULL_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)kcms$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)mlib_image$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \ - $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)sunec$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \ alt-rt.jar \ charsets.jar \ @@ -179,8 +183,6 @@ FULL_JRE_LIB_FILES := \ ext/cldrdata.jar \ ext/dnsns.jar \ ext/nashorn.jar \ - ext/sunec.jar \ - ext/sunpkcs11.jar \ ext/zipfs.jar \ flavormap.properties \ fontconfig.RedHat.5.bfc \ @@ -253,8 +255,6 @@ FULL_JRE_JAR_FILES := \ ext/cldrdata.jar \ ext/dnsns.jar \ ext/nashorn.jar \ - ext/sunec.jar \ - ext/sunpkcs11.jar \ ext/zipfs.jar From a003234ac85dcd5a99d7fa17f564c4e864c4f2f2 Mon Sep 17 00:00:00 2001 From: Ron Durbin Date: Wed, 20 Mar 2013 20:44:54 -0700 Subject: [PATCH 078/137] 8010396: checking MallocMaxTestWords in testMalloc() function is redundant Remove redundant checks in testMalloc and add assert. Reviewed-by: dcubed, coleenp, dholmes --- hotspot/src/share/vm/runtime/os.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 05fa2d07e73..aff49e80615 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -577,15 +577,15 @@ void verify_block(void* memblock) { // condition without really running the system out of memory. // static u_char* testMalloc(size_t alloc_size) { + assert(MallocMaxTestWords > 0, "sanity check"); - if (MallocMaxTestWords > 0 && - (cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) { + if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) { return NULL; } u_char* ptr = (u_char*)::malloc(alloc_size); - if (MallocMaxTestWords > 0 && (ptr != NULL)) { + if (ptr != NULL) { Atomic::add(((jint) (alloc_size / BytesPerWord)), (volatile jint *) &cur_malloc_words); } From 6bec5bf02c19c41794a739e399d21b76dd67613f Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Thu, 21 Mar 2013 09:07:43 +0100 Subject: [PATCH 079/137] 8004241: NPG: Metaspace occupies more memory than specified by -XX:MaxMetaspaceSize option Enforce MaxMetaspaceSize for both metaspace parts, check MaxMetaspaceSize against "reserved", not "capacity" Reviewed-by: jmasa, johnc --- hotspot/src/share/vm/memory/metaspace.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index f7861121383..fc4ed3d376e 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1100,25 +1100,24 @@ size_t MetaspaceGC::delta_capacity_until_GC(size_t word_size) { } bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { + // If the user wants a limit, impose one. + if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) && + MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) { + return false; + } // Class virtual space should always be expanded. Call GC for the other // metadata virtual space. if (vsl == Metaspace::class_space_list()) return true; - // If the user wants a limit, impose one. - size_t max_metaspace_size_words = MaxMetaspaceSize / BytesPerWord; - size_t metaspace_size_words = MetaspaceSize / BytesPerWord; - if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) && - vsl->capacity_words_sum() >= max_metaspace_size_words) { - return false; - } - // If this is part of an allocation after a GC, expand // unconditionally. if(MetaspaceGC::expand_after_GC()) { return true; } + size_t metaspace_size_words = MetaspaceSize / BytesPerWord; + // If the capacity is below the minimum capacity, allow the // expansion. Also set the high-water-mark (capacity_until_GC) // to that minimum capacity so that a GC will not be induced From d08900246077315c9b8146628112384712277043 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Thu, 21 Mar 2013 16:50:35 +0400 Subject: [PATCH 080/137] 8007146: [macosx] Setting a display mode crashes JDK under VNC Reviewed-by: serb --- .../macosx/native/sun/awt/CGraphicsDevice.m | 55 +++++++++++++--- .../awt/GraphicsDevice/CheckDisplayModes.java | 64 +++++++++++++++++++ 2 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java diff --git a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m index 1e2df28dd56..230569dbafd 100644 --- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m +++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m @@ -49,6 +49,42 @@ static int getBPPFromModeString(CFStringRef mode) return 0; } +static BOOL isValidDisplayMode(CGDisplayModeRef mode){ + return (1 < CGDisplayModeGetWidth(mode) && 1 < CGDisplayModeGetHeight(mode)); +} + +static CFMutableArrayRef getAllValidDisplayModes(jint displayID){ + CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL); + + CFIndex numModes = CFArrayGetCount(allModes); + CFMutableArrayRef validModes = CFArrayCreateMutable(kCFAllocatorDefault, numModes + 1, NULL); + + CFIndex n; + for (n=0; n < numModes; n++) { + CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n); + if (cRef != NULL && isValidDisplayMode(cRef)) { + CFArrayAppendValue(validModes, cRef); + } + } + + CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID); + + BOOL containsCurrentMode = NO; + numModes = CFArrayGetCount(validModes); + for (n=0; n < numModes; n++) { + if(CFArrayGetValueAtIndex(validModes, n) == currentMode){ + containsCurrentMode = YES; + break; + } + } + + if (!containsCurrentMode) { + CFArrayAppendValue(validModes, currentMode); + } + + return validModes; +} + /* * Find the best possible match in the list of display modes that we can switch to based on * the provided parameters. @@ -198,28 +234,30 @@ Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode (JNIEnv *env, jclass class, jint displayID, jint w, jint h, jint bpp, jint refrate) { JNF_COCOA_ENTER(env); - CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL); + CFArrayRef allModes = getAllValidDisplayModes(displayID); + CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate); + __block CGError retCode = kCGErrorSuccess; if (closestMatch != NULL) { [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ CGDisplayConfigRef config; - CGError retCode = CGBeginDisplayConfiguration(&config); + retCode = CGBeginDisplayConfiguration(&config); if (retCode == kCGErrorSuccess) { CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL); - CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly); - if (config != NULL) { - CFRelease(config); - } + retCode = CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly); } }]; } else { [JNFException raise:env as:kIllegalArgumentException reason:"Invalid display mode"]; } + if (retCode != kCGErrorSuccess){ + [JNFException raise:env as:kIllegalArgumentException reason:"Unable to set display mode!"]; + } + CFRelease(allModes); JNF_COCOA_EXIT(env); } - /* * Class: sun_awt_CGraphicsDevice * Method: nativeGetDisplayMode @@ -247,7 +285,8 @@ Java_sun_awt_CGraphicsDevice_nativeGetDisplayModes { jobjectArray jreturnArray = NULL; JNF_COCOA_ENTER(env); - CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL); + CFArrayRef allModes = getAllValidDisplayModes(displayID); + CFIndex numModes = CFArrayGetCount(allModes); static JNF_CLASS_CACHE(jc_DisplayMode, "java/awt/DisplayMode"); diff --git a/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java new file mode 100644 index 00000000000..bc8d8a50be6 --- /dev/null +++ b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java @@ -0,0 +1,64 @@ +/* + * 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 8007146 + * @summary [macosx] Setting a display mode crashes JDK under VNC + * @author Alexander Scherbatiy + * @run main CheckDisplayModes + */ +import java.awt.DisplayMode; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +public class CheckDisplayModes { + + public static void main(String[] args) { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice graphicDevice = ge.getDefaultScreenDevice(); + DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode(); + checkDisplayMode(defaultDisplayMode); + graphicDevice.setDisplayMode(defaultDisplayMode); + + DisplayMode[] displayModes = graphicDevice.getDisplayModes(); + boolean isDefaultDisplayModeIncluded = false; + for (DisplayMode displayMode : displayModes) { + checkDisplayMode(displayMode); + graphicDevice.setDisplayMode(displayMode); + if (defaultDisplayMode.equals(displayMode)) { + isDefaultDisplayModeIncluded = true; + } + } + + if (!isDefaultDisplayModeIncluded) { + throw new RuntimeException("Default display mode is not included"); + } + } + + static void checkDisplayMode(DisplayMode displayMode) { + if (displayMode == null || displayMode.getWidth() <= 1 || displayMode.getHeight() <= 1) { + throw new RuntimeException("invalid display mode"); + } + } +} From 0f8bf3e7c388cc5f27445dee1e08d99e2ede6ad9 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 21 Mar 2013 19:19:08 +0530 Subject: [PATCH 081/137] 8009869: Need to modify java.security property package.access to include nashorn packages Reviewed-by: ahgross, jlaskey, lagergren --- jdk/src/share/lib/security/java.security-linux | 8 ++++++-- jdk/src/share/lib/security/java.security-macosx | 4 ++++ jdk/src/share/lib/security/java.security-solaris | 8 ++++++-- jdk/src/share/lib/security/java.security-windows | 8 ++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/lib/security/java.security-linux b/jdk/src/share/lib/security/java.security-linux index 8fc53d73677..1abac9d2aa8 100644 --- a/jdk/src/share/lib/security/java.security-linux +++ b/jdk/src/share/lib/security/java.security-linux @@ -157,7 +157,9 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools. # # List of comma-separated packages that start with or equal this string @@ -181,7 +183,9 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools # # Determines whether this properties file can be appended to diff --git a/jdk/src/share/lib/security/java.security-macosx b/jdk/src/share/lib/security/java.security-macosx index 5a319fa5445..f3d10a4b682 100644 --- a/jdk/src/share/lib/security/java.security-macosx +++ b/jdk/src/share/lib/security/java.security-macosx @@ -159,6 +159,8 @@ package.access=sun.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools.,\ apple. # @@ -184,6 +186,8 @@ package.definition=sun.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools.,\ apple. # diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index 2a781cff75d..a24634e61b9 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -159,7 +159,9 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools. # # List of comma-separated packages that start with or equal this string @@ -183,7 +185,9 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools # # Determines whether this properties file can be appended to diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index a00f4628dd6..a7d74c90554 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -158,7 +158,9 @@ package.access=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools. # # List of comma-separated packages that start with or equal this string @@ -182,7 +184,9 @@ package.definition=sun.,\ com.sun.org.apache.xalan.internal.utils.,\ com.sun.org.glassfish.external.,\ com.sun.org.glassfish.gmbal.,\ - jdk.internal. + jdk.internal.,\ + jdk.nashorn.internal.,\ + jdk.nashorn.tools. # # Determines whether this properties file can be appended to From 9bf86a475ef72b783cfdcd26aafe8e7c48484ff6 Mon Sep 17 00:00:00 2001 From: Joseph Provino Date: Thu, 21 Mar 2013 10:18:05 -0400 Subject: [PATCH 082/137] 8009904: jvmtiClassFileReconstituter.cpp needs to be excluded from the minimal jvm JvmtiClassFileReconstituter.cpp needs to be added to the list of files to exclude when JVMTI is excluded from the jvm Reviewed-by: dholmes, sspitsyn --- hotspot/make/excludeSrc.make | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index 1f044812352..5ec9566caea 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -28,7 +28,8 @@ ifeq ($(INCLUDE_JVMTI), false) Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \ jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \ jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \ - jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp + jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \ + jvmtiClassFileReconstituter.cpp endif ifeq ($(INCLUDE_FPROF), false) From 85aa7836deb59b638c345e36417b2f80ec3ff7f0 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Thu, 21 Mar 2013 10:11:24 -0700 Subject: [PATCH 083/137] 8009584: [parfait] Null pointer deference in hotspot/src/cpu/x86/vm/relocInfo_x86.cpp Added guarantee() to pd_address_in_code() Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/relocInfo_x86.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp index d4a929613ab..e16c6653960 100644 --- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp +++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp @@ -145,12 +145,9 @@ address* Relocation::pd_address_in_code() { assert(which == Assembler::disp32_operand || which == Assembler::call32_operand || which == Assembler::imm_operand, "format unpacks ok"); - if (which != Assembler::imm_operand) { - // The "address" in the code is a displacement can't return it as - // and address* since it is really a jint* - ShouldNotReachHere(); - return NULL; - } + // The "address" in the code is a displacement can't return it as + // and address* since it is really a jint* + guarantee(which == Assembler::imm_operand, "must be immediate operand"); #else assert(which == Assembler::disp32_operand || which == Assembler::imm_operand, "format unpacks ok"); #endif // AMD64 From 6c55facb77e015c948dc27eb090aa87c4cfe8d35 Mon Sep 17 00:00:00 2001 From: Morris Meyer Date: Thu, 21 Mar 2013 10:13:56 -0700 Subject: [PATCH 084/137] 8009593: [parfait] Null pointer deference in hotspot/src/share/vm/oops/constantPool.cpp Added guarantee() to print_entry_on() Reviewed-by: kvn --- hotspot/src/share/vm/oops/constantPool.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index c025730bbb4..ba7ec439e4f 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -1852,6 +1852,7 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) { switch (tag_at(index).value()) { case JVM_CONSTANT_Class : { Klass* k = klass_at(index, CATCH); + guarantee(k != NULL, "need klass"); k->print_value_on(st); st->print(" {0x%lx}", (address)k); } From 8eecfc752261c7a99c9f369f079dc93c85003846 Mon Sep 17 00:00:00 2001 From: Rob McKenna Date: Thu, 21 Mar 2013 17:33:15 +0000 Subject: [PATCH 085/137] 8009251: Add proxy handling and keep-alive fixes to jsse Reviewed-by: chegar --- .../classes/sun/net/www/http/HttpClient.java | 2 +- .../AbstractDelegateHttpsURLConnection.java | 9 ++- .../net/www/protocol/https/HttpsClient.java | 81 +++++++++++++++---- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java index aeb74fa6938..9f6b80afe9b 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java @@ -46,7 +46,7 @@ public class HttpClient extends NetworkClient { // whether this httpclient comes from the cache protected boolean cachedHttpClient = false; - private boolean inCache; + protected boolean inCache; // Http requests we send MessageHeader requests; diff --git a/jdk/src/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java index 88c62594008..ada2ee9800a 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java @@ -96,7 +96,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends http = HttpsClient.New (getSSLSocketFactory(), url, getHostnameVerifier(), - useCache); + useCache, this); ((HttpsClient)http).afterConnect(); } @@ -149,7 +149,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends http = HttpsClient.New (getSSLSocketFactory(), url, getHostnameVerifier(), - proxyHost, proxyPort, useCache); + proxyHost, proxyPort, useCache, this); connected = true; } @@ -189,7 +189,8 @@ public abstract class AbstractDelegateHttpsURLConnection extends protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout) throws IOException { return HttpsClient.New(getSSLSocketFactory(), url, - getHostnameVerifier(), p, true, connectTimeout); + getHostnameVerifier(), p, true, connectTimeout, + this); } // will open new connection @@ -198,7 +199,7 @@ public abstract class AbstractDelegateHttpsURLConnection extends throws IOException { return HttpsClient.New(getSSLSocketFactory(), url, getHostnameVerifier(), p, - useCache, connectTimeout); + useCache, connectTimeout, this); } /** diff --git a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java index 4ead34da647..bf4c2b412ca 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.io.PrintStream; import java.io.BufferedOutputStream; +import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; import java.net.URL; @@ -46,11 +47,15 @@ import javax.security.auth.x500.X500Principal; import javax.net.ssl.*; import sun.net.www.http.HttpClient; +import sun.net.www.protocol.http.HttpURLConnection; import sun.security.action.*; import sun.security.util.HostnameChecker; import sun.security.ssl.SSLSocketImpl; +import sun.util.logging.PlatformLogger; +import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; + /** * This class provides HTTPS client URL support, building on the standard @@ -274,15 +279,17 @@ final class HttpsClient extends HttpClient // This code largely ripped off from HttpClient.New, and // it uses the same keepalive cache. - static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv) + static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, + HttpURLConnection httpuc) throws IOException { - return HttpsClient.New(sf, url, hv, true); + return HttpsClient.New(sf, url, hv, true, httpuc); } /** See HttpClient for the model for this method. */ static HttpClient New(SSLSocketFactory sf, URL url, - HostnameVerifier hv, boolean useCache) throws IOException { - return HttpsClient.New(sf, url, hv, (String)null, -1, useCache); + HostnameVerifier hv, boolean useCache, + HttpURLConnection httpuc) throws IOException { + return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc); } /** @@ -290,37 +297,74 @@ final class HttpsClient extends HttpClient * the specified proxy server. */ static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, - String proxyHost, int proxyPort) throws IOException { - return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true); + String proxyHost, int proxyPort, + HttpURLConnection httpuc) throws IOException { + return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc); } static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, - String proxyHost, int proxyPort, boolean useCache) + String proxyHost, int proxyPort, boolean useCache, + HttpURLConnection httpuc) throws IOException { - return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1); + return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1, + httpuc); } static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, String proxyHost, int proxyPort, boolean useCache, - int connectTimeout) + int connectTimeout, HttpURLConnection httpuc) throws IOException { return HttpsClient.New(sf, url, hv, (proxyHost == null? null : HttpsClient.newHttpProxy(proxyHost, proxyPort)), - useCache, connectTimeout); + useCache, connectTimeout, httpuc); } static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, Proxy p, boolean useCache, - int connectTimeout) - throws IOException { + int connectTimeout, HttpURLConnection httpuc) + throws IOException + { + if (p == null) { + p = Proxy.NO_PROXY; + } HttpsClient ret = null; if (useCache) { /* see if one's already around */ ret = (HttpsClient) kac.get(url, sf); + if (ret != null && httpuc != null && + httpuc.streaming() && + httpuc.getRequestMethod() == "POST") { + if (!ret.available()) + ret = null; + } + if (ret != null) { - ret.cachedHttpClient = true; + if ((ret.proxy != null && ret.proxy.equals(p)) || + (ret.proxy == null && p == null)) { + synchronized (ret) { + ret.cachedHttpClient = true; + assert ret.inCache; + ret.inCache = false; + if (httpuc != null && ret.needsTunneling()) + httpuc.setTunnelState(TUNNELING); + PlatformLogger logger = HttpURLConnection.getHttpLogger(); + if (logger.isLoggable(PlatformLogger.FINEST)) { + logger.finest("KeepAlive stream retrieved from the cache, " + ret); + } + } + } else { + // We cannot return this connection to the cache as it's + // KeepAliveTimeout will get reset. We simply close the connection. + // This should be fine as it is very rare that a connection + // to the same host will not use the same proxy. + synchronized(ret) { + ret.inCache = false; + ret.closeServer(); + } + ret = null; + } } } if (ret == null) { @@ -328,7 +372,11 @@ final class HttpsClient extends HttpClient } else { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkConnect(url.getHost(), url.getPort()); + if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) { + security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort()); + } else { + security.checkConnect(url.getHost(), url.getPort()); + } } ret.url = url; } @@ -607,6 +655,11 @@ final class HttpsClient extends HttpClient @Override protected void putInKeepAliveCache() { + if (inCache) { + assert false : "Duplicate put to keep alive cache"; + return; + } + inCache = true; kac.put(url, sslSocketFactory, this); } From d04381e42768fe3f92f4eaeea89f1fabe01cfa7f Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:42:22 -0700 Subject: [PATCH 086/137] Added tag jdk8-b82 for changeset caa9b4e63aab --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 8376608abe9..7b38704aae9 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -203,3 +203,4 @@ fd1a5574cf68af24bfd52decc37ac6361afb278a jdk8-b78 91d35211e74464dca5edf9b66ab01d0d0d8cded7 jdk8-b79 907a926d3c96472f357617b48b6b968ea855c23c jdk8-b80 145dbc56f931c134e837b675b9e6e7bf08902e93 jdk8-b81 +29153d0df68f84162ffe8c2cf4f402a3f2245e85 jdk8-b82 From c8f1a1b8e2c513f06643084aacf2504793fdb50c Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:42:42 -0700 Subject: [PATCH 087/137] Added tag jdk8-b82 for changeset e2239e25e90a --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index edf54fe6b06..92bf938663c 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -203,3 +203,4 @@ d4e68ce17795601017ac2f952baad7272942c36e jdk8-b75 e41fb1aa0329767b2737303c994e38bede1baa07 jdk8-b79 5f3d4a6bdd027a1631d97e2dfff63fd5e46987a4 jdk8-b80 2a00aeeb466b9dee22508f6261f63b70f9c696fe jdk8-b81 +48e1bc77004d9af575b733c04637b98fd17603c2 jdk8-b82 From 65547b27ffceaa270ad9cf1aa836b6de71a18273 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:42:51 -0700 Subject: [PATCH 088/137] Added tag jdk8-b82 for changeset 3826413d5c5b --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index aa835932b92..486a2cdf23e 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -324,3 +324,4 @@ df5396524152118535c36da5801d828b560d19a2 hs25-b21 dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22 65b797426a3bec6e91b64085a0cfb94adadb634a jdk8-b81 0631ebcc45f05c73b09a56c2586685af1f781c1d hs25-b23 +3db4ab0e12f437fe374817de346b2b0c6b4a5b31 jdk8-b82 From fd6ca911a563cde0c1e454ea630facb1b0f80533 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:43:06 -0700 Subject: [PATCH 089/137] Added tag jdk8-b82 for changeset 11e0f924d1ba --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 78505e9dc94..0c78beb6716 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -203,3 +203,4 @@ ff0b73a6b3f6cea644d37d56d746a37743419fa7 jdk8-b75 58fa065dd5d663d62f85402461388fb7a92656fa jdk8-b79 4873a0499bc3bd263b7dd3b551a2b4e275ab5a0b jdk8-b80 ef3495555a4c6e706a3058c18aa229b14220de0b jdk8-b81 +d5a58291f09a5081eaf22c2a6ab2f9ced4b78882 jdk8-b82 From c9e41a62381b4ee678416e48b35e6da3295b3891 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:43:09 -0700 Subject: [PATCH 090/137] Added tag jdk8-b82 for changeset d5a7172af7df --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index e683b469a5d..e02bdee2151 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -203,3 +203,4 @@ c4853f3f0e89ac60aa5b517f5f224f0f60e08577 jdk8-b76 70d8658d2a3063bc13127f3452af017d838f1362 jdk8-b79 b0224010e2f0c2474055ac592c8d3f37b9264690 jdk8-b80 c88bb21560ccf1a9e6d2a2ba08ed2045a002676f jdk8-b81 +d8d8032d02d77fbf5f9b3bb8df73663f42fd4dd0 jdk8-b82 From 6219b241119e21315cddc2beecb0956c6a855fca Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:43:23 -0700 Subject: [PATCH 091/137] Added tag jdk8-b82 for changeset 744dd8193801 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 92fe10a1d9a..607d2df6b05 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -203,3 +203,4 @@ b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77 c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79 dfb40f066c6ce129822f0f5dc2ac89173808781a jdk8-b80 c0f8022eba536dcdc8aae659005b33f3982b9368 jdk8-b81 +624bcb4800065c6656171948e31ebb2925f25c7a jdk8-b82 From 58859413d38fdebc4133b7c535a00c2ef4a30de8 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:43:39 -0700 Subject: [PATCH 092/137] Added tag jdk8-b82 for changeset db9ac0924815 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 71e9139a5d2..4f56fa54e99 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -203,3 +203,4 @@ af8417e590f4e76e0dfed09e71239fb102ef0d43 jdk8-b78 56dfafbb9e1ad7548a4415316dc003296fb498cb jdk8-b79 a8227c61768499dac847ea718af6719027c949f2 jdk8-b80 ed69d087fdfd394491657a28ba9bc58e7849b7db jdk8-b81 +825da6847791994a8f405ee397df9e7fa638a458 jdk8-b82 From 0fbaf75ff11f318ba969dec673edf0f4280b7fb8 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 21 Mar 2013 10:43:41 -0700 Subject: [PATCH 093/137] Added tag jdk8-b82 for changeset fd698c5ee684 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 4eb67ac90af..ef0d7251625 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -191,3 +191,4 @@ b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b66 b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b67 b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b68 b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b69 +5759f600fcf7b51ccc6cc8229be980e2153f8675 jdk8-b82 From 9b5ebab5f6be805e839ea42118d5a812b03531be Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 21 Mar 2013 16:31:48 -0700 Subject: [PATCH 094/137] 8009517: new code changes causing errors in old build (-Werror) environment Reviewed-by: mduigou --- jdk/make/com/sun/org/apache/xml/Makefile | 4 +++- jdk/make/javax/others/Makefile | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/make/com/sun/org/apache/xml/Makefile b/jdk/make/com/sun/org/apache/xml/Makefile index f00135d8d1e..b3568e40482 100644 --- a/jdk/make/com/sun/org/apache/xml/Makefile +++ b/jdk/make/com/sun/org/apache/xml/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2011, 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 @@ -34,6 +34,8 @@ JAVAC_MAX_WARNINGS = true JAVAC_WARNINGS_FATAL = true include $(BUILDDIR)/common/Defs.gmk +JAVAC_LINT_OPTIONS += -Xlint:-overrides + # # Files to compile # diff --git a/jdk/make/javax/others/Makefile b/jdk/make/javax/others/Makefile index b122c2063f5..7ee115142f4 100644 --- a/jdk/make/javax/others/Makefile +++ b/jdk/make/javax/others/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2011, 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 @@ -33,6 +33,8 @@ JAVAC_WARNINGS_FATAL = true include $(BUILDDIR)/common/Defs.gmk +JAVAC_LINT_OPTIONS += -Xlint:-deprecation + # # Files to compile # From ba67f14480f2c60aae9a8d4a7db2e69ff8823bb3 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Thu, 21 Mar 2013 20:46:46 -0700 Subject: [PATCH 095/137] 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash Call dlerror() in VM thread as necessary. Reviewed-by: coleenp, dholmes --- hotspot/src/os/linux/vm/os_linux.cpp | 32 ++++++++------ hotspot/src/os/linux/vm/os_linux.hpp | 3 +- .../test/runtime/8010389/VMThreadDlopen.java | 44 +++++++++++++++++++ 3 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 hotspot/test/runtime/8010389/VMThreadDlopen.java diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 59cb59d6805..29842b223f0 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -1811,13 +1811,15 @@ bool os::Linux::_stack_is_executable = false; class VM_LinuxDllLoad: public VM_Operation { private: const char *_filename; + char *_ebuf; + int _ebuflen; void *_lib; public: - VM_LinuxDllLoad(const char *fn) : - _filename(fn), _lib(NULL) {} + VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) : + _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {} VMOp_Type type() const { return VMOp_LinuxDllLoad; } void doit() { - _lib = os::Linux::dll_load_inner(_filename); + _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen); os::Linux::_stack_is_executable = true; } void* loaded_library() { return _lib; } @@ -1865,13 +1867,13 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) // This is for the case where the DLL has an static // constructor function that executes JNI code. We cannot // load such DLLs in the VMThread. - result = ::dlopen(filename, RTLD_LAZY); + result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); } ThreadInVMfromNative tiv(jt); debug_only(VMNativeEntryWrapper vew;) - VM_LinuxDllLoad op(filename); + VM_LinuxDllLoad op(filename, ebuf, ebuflen); VMThread::execute(&op); if (LoadExecStackDllInVMThread) { result = op.loaded_library(); @@ -1883,7 +1885,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) } if (!load_attempted) { - result = ::dlopen(filename, RTLD_LAZY); + result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); } if (result != NULL) { @@ -1892,11 +1894,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) } Elf32_Ehdr elf_head; - - // Read system error message into ebuf - // It may or may not be overwritten below - ::strncpy(ebuf, ::dlerror(), ebuflen-1); - ebuf[ebuflen-1]='\0'; int diag_msg_max_length=ebuflen-strlen(ebuf); char* diag_msg_buf=ebuf+strlen(ebuf); @@ -2039,10 +2036,19 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) return NULL; } -void * os::Linux::dll_load_inner(const char *filename) { +void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) { + void * result = ::dlopen(filename, RTLD_LAZY); + if (result == NULL) { + ::strncpy(ebuf, ::dlerror(), ebuflen - 1); + ebuf[ebuflen-1] = '\0'; + } + return result; +} + +void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) { void * result = NULL; if (LoadExecStackDllInVMThread) { - result = ::dlopen(filename, RTLD_LAZY); + result = dlopen_helper(filename, ebuf, ebuflen); } // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp index 356f7f67afa..c09be025c12 100644 --- a/hotspot/src/os/linux/vm/os_linux.hpp +++ b/hotspot/src/os/linux/vm/os_linux.hpp @@ -95,7 +95,8 @@ class Linux { public: static bool _stack_is_executable; - static void *dll_load_inner(const char *name); + static void *dlopen_helper(const char *name, char *ebuf, int ebuflen); + static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen); static void init_thread_fpu_state(); static int get_fpu_control_word(); diff --git a/hotspot/test/runtime/8010389/VMThreadDlopen.java b/hotspot/test/runtime/8010389/VMThreadDlopen.java new file mode 100644 index 00000000000..04407233773 --- /dev/null +++ b/hotspot/test/runtime/8010389/VMThreadDlopen.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. + */ + +import java.io.File; + +/* + * @test + * @key regression + * @bug 8010389 + * @run main/othervm -Djava.library.path=. VMThreadDlopen + */ + +public class VMThreadDlopen { + public static void main(String[] args) throws Exception { + File file = new File("libbroken.so"); + file.createNewFile(); + try { + System.loadLibrary("broken"); + } catch (UnsatisfiedLinkError e) { + e.printStackTrace(); + // expected + } + } +} From debc12e19ed492352c0625ca080acba573d20e55 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 22 Mar 2013 19:59:14 +0800 Subject: [PATCH 096/137] 8010531: Add BadKdc* tests to problem list for solaris-sparcv9 Reviewed-by: alanb --- jdk/test/ProblemList.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index befe68372f3..90d29821665 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -288,6 +288,12 @@ sun/security/tools/keytool/standard.sh solaris-all # 8000439: NPG: REGRESSION : sun/security/krb5/auto/MaxRetries.java fails with timeout sun/security/krb5/auto/MaxRetries.java solaris-sparcv9 +# 8006690: sun/security/krb5/auto/BadKdc1.java fails intermittently +sun/security/krb5/auto/BadKdc1.java solaris-sparcv9 +sun/security/krb5/auto/BadKdc2.java solaris-sparcv9 +sun/security/krb5/auto/BadKdc3.java solaris-sparcv9 +sun/security/krb5/auto/BadKdc4.java solaris-sparcv9 + # 7194428 sun/security/mscapi/ShortRSAKey1024.sh windows-all From 445664ec5207189fe011a5fbbd01ce815f5d8fe7 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Fri, 22 Mar 2013 15:01:14 +0100 Subject: [PATCH 097/137] 8005116: NPG: Rename -permstat option for jmap in jdk8 to -clstats Reviewed-by: jmasa, sla --- jdk/src/share/classes/sun/tools/jmap/JMap.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jmap/JMap.java b/jdk/src/share/classes/sun/tools/jmap/JMap.java index 5350c31ed0b..8c127ace9c1 100644 --- a/jdk/src/share/classes/sun/tools/jmap/JMap.java +++ b/jdk/src/share/classes/sun/tools/jmap/JMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, 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 @@ -50,7 +50,7 @@ public class JMap { // These options imply the use of a SA tool private static String SA_TOOL_OPTIONS = - "-heap|-heap:format=b|-permstat|-finalizerinfo"; + "-heap|-heap:format=b|-clstats|-finalizerinfo"; // The -F (force) option is currently not passed through to SA private static String FORCE_SA_OPTION = "-F"; @@ -147,12 +147,12 @@ public class JMap { // Invoke SA tool with the given arguments private static void runTool(String option, String args[]) throws Exception { String[][] tools = { - { "-pmap", "sun.jvm.hotspot.tools.PMap" }, - { "-heap", "sun.jvm.hotspot.tools.HeapSummary" }, - { "-heap:format=b", "sun.jvm.hotspot.tools.HeapDumper" }, - { "-histo", "sun.jvm.hotspot.tools.ObjectHistogram" }, - { "-permstat", "sun.jvm.hotspot.tools.PermStat" }, - { "-finalizerinfo", "sun.jvm.hotspot.tools.FinalizerInfo" }, + { "-pmap", "sun.jvm.hotspot.tools.PMap" }, + { "-heap", "sun.jvm.hotspot.tools.HeapSummary" }, + { "-heap:format=b", "sun.jvm.hotspot.tools.HeapDumper" }, + { "-histo", "sun.jvm.hotspot.tools.ObjectHistogram" }, + { "-clstats", "sun.jvm.hotspot.tools.ClassLoaderStats" }, + { "-finalizerinfo", "sun.jvm.hotspot.tools.FinalizerInfo" }, }; String tool = null; @@ -356,7 +356,7 @@ public class JMap { System.out.println(" -heap to print java heap summary"); System.out.println(" -histo[:live] to print histogram of java object heap; if the \"live\""); System.out.println(" suboption is specified, only count live objects"); - System.out.println(" -permstat to print permanent generation statistics"); + System.out.println(" -clstats to print class loader statistics"); System.out.println(" -finalizerinfo to print information on objects awaiting finalization"); System.out.println(" -dump: to dump java heap in hprof binary format"); System.out.println(" dump-options:"); From 1c46d9bac24b6ffe0d86d5cc9a191fa961722743 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Fri, 22 Mar 2013 15:01:24 +0100 Subject: [PATCH 098/137] 8004172: Update jstat counter names to reflect metaspace changes Reviewed-by: mchung --- .../sun/tools/jstat/resources/jstat_options | 66 +++++++------------ .../sun/tools/jstat/gcCapacityOutput1.awk | 8 +-- jdk/test/sun/tools/jstat/gcCauseOutput1.awk | 2 +- ...yOutput1.awk => gcMetaCapacityOutput1.awk} | 6 +- jdk/test/sun/tools/jstat/gcOldOutput1.awk | 4 +- jdk/test/sun/tools/jstat/gcOutput1.awk | 4 +- ...tput1.sh => jstatGcMetaCapacityOutput1.sh} | 8 +-- jdk/test/sun/tools/jstat/lineCounts1.awk | 4 +- jdk/test/sun/tools/jstat/lineCounts2.awk | 4 +- jdk/test/sun/tools/jstat/lineCounts3.awk | 4 +- jdk/test/sun/tools/jstat/lineCounts4.awk | 4 +- jdk/test/sun/tools/jstat/options1.out | 2 +- jdk/test/sun/tools/jstat/options2.out | 2 +- jdk/test/sun/tools/jstat/timeStamp1.awk | 4 +- .../sun/tools/jstatd/jstatGcutilOutput1.awk | 4 +- 15 files changed, 55 insertions(+), 71 deletions(-) rename jdk/test/sun/tools/jstat/{gcPermCapacityOutput1.awk => gcMetaCapacityOutput1.awk} (71%) rename jdk/test/sun/tools/jstat/{jstatGcPermCapacityOutput1.sh => jstatGcMetaCapacityOutput1.sh} (78%) diff --git a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options index 14a2d05e0ed..bead54260fd 100644 --- a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options +++ b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options @@ -192,16 +192,16 @@ option gc { format "0.0" } column { - header "^PC^" /* Perm Space Capacity - Current */ - data sun.gc.generation.2.space.0.capacity + header "^MC^" /* Metaspace Capacity - Current */ + data sun.gc.metaspace.capacity align center width 6 scale K format "0.0" } column { - header "^PU^" /* Perm Space Used */ - data sun.gc.generation.2.space.0.used + header "^MU^" /* Metaspae Used */ + data sun.gc.metaspace.used align center width 6 scale K @@ -330,32 +330,24 @@ option gccapacity { format "0.0" } column { - header "^PGCMN^" /* Perm Generation Capacity - Minimum */ - data sun.gc.generation.2.minCapacity + header "^MCMN^" /* Metaspace Capacity - Minimum */ + data sun.gc.metaspace.minCapacity scale K align right width 8 format "0.0" } column { - header "^PGCMX^" /* Perm Generation Capacity - Maximum */ - data sun.gc.generation.2.maxCapacity + header "^MCMX^" /* Metaspace Capacity - Maximum */ + data sun.gc.metaspace.maxCapacity scale K align right width 8 format "0.0" } column { - header "^PGC^" /* Perm Generation Capacity - Current */ - data sun.gc.generation.2.capacity - scale K - align right - width 8 - format "0.0" - } - column { - header "^PC^" /* Perm Space Capacity - Current */ - data sun.gc.generation.2.space.0.capacity + header "^MC^" /* Metaspace Capacity - Current */ + data sun.gc.metaspace.capacity scale K align right width 8 @@ -412,8 +404,8 @@ option gccause { format "0.00" } column { - header "^P^" /* Perm Space - Percent Used */ - data (1-((sun.gc.generation.2.space.0.capacity - sun.gc.generation.2.space.0.used)/sun.gc.generation.2.space.0.capacity)) * 100 + header "^M^" /* Metaspace - Percent Used */ + data (1-((sun.gc.metaspace.capacity - sun.gc.metaspace.used)/sun.gc.metaspace.capacity)) * 100 align right width 6 scale raw @@ -654,16 +646,16 @@ option gcnewcapacity { option gcold { column { - header "^PC^" /* Perm Space Capacity - Current */ - data sun.gc.generation.2.space.0.capacity + header "^MC^" /* Metaspace Capacity - Current */ + data sun.gc.metaspace.capacity width 8 align right scale K format "0.0" } column { - header "^PU^" /* Perm Space Used */ - data sun.gc.generation.2.space.0.used + header "^MU^" /* Metaspace Space Used */ + data sun.gc.metaspace.used width 8 align right scale K @@ -784,34 +776,26 @@ option gcoldcapacity { } } -option gcpermcapacity { +option gcmetacapacity { column { - header "^PGCMN^" /* Perm Generation Capacity - Minumum */ - data sun.gc.generation.2.minCapacity + header "^MCMN^" /* Metaspace Capacity - Minimum */ + data sun.gc.metaspace.minCapacity scale K align right width 10 format "0.0" } column { - header "^PGCMX^" /* Perm Generation Capacity - Maximum */ - data sun.gc.generation.2.maxCapacity + header "^MCMX^" /* Metaspace Capacity - Maximum */ + data sun.gc.metaspace.maxCapacity scale K align right width 10 format "0.0" } column { - header "^PGC^" /* Perm Generation Capacity - Current */ - data sun.gc.generation.2.capacity - scale K - align right - width 10 - format "0.0" - } - column { - header "^PC^" /* Perm Space Capacity - Current */ - data sun.gc.generation.2.space.0.capacity + header "^MC^" /* Metaspace Capacity - Current */ + data sun.gc.metaspace.capacity scale K align right width 10 @@ -884,8 +868,8 @@ option gcutil { format "0.00" } column { - header "^P^" /* Perm Space - Percent Used */ - data (1-((sun.gc.generation.2.space.0.capacity - sun.gc.generation.2.space.0.used)/sun.gc.generation.2.space.0.capacity)) * 100 + header "^M^" /* Metaspace Space - Percent Used */ + data (1-((sun.gc.metaspace.capacity - sun.gc.metaspace.used)/sun.gc.metaspace.capacity)) * 100 align right width 6 scale raw diff --git a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk index da3c7568ef4..c59de5f0bdb 100644 --- a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC -# 2176.0 7232.0 2176.0 64.0 64.0 2048.0 6016.0 58304.0 6016.0 6016.0 8192.0 65536.0 8192.0 8192.0 0 0 +# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC +# 2176.0 7232.0 2176.0 64.0 64.0 2048.0 6016.0 58304.0 6016.0 6016.0 8192.0 65536.0 8192.0 8192.0 0 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC $/ { +/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk index 0219697e73b..973d2c049e6 100644 --- a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk @@ -11,7 +11,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT LGCC GCC $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/gcPermCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk similarity index 71% rename from jdk/test/sun/tools/jstat/gcPermCapacityOutput1.awk rename to jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk index 5d41c2f92e0..c015dd69c94 100644 --- a/jdk/test/sun/tools/jstat/gcPermCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# PGCMN PGCMX PGC PC YGC FGC FGCT GCT +# MCMN MCMX MC YGC FGC FGCT GCT # 8192.0 65536.0 8192.0 8192.0 1 0 0.000 0.029 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ PGCMN PGCMX PGC PC YGC FGC FGCT GCT $/ { +/^ MCMN MCMX MC YGC FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcOldOutput1.awk b/jdk/test/sun/tools/jstat/gcOldOutput1.awk index 3c1e368769b..df7c6b582c5 100644 --- a/jdk/test/sun/tools/jstat/gcOldOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOldOutput1.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# PC PU OC OU YGC FGC FGCT GCT +# MC MU OC OU YGC FGC FGCT GCT # 8192.0 1877.3 6016.0 180.8 1 0 0.000 0.030 @@ -11,7 +11,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ PC PU OC OU YGC FGC FGCT GCT $/ { +/^ MC MU OC OU YGC FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/gcOutput1.awk b/jdk/test/sun/tools/jstat/gcOutput1.awk index bfad48fdf3f..5ac5b2837a2 100644 --- a/jdk/test/sun/tools/jstat/gcOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOutput1.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT +# S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT # 64.0 64.0 0.0 0.0 2048.0 1711.2 6016.0 0.0 8192.0 1948.6 0 0.000 0 0.000 0.000 @@ -11,7 +11,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT $/ { +/^ S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/jstatGcPermCapacityOutput1.sh b/jdk/test/sun/tools/jstat/jstatGcMetaCapacityOutput1.sh similarity index 78% rename from jdk/test/sun/tools/jstat/jstatGcPermCapacityOutput1.sh rename to jdk/test/sun/tools/jstat/jstatGcMetaCapacityOutput1.sh index 04754fe7a45..85aece158a4 100644 --- a/jdk/test/sun/tools/jstat/jstatGcPermCapacityOutput1.sh +++ b/jdk/test/sun/tools/jstat/jstatGcMetaCapacityOutput1.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. +# 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 @@ -23,8 +23,8 @@ # @test # @bug 4990825 -# @run shell jstatGcPermCapacityOutput1.sh -# @summary Test that output of 'jstat -gcpermcapcaity 0' has expected line counts +# @run shell jstatGcMetaCapacityOutput1.sh +# @summary Test that output of 'jstat -gcmetacapacity 0' has expected line counts . ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh @@ -33,4 +33,4 @@ verify_os JSTAT="${TESTJAVA}/bin/jstat" -${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcpermcapacity 0 2>&1 | awk -f ${TESTSRC}/gcPermCapacityOutput1.awk +${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcmetacapacity 0 2>&1 | awk -f ${TESTSRC}/gcMetaCapacityOutput1.awk diff --git a/jdk/test/sun/tools/jstat/lineCounts1.awk b/jdk/test/sun/tools/jstat/lineCounts1.awk index 4c1974d6633..33b2f08cc61 100644 --- a/jdk/test/sun/tools/jstat/lineCounts1.awk +++ b/jdk/test/sun/tools/jstat/lineCounts1.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 # 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 # 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 @@ -14,7 +14,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts2.awk b/jdk/test/sun/tools/jstat/lineCounts2.awk index 51e31846501..b1e80482241 100644 --- a/jdk/test/sun/tools/jstat/lineCounts2.awk +++ b/jdk/test/sun/tools/jstat/lineCounts2.awk @@ -3,14 +3,14 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts3.awk b/jdk/test/sun/tools/jstat/lineCounts3.awk index c50db509c27..e7c362fbd8f 100644 --- a/jdk/test/sun/tools/jstat/lineCounts3.awk +++ b/jdk/test/sun/tools/jstat/lineCounts3.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 # 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 # 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 @@ -19,7 +19,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts4.awk b/jdk/test/sun/tools/jstat/lineCounts4.awk index 3a36b119240..af9487edb27 100644 --- a/jdk/test/sun/tools/jstat/lineCounts4.awk +++ b/jdk/test/sun/tools/jstat/lineCounts4.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 # 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 # 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 @@ -22,7 +22,7 @@ BEGIN { datalines2=0; } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstat/options1.out b/jdk/test/sun/tools/jstat/options1.out index e6eaf667261..18c2162cc5c 100644 --- a/jdk/test/sun/tools/jstat/options1.out +++ b/jdk/test/sun/tools/jstat/options1.out @@ -3,10 +3,10 @@ -gc -gccapacity -gccause +-gcmetacapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity --gcpermcapacity -gcutil -printcompilation diff --git a/jdk/test/sun/tools/jstat/options2.out b/jdk/test/sun/tools/jstat/options2.out index 5d05d60f0dc..27da99b6f99 100644 --- a/jdk/test/sun/tools/jstat/options2.out +++ b/jdk/test/sun/tools/jstat/options2.out @@ -4,10 +4,10 @@ -gc -gccapacity -gccause +-gcmetacapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity --gcpermcapacity -gcutil -printcompilation diff --git a/jdk/test/sun/tools/jstat/timeStamp1.awk b/jdk/test/sun/tools/jstat/timeStamp1.awk index 907198b33f3..825101b3ac4 100644 --- a/jdk/test/sun/tools/jstat/timeStamp1.awk +++ b/jdk/test/sun/tools/jstat/timeStamp1.awk @@ -3,14 +3,14 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^Timestamp S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^Timestamp S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } diff --git a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk index 4c1974d6633..33b2f08cc61 100644 --- a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk +++ b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk @@ -3,7 +3,7 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT +# S0 S1 E O M YGC YGCT FGC FGCT GCT # 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 # 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 # 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 @@ -14,7 +14,7 @@ BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O P YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { headerlines++; } From 902be4665bd0f42d5add136a3c13f61175a78cf2 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Fri, 22 Mar 2013 16:10:01 +0100 Subject: [PATCH 099/137] 8000754: NPG: Implement a MemoryPool MXBean for Metaspace Reviewed-by: jmasa, stefank --- hotspot/src/share/vm/memory/metaspace.hpp | 8 +- hotspot/src/share/vm/memory/universe.cpp | 1 + .../src/share/vm/services/memoryManager.cpp | 4 + .../src/share/vm/services/memoryManager.hpp | 10 +++ hotspot/src/share/vm/services/memoryPool.cpp | 34 +++++++++ hotspot/src/share/vm/services/memoryPool.hpp | 26 +++++++ .../src/share/vm/services/memoryService.cpp | 21 +++++- .../src/share/vm/services/memoryService.hpp | 5 ++ .../metaspace/TestMetaspaceMemoryPools.java | 75 +++++++++++++++++++ 9 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index f704804795f..56197fdd070 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -157,16 +157,16 @@ class Metaspace : public CHeapObj { class MetaspaceAux : AllStatic { + static size_t free_chunks_total(Metaspace::MetadataType mdtype); + static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); + + public: // Statistics for class space and data space in metaspace. static size_t used_in_bytes(Metaspace::MetadataType mdtype); static size_t free_in_bytes(Metaspace::MetadataType mdtype); static size_t capacity_in_bytes(Metaspace::MetadataType mdtype); static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); - static size_t free_chunks_total(Metaspace::MetadataType mdtype); - static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); - - public: // Total of space allocated to metadata in all Metaspaces static size_t used_in_bytes() { return used_in_bytes(Metaspace::ClassType) + diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 79e092a3b19..4406addc9e8 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1108,6 +1108,7 @@ bool universe_post_init() { // Initialize performance counters for metaspaces MetaspaceCounters::initialize_performance_counters(); + MemoryService::add_metaspace_memory_pools(); GC_locker::unlock(); // allow gc after bootstrapping diff --git a/hotspot/src/share/vm/services/memoryManager.cpp b/hotspot/src/share/vm/services/memoryManager.cpp index 3996d2163c8..d5e54f5ff15 100644 --- a/hotspot/src/share/vm/services/memoryManager.cpp +++ b/hotspot/src/share/vm/services/memoryManager.cpp @@ -61,6 +61,10 @@ MemoryManager* MemoryManager::get_code_cache_memory_manager() { return (MemoryManager*) new CodeCacheMemoryManager(); } +MemoryManager* MemoryManager::get_metaspace_memory_manager() { + return (MemoryManager*) new MetaspaceMemoryManager(); +} + GCMemoryManager* MemoryManager::get_copy_memory_manager() { return (GCMemoryManager*) new CopyMemoryManager(); } diff --git a/hotspot/src/share/vm/services/memoryManager.hpp b/hotspot/src/share/vm/services/memoryManager.hpp index 370d830e977..12c0a0ec458 100644 --- a/hotspot/src/share/vm/services/memoryManager.hpp +++ b/hotspot/src/share/vm/services/memoryManager.hpp @@ -56,6 +56,7 @@ public: enum Name { Abstract, CodeCache, + Metaspace, Copy, MarkSweepCompact, ParNew, @@ -88,6 +89,7 @@ public: // Static factory methods to get a memory manager of a specific type static MemoryManager* get_code_cache_memory_manager(); + static MemoryManager* get_metaspace_memory_manager(); static GCMemoryManager* get_copy_memory_manager(); static GCMemoryManager* get_msc_memory_manager(); static GCMemoryManager* get_parnew_memory_manager(); @@ -108,6 +110,14 @@ public: const char* name() { return "CodeCacheManager"; } }; +class MetaspaceMemoryManager : public MemoryManager { +public: + MetaspaceMemoryManager() : MemoryManager() {} + + MemoryManager::Name kind() { return MemoryManager::Metaspace; } + const char *name() { return "MetaspaceManager"; } +}; + class GCStatInfo : public ResourceObj { private: size_t _index; diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index e2895b1f816..969ed7f22bf 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -26,12 +26,15 @@ #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "oops/oop.inline.hpp" +#include "runtime/globals.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" +#include "runtime/os.hpp" #include "services/lowMemoryDetector.hpp" #include "services/management.hpp" #include "services/memoryManager.hpp" #include "services/memoryPool.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" MemoryPool::MemoryPool(const char* name, @@ -256,3 +259,34 @@ MemoryUsage CodeHeapPool::get_memory_usage() { return MemoryUsage(initial_size(), used, committed, maxSize); } + +MetaspacePoolBase::MetaspacePoolBase(const char *name, + Metaspace::MetadataType md_type, + size_t max_size) : + _md_type(md_type), + MemoryPool(name, NonHeap, MetaspaceAux::capacity_in_bytes(_md_type), max_size, + true, false) { } + +size_t MetaspacePoolBase::used_in_bytes() { + return MetaspaceAux::used_in_bytes(_md_type); +} + +MemoryUsage MetaspacePoolBase::get_memory_usage() { + size_t used = MetaspaceAux::used_in_bytes(_md_type); + size_t committed = align_size_down_(MetaspaceAux::capacity_in_bytes(_md_type), os::vm_page_size()); + return MemoryUsage(initial_size(), used, committed, max_size()); +} + +ClassMetaspacePool::ClassMetaspacePool() : + MetaspacePoolBase("Class Metaspace", Metaspace::ClassType, calculate_max_size()) { } + +size_t ClassMetaspacePool::calculate_max_size() { + return UseCompressedKlassPointers ? ClassMetaspaceSize : _undefined_max_size; +} + +MetaspacePool::MetaspacePool() : + MetaspacePoolBase("Metaspace", Metaspace::NonClassType, calculate_max_size()) { } + +size_t MetaspacePool::calculate_max_size() { + return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : _undefined_max_size; +} diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp index 82606185340..f36c3984ced 100644 --- a/hotspot/src/share/vm/services/memoryPool.hpp +++ b/hotspot/src/share/vm/services/memoryPool.hpp @@ -28,6 +28,7 @@ #include "gc_implementation/shared/mutableSpace.hpp" #include "memory/defNewGeneration.hpp" #include "memory/heap.hpp" +#include "memory/metaspace.hpp" #include "memory/space.hpp" #include "services/memoryUsage.hpp" #include "utilities/macros.hpp" @@ -222,4 +223,29 @@ public: size_t used_in_bytes() { return _codeHeap->allocated_capacity(); } }; +class MetaspacePoolBase : public MemoryPool { +private: + Metaspace::MetadataType _md_type; +protected: + static const size_t _undefined_max_size = (size_t) -1; +public: + MetaspacePoolBase(const char *name, Metaspace::MetadataType md_type, size_t max_size); + MemoryUsage get_memory_usage(); + size_t used_in_bytes(); +}; + +class ClassMetaspacePool : public MetaspacePoolBase { +private: + size_t calculate_max_size(); +public: + ClassMetaspacePool(); +}; + +class MetaspacePool : public MetaspacePoolBase { +private: + size_t calculate_max_size(); +public: + MetaspacePool(); +}; + #endif // SHARE_VM_SERVICES_MEMORYPOOL_HPP diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index 0040f9d96fc..168d9909c9b 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -60,9 +60,11 @@ GrowableArray* MemoryService::_pools_list = GrowableArray* MemoryService::_managers_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(init_managers_list_size, true); -GCMemoryManager* MemoryService::_minor_gc_manager = NULL; -GCMemoryManager* MemoryService::_major_gc_manager = NULL; -MemoryPool* MemoryService::_code_heap_pool = NULL; +GCMemoryManager* MemoryService::_minor_gc_manager = NULL; +GCMemoryManager* MemoryService::_major_gc_manager = NULL; +MemoryPool* MemoryService::_code_heap_pool = NULL; +MemoryPool* MemoryService::_metaspace_pool = NULL; +MemoryPool* MemoryService::_class_metaspace_pool = NULL; class GcThreadCountClosure: public ThreadClosure { private: @@ -398,6 +400,19 @@ void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) { _managers_list->append(mgr); } +void MemoryService::add_metaspace_memory_pools() { + _metaspace_pool = new MetaspacePool(); + _class_metaspace_pool = new ClassMetaspacePool(); + + MemoryManager* mgr = MemoryManager::get_metaspace_memory_manager(); + mgr->add_pool(_metaspace_pool); + mgr->add_pool(_class_metaspace_pool); + + _pools_list->append(_metaspace_pool); + _pools_list->append(_class_metaspace_pool); + _managers_list->append(mgr); +} + MemoryManager* MemoryService::get_memory_manager(instanceHandle mh) { for (int i = 0; i < _managers_list->length(); i++) { MemoryManager* mgr = _managers_list->at(i); diff --git a/hotspot/src/share/vm/services/memoryService.hpp b/hotspot/src/share/vm/services/memoryService.hpp index 44cf62ea3cb..fcd2fdf421d 100644 --- a/hotspot/src/share/vm/services/memoryService.hpp +++ b/hotspot/src/share/vm/services/memoryService.hpp @@ -73,6 +73,10 @@ private: // Code heap memory pool static MemoryPool* _code_heap_pool; + // Metaspace pools + static MemoryPool* _metaspace_pool; + static MemoryPool* _class_metaspace_pool; + static void add_generation_memory_pool(Generation* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr); @@ -121,6 +125,7 @@ private: public: static void set_universe_heap(CollectedHeap* heap); static void add_code_heap_memory_pool(CodeHeap* heap); + static void add_metaspace_memory_pools(); static MemoryPool* get_memory_pool(instanceHandle pool); static MemoryManager* get_memory_manager(instanceHandle mgr); diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java new file mode 100644 index 00000000000..884f377bc22 --- /dev/null +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java @@ -0,0 +1,75 @@ +import java.util.List; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryManagerMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; + +/* @test TestMetaspaceMemoryPools + * @bug 8000754 + * @summary Tests that two MemoryPoolMXBeans are created, one for metaspace and + * one for class metaspace, is created and that a MemoryManagerMXBean + * is created. + * @run main/othervm TestMetaspaceMemoryPools defined undefined + * @run main/othervm -XX:-UseCompressedKlassPointers TestMetaspaceMemoryPools undefined undefined + * @run main/othervm -XX:-UseCompressedKlassPointers -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPools undefined defined + */ +public class TestMetaspaceMemoryPools { + public static void main(String[] args) { + boolean isClassMetaspaceMaxDefined = args[0].equals("defined"); + boolean isMetaspaceMaxDefined = args[1].equals("defined"); + + verifyThatMetaspaceMemoryManagerExists(); + + verifyMemoryPool(getMemoryPool("Class Metaspace"), isClassMetaspaceMaxDefined); + verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined); + } + + private static void verifyThatMetaspaceMemoryManagerExists() { + List managers = ManagementFactory.getMemoryManagerMXBeans(); + for (MemoryManagerMXBean manager : managers) { + if (manager.getName().equals("MetaspaceManager")) { + return; + } + } + + throw new RuntimeException("Expected to find a metaspace memory manager"); + } + + private static MemoryPoolMXBean getMemoryPool(String name) { + List pools = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean pool : pools) { + if (pool.getName().equals(name)) { + return pool; + } + } + + throw new RuntimeException("Expected to find a memory pool with name " + name); + } + + private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) { + MemoryUsage mu = pool.getUsage(); + assertDefined(mu.getInit(), "init"); + assertDefined(mu.getUsed(), "used"); + assertDefined(mu.getCommitted(), "committed"); + + if (isMaxDefined) { + assertDefined(mu.getMax(), "max"); + } else { + assertUndefined(mu.getMax(), "max"); + } + } + + private static void assertDefined(long value, String name) { + assertTrue(value != -1, "Expected " + name + " to be defined"); + } + + private static void assertUndefined(long value, String name) { + assertTrue(value == -1, "Expected " + name + " to be undefined"); + } + + private static void assertTrue(boolean condition, String msg) { + if (!condition) { + throw new RuntimeException(msg); + } + } +} From 439ddacaac5ca158c924dc737ab53bf9cf812dd6 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Fri, 22 Mar 2013 19:56:20 +0400 Subject: [PATCH 100/137] 7123476: DesktopOpenTests:When enter the file path and click the open button,it crash Reviewed-by: art, anthony --- jdk/make/sun/xawt/FILES_c_unix.gmk | 3 +- jdk/makefiles/CompileNativeLibraries.gmk | 3 +- .../solaris/native/sun/awt/gtk2_interface.c | 35 +++++- .../solaris/native/sun/awt/gtk2_interface.h | 16 ++- jdk/src/solaris/native/sun/xawt/awt_Desktop.c | 105 +++++------------- .../solaris/native/sun/xawt/gnome_interface.c | 87 +++++++++++++++ .../solaris/native/sun/xawt/gnome_interface.h | 39 +++++++ 7 files changed, 209 insertions(+), 79 deletions(-) create mode 100644 jdk/src/solaris/native/sun/xawt/gnome_interface.c create mode 100644 jdk/src/solaris/native/sun/xawt/gnome_interface.h diff --git a/jdk/make/sun/xawt/FILES_c_unix.gmk b/jdk/make/sun/xawt/FILES_c_unix.gmk index 0ce8bdd11f5..74ea1cd2ced 100644 --- a/jdk/make/sun/xawt/FILES_c_unix.gmk +++ b/jdk/make/sun/xawt/FILES_c_unix.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 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 @@ -76,6 +76,7 @@ FILES_c = \ debug_trace.c \ debug_util.c \ awt_Plugin.c \ + gnome_interface.c \ gtk2_interface.c \ swing_GTKEngine.c \ swing_GTKStyle.c \ diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 9df22fe8b6a..3e3751435a2 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.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 @@ -843,6 +843,7 @@ LIBAWT_XAWT_FILES:=\ debug_trace.c \ debug_util.c \ awt_Plugin.c \ + gnome_interface.c \ gtk2_interface.c \ swing_GTKEngine.c \ swing_GTKStyle.c \ diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.c b/jdk/src/solaris/native/sun/awt/gtk2_interface.c index cb93366be69..daca810e5a5 100644 --- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c +++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, 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 @@ -437,6 +437,39 @@ gboolean gtk2_check_version() } } +/** + * Functions for awt_Desktop.c + */ +gboolean gtk2_show_uri_load() { + gboolean success = FALSE; + dlerror(); + const char *gtk_version = fp_gtk_check_version(2, 14, 0); + if (gtk_version != NULL) { + // The gtk_show_uri is available from GTK+ 2.14 +#ifdef INTERNAL_BUILD + fprintf (stderr, "The version of GTK is %s. " + "The gtk_show_uri function is supported " + "since GTK+ 2.14.\n", gtk_version); +#endif /* INTERNAL_BUILD */ + } else { + // Loading symbols only if the GTK version is 2.14 and higher + fp_gtk_show_uri = dl_symbol("gtk_show_uri"); + const char *dlsym_error = dlerror(); + if (dlsym_error) { +#ifdef INTERNAL_BUILD + fprintf (stderr, "Cannot load symbol: %s \n", dlsym_error); +#endif /* INTERNAL_BUILD */ + } else if (fp_gtk_show_uri == NULL) { +#ifdef INTERNAL_BUILD + fprintf(stderr, "dlsym(gtk_show_uri) returned NULL\n"); +#endif /* INTERNAL_BUILD */ + } else { + success = TRUE; + } + } + return success; +} + /** * Functions for sun_awt_X11_GtkFileDialogPeer.c */ diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.h b/jdk/src/solaris/native/sun/awt/gtk2_interface.h index 1b46920a534..22ba24a49ae 100644 --- a/jdk/src/solaris/native/sun/awt/gtk2_interface.h +++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, 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 @@ -42,6 +42,7 @@ #define GTK_STOCK_CANCEL "gtk-cancel" #define GTK_STOCK_SAVE "gtk-save" #define GTK_STOCK_OPEN "gtk-open" +#define GDK_CURRENT_TIME 0L typedef enum _WidgetType { @@ -280,6 +281,7 @@ struct _GSList typedef void GdkColormap; typedef void GdkDrawable; typedef void GdkGC; +typedef void GdkScreen; typedef void GdkPixbuf; typedef void GdkPixmap; typedef void GdkWindow; @@ -663,6 +665,15 @@ gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor, */ gboolean gtk2_load(); +/* + * Loads fp_gtk_show_uri function pointer. This initialization is + * separated because the function is required only + * for java.awt.Desktop API. The function relies on initialization in + * gtk2_load, so it must be invoked only after a successful gtk2_load + * invocation + */ +gboolean gtk2_show_uri_load(); + /* * Unload the gtk2 library. If the library is already unloaded this method has * no effect and returns success. @@ -795,4 +806,7 @@ void (*fp_gdk_threads_init)(void); void (*fp_gdk_threads_enter)(void); void (*fp_gdk_threads_leave)(void); +gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri, + guint32 timestamp, GError **error); + #endif /* !_GTK2_INTERFACE_H */ diff --git a/jdk/src/solaris/native/sun/xawt/awt_Desktop.c b/jdk/src/solaris/native/sun/xawt/awt_Desktop.c index b8b250beb18..317af3dfaa2 100644 --- a/jdk/src/solaris/native/sun/xawt/awt_Desktop.c +++ b/jdk/src/solaris/native/sun/xawt/awt_Desktop.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, 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 @@ -23,71 +23,11 @@ * questions. */ -#include -#include -#include +#include "gtk2_interface.h" +#include "gnome_interface.h" -typedef int gboolean; - -typedef gboolean (GNOME_URL_SHOW_TYPE)(const char *, void **); -typedef gboolean (GNOME_VFS_INIT_TYPE)(void); - -GNOME_URL_SHOW_TYPE *gnome_url_show; -GNOME_VFS_INIT_TYPE *gnome_vfs_init; - -int init(){ - void *vfs_handle; - void *gnome_handle; - const char *errmsg; - - vfs_handle = dlopen(VERSIONED_JNI_LIB_NAME("gnomevfs-2", "0"), RTLD_LAZY); - if (vfs_handle == NULL) { - vfs_handle = dlopen(JNI_LIB_NAME("gnomevfs-2"), RTLD_LAZY); - if (vfs_handle == NULL) { -#ifdef INTERNAL_BUILD - fprintf(stderr, "can not load libgnomevfs-2.so\n"); -#endif - return 0; - } - } - dlerror(); /* Clear errors */ - gnome_vfs_init = (GNOME_VFS_INIT_TYPE*)dlsym(vfs_handle, "gnome_vfs_init"); - if (gnome_vfs_init == NULL){ -#ifdef INTERNAL_BUILD - fprintf(stderr, "dlsym( gnome_vfs_init) returned NULL\n"); -#endif - return 0; - } - if ((errmsg = dlerror()) != NULL) { -#ifdef INTERNAL_BUILD - fprintf(stderr, "can not find symbol gnome_vfs_init %s \n", errmsg); -#endif - return 0; - } - // call gonme_vfs_init() - (*gnome_vfs_init)(); - - gnome_handle = dlopen(VERSIONED_JNI_LIB_NAME("gnome-2", "0"), RTLD_LAZY); - if (gnome_handle == NULL) { - gnome_handle = dlopen(JNI_LIB_NAME("gnome-2"), RTLD_LAZY); - if (gnome_handle == NULL) { -#ifdef INTERNAL_BUILD - fprintf(stderr, "can not load libgnome-2.so\n"); -#endif - return 0; - } - } - dlerror(); /* Clear errors */ - gnome_url_show = (GNOME_URL_SHOW_TYPE*)dlsym(gnome_handle, "gnome_url_show"); - if ((errmsg = dlerror()) != NULL) { -#ifdef INTERNAL_BUILD - fprintf(stderr, "can not find symble gnome_url_show\n"); -#endif - return 0; - } - - return 1; -} +static gboolean gtk_has_been_loaded = FALSE; +static gboolean gnome_has_been_loaded = FALSE; /* * Class: sun_awt_X11_XDesktopPeer @@ -97,8 +37,20 @@ int init(){ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init (JNIEnv *env, jclass cls) { - int init_ok = init(); - return init_ok ? JNI_TRUE : JNI_FALSE; + + if (gtk_has_been_loaded || gnome_has_been_loaded) { + return JNI_TRUE; + } + + if (gtk2_load() && gtk2_show_uri_load()) { + gtk_has_been_loaded = TRUE; + return JNI_TRUE; + } else if (gnome_load()) { + gnome_has_been_loaded = TRUE; + return JNI_TRUE; + } + + return JNI_FALSE; } /* @@ -109,16 +61,19 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show (JNIEnv *env, jobject obj, jbyteArray url_j) { - gboolean success; - const char* url_c; - - if (gnome_url_show == NULL) { - return JNI_FALSE; - } + gboolean success = FALSE; + const gchar* url_c; url_c = (char*)(*env)->GetByteArrayElements(env, url_j, NULL); - // call gnome_url_show(const char* , GError**) - success = (*gnome_url_show)(url_c, NULL); + + if (gtk_has_been_loaded) { + fp_gdk_threads_enter(); + success = fp_gtk_show_uri(NULL, url_c, GDK_CURRENT_TIME, NULL); + fp_gdk_threads_leave(); + } else if (gnome_has_been_loaded) { + success = (*gnome_url_show)(url_c, NULL); + } + (*env)->ReleaseByteArrayElements(env, url_j, (signed char*)url_c, 0); return success ? JNI_TRUE : JNI_FALSE; diff --git a/jdk/src/solaris/native/sun/xawt/gnome_interface.c b/jdk/src/solaris/native/sun/xawt/gnome_interface.c new file mode 100644 index 00000000000..90d56de93d1 --- /dev/null +++ b/jdk/src/solaris/native/sun/xawt/gnome_interface.c @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#include "gnome_interface.h" + +GNOME_URL_SHOW_TYPE *gnome_url_show = NULL; + +gboolean gnome_load() { + void *vfs_handle; + void *gnome_handle; + const char *errmsg; + GNOME_VFS_INIT_TYPE *gnome_vfs_init; + + // trying to open the gnomevfs. VERSIONED_JNI_LIB_NAME + // macros formats the library name in a system specific manner + // see jdk/src/solaris/javavm/export/jvm_md.h for more details + vfs_handle = dlopen(VERSIONED_JNI_LIB_NAME("gnomevfs-2", "0"), RTLD_LAZY); + if (vfs_handle == NULL) { + // if we cannot load the library using a version assumed by JNI + // we are trying to load the library without a version suffix + vfs_handle = dlopen(JNI_LIB_NAME("gnomevfs-2"), RTLD_LAZY); + if (vfs_handle == NULL) { + #ifdef INTERNAL_BUILD + fprintf(stderr, "can not load libgnomevfs-2.so\n"); + #endif + return FALSE; + } + } + dlerror(); /* Clear errors */ + gnome_vfs_init = (GNOME_VFS_INIT_TYPE*)dlsym(vfs_handle, "gnome_vfs_init"); + if (gnome_vfs_init == NULL){ + #ifdef INTERNAL_BUILD + fprintf(stderr, "dlsym( gnome_vfs_init) returned NULL\n"); + #endif + return FALSE; + } + if ((errmsg = dlerror()) != NULL) { + #ifdef INTERNAL_BUILD + fprintf(stderr, "can not find symbol gnome_vfs_init %s \n", errmsg); + #endif + return FALSE; + } + // call gonme_vfs_init() + (*gnome_vfs_init)(); + + gnome_handle = dlopen(VERSIONED_JNI_LIB_NAME("gnome-2", "0"), RTLD_LAZY); + if (gnome_handle == NULL) { + gnome_handle = dlopen(JNI_LIB_NAME("gnome-2"), RTLD_LAZY); + if (gnome_handle == NULL) { + #ifdef INTERNAL_BUILD + fprintf(stderr, "can not load libgnome-2.so\n"); + #endif + return FALSE; + } + } + dlerror(); /* Clear errors */ + gnome_url_show = (GNOME_URL_SHOW_TYPE*)dlsym(gnome_handle, "gnome_url_show"); + if ((errmsg = dlerror()) != NULL) { + #ifdef INTERNAL_BUILD + fprintf(stderr, "can not find symble gnome_url_show\n"); + #endif + return FALSE; + } + return TRUE; +} diff --git a/jdk/src/solaris/native/sun/xawt/gnome_interface.h b/jdk/src/solaris/native/sun/xawt/gnome_interface.h new file mode 100644 index 00000000000..2ca444725e8 --- /dev/null +++ b/jdk/src/solaris/native/sun/xawt/gnome_interface.h @@ -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. 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. + */ + +#ifndef _GNOME_INTERFACE_H +#define _GNOME_INTERFACE_H +#include "gtk2_interface.h" +#include +#include +#include + +typedef gboolean (GNOME_URL_SHOW_TYPE)(const char *, void **); +typedef gboolean (GNOME_VFS_INIT_TYPE)(void); + +extern GNOME_URL_SHOW_TYPE *gnome_url_show; +gboolean gnome_load(); + +#endif /* !_GNOME_INTERFACE_H */ From 7188961426d46639e8ed1f0ab134d4f91fb1cdca Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Sat, 23 Mar 2013 00:58:39 +0100 Subject: [PATCH 101/137] 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable Reviewed-by: jlaskey, lagergren --- nashorn/make/project.properties | 2 +- .../jdk/nashorn/internal/codegen/Attr.java | 443 +++++++++++------- .../internal/codegen/ClassEmitter.java | 12 +- .../internal/codegen/CodeGenerator.java | 236 +++++----- .../internal/codegen/CompilationPhase.java | 49 +- .../nashorn/internal/codegen/Compiler.java | 3 +- .../internal/codegen/FinalizeTypes.java | 164 ++++--- .../internal/codegen/FoldConstants.java | 14 +- .../internal/codegen/FunctionSignature.java | 2 +- .../jdk/nashorn/internal/codegen/Lower.java | 247 +++++----- .../internal/codegen/MethodEmitter.java | 5 +- .../nashorn/internal/codegen/Splitter.java | 81 ++-- .../nashorn/internal/codegen/WeighNodes.java | 81 ++-- .../jdk/nashorn/internal/ir/AccessNode.java | 15 +- .../jdk/nashorn/internal/ir/Assignment.java | 7 + .../src/jdk/nashorn/internal/ir/BaseNode.java | 13 +- .../jdk/nashorn/internal/ir/BinaryNode.java | 22 +- .../src/jdk/nashorn/internal/ir/Block.java | 360 ++------------ .../jdk/nashorn/internal/ir/BreakNode.java | 4 +- .../src/jdk/nashorn/internal/ir/CallNode.java | 12 +- .../src/jdk/nashorn/internal/ir/CaseNode.java | 4 +- .../jdk/nashorn/internal/ir/CatchNode.java | 4 +- .../jdk/nashorn/internal/ir/ContinueNode.java | 4 +- .../jdk/nashorn/internal/ir/DoWhileNode.java | 4 +- .../jdk/nashorn/internal/ir/EmptyNode.java | 4 +- .../jdk/nashorn/internal/ir/ExecuteNode.java | 4 +- .../src/jdk/nashorn/internal/ir/ForNode.java | 4 +- .../jdk/nashorn/internal/ir/FunctionNode.java | 326 ++++--------- .../jdk/nashorn/internal/ir/IdentNode.java | 63 ++- .../src/jdk/nashorn/internal/ir/IfNode.java | 4 +- .../jdk/nashorn/internal/ir/IndexNode.java | 9 +- .../jdk/nashorn/internal/ir/LabelNode.java | 4 +- .../nashorn/internal/ir/LexicalContext.java | 198 ++++++++ .../nashorn/internal/ir/LineNumberNode.java | 4 +- .../jdk/nashorn/internal/ir/LiteralNode.java | 34 +- .../src/jdk/nashorn/internal/ir/Location.java | 6 +- nashorn/src/jdk/nashorn/internal/ir/Node.java | 18 +- .../jdk/nashorn/internal/ir/ObjectNode.java | 4 +- .../jdk/nashorn/internal/ir/PropertyNode.java | 4 +- .../nashorn/internal/ir/ReferenceNode.java | 91 ---- .../jdk/nashorn/internal/ir/ReturnNode.java | 4 +- .../jdk/nashorn/internal/ir/RuntimeNode.java | 9 +- .../jdk/nashorn/internal/ir/SplitNode.java | 4 +- .../jdk/nashorn/internal/ir/SwitchNode.java | 4 +- .../src/jdk/nashorn/internal/ir/Symbol.java | 60 +-- .../jdk/nashorn/internal/ir/TernaryNode.java | 18 +- .../jdk/nashorn/internal/ir/ThrowNode.java | 4 +- .../src/jdk/nashorn/internal/ir/TryNode.java | 13 +- .../jdk/nashorn/internal/ir/TypeOverride.java | 6 +- .../jdk/nashorn/internal/ir/UnaryNode.java | 22 +- .../src/jdk/nashorn/internal/ir/VarNode.java | 88 ++-- .../jdk/nashorn/internal/ir/WhileNode.java | 4 +- .../src/jdk/nashorn/internal/ir/WithNode.java | 4 +- .../nashorn/internal/ir/debug/JSONWriter.java | 79 ++-- .../internal/ir/debug/PrintVisitor.java | 78 ++- .../ir/visitor/NodeOperatorVisitor.java | 16 +- .../internal/ir/visitor/NodeVisitor.java | 151 +++--- .../jdk/nashorn/internal/parser/Parser.java | 219 +++++---- .../jdk/nashorn/internal/runtime/Context.java | 2 +- .../runtime/resources/Messages.properties | 4 +- nashorn/test/script/basic/JDK-8006755.js | 2 +- nashorn/test/script/basic/NASHORN-837.js | 24 +- .../internal/codegen/CompilerTest.java | 12 +- 63 files changed, 1671 insertions(+), 1721 deletions(-) create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java delete mode 100644 nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 60444de766b..58da977dc4a 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -210,7 +210,7 @@ run.test.xms=2G # add '-Dtest.js.outofprocess' to run each test in a new sub-process run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:-TieredCompilation -esa -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8 #-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs} +run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main} run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index a441ef4d94c..938055984cd 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -37,14 +37,16 @@ import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; import static jdk.nashorn.internal.ir.Symbol.IS_LET; import static jdk.nashorn.internal.ir.Symbol.IS_PARAM; +import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE; import static jdk.nashorn.internal.ir.Symbol.IS_THIS; import static jdk.nashorn.internal.ir.Symbol.IS_VAR; +import static jdk.nashorn.internal.ir.Symbol.KINDMASK; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Set; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; @@ -52,19 +54,19 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CallNode.EvalArgs; -import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; 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.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.ObjectNode; import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; @@ -117,6 +119,8 @@ final class Attr extends NodeOperatorVisitor { */ private Set localUses; + private final LexicalContext lexicalContext = new LexicalContext(); + private static final DebugLogger LOG = new DebugLogger("attr"); private static final boolean DEBUG = LOG.isEnabled(); @@ -137,14 +141,15 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final AccessNode accessNode) { + public Node leaveAccessNode(final AccessNode accessNode) { newTemporary(Type.OBJECT, accessNode); //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this end(accessNode); return accessNode; } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { + lexicalContext.push(block); start(block); final Set savedLocalDefs = localDefs; @@ -160,9 +165,7 @@ final class Attr extends NodeOperatorVisitor { localDefs = new HashSet<>(savedLocalDefs); localUses = new HashSet<>(savedLocalUses); - for (final Node statement : block.getStatements()) { - statement.accept(this); - } + block.visitStatements(this); } finally { localDefs = savedLocalDefs; localUses = savedLocalUses; @@ -172,11 +175,12 @@ final class Attr extends NodeOperatorVisitor { end(block); + lexicalContext.pop(block); return null; } @Override - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { start(callNode); callNode.getFunction().accept(this); @@ -197,8 +201,7 @@ final class Attr extends NodeOperatorVisitor { evalArgs.setThis(thisNode); } - newTemporary(Type.OBJECT, callNode); // object type here, access specialization in FinalizeTypes may narrow it later - newType(callNode.getFunction().getSymbol(), Type.OBJECT); + newTemporary(callNode.getType(), callNode); // access specialization in FinalizeTypes may narrow it further later end(callNode); @@ -206,29 +209,106 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final CatchNode catchNode) { + public Node enterCatchNode(final CatchNode catchNode) { final IdentNode exception = catchNode.getException(); final Block block = getCurrentBlock(); start(catchNode); // define block-local exception variable - final Symbol def = block.defineSymbol(exception.getName(), IS_VAR | IS_LET, exception); + final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET, exception); newType(def, Type.OBJECT); addLocalDef(exception.getName()); return catchNode; } + /** + * Declare the definition of a new symbol. + * + * @param name Name of symbol. + * @param symbolFlags Symbol flags. + * @param node Defining Node. + * + * @return Symbol for given name or null for redefinition. + */ + private Symbol defineSymbol(final Block block, final String name, final int symbolFlags, final Node node) { + int flags = symbolFlags; + Symbol symbol = findSymbol(block, name); // Locate symbol. + + if ((flags & KINDMASK) == IS_GLOBAL) { + flags |= IS_SCOPE; + } + + final FunctionNode function = lexicalContext.getFunction(block); + if (symbol != null) { + // Symbol was already defined. Check if it needs to be redefined. + if ((flags & KINDMASK) == IS_PARAM) { + if (!isLocal(function, symbol)) { + // Not defined in this function. Create a new definition. + symbol = null; + } else if (symbol.isParam()) { + // Duplicate parameter. Null return will force an error. + assert false : "duplicate parameter"; + return null; + } + } else if ((flags & KINDMASK) == IS_VAR) { + if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) { + assert !((flags & IS_LET) == IS_LET && symbol.getBlock() == block) : "duplicate let variable in block"; + // Always create a new definition. + symbol = null; + } else { + // Not defined in this function. Create a new definition. + if (!isLocal(function, symbol) || symbol.less(IS_VAR)) { + symbol = null; + } + } + } + } + + if (symbol == null) { + // If not found, then create a new one. + Block symbolBlock; + + // Determine where to create it. + if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { + symbolBlock = block; + } else { + symbolBlock = function; + } + + // Create and add to appropriate block. + symbol = new Symbol(name, flags, node, symbolBlock); + symbolBlock.putSymbol(name, symbol); + + if ((flags & Symbol.KINDMASK) != IS_GLOBAL) { + symbolBlock.getFrame().addSymbol(symbol); + symbol.setNeedsSlot(true); + } + } else if (symbol.less(flags)) { + symbol.setFlags(flags); + } + + if (node != null) { + node.setSymbol(symbol); + } + + return symbol; + } + @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { start(functionNode, false); if (functionNode.isLazy()) { - LOG.info("LAZY: " + functionNode.getName()); + LOG.info("LAZY: " + functionNode.getName() + " => Promoting to OBJECT"); + newTemporary(lexicalContext.getCurrentFunction(), Type.OBJECT, functionNode); + functionNode.setReturnType(Type.OBJECT); end(functionNode); return null; } + lexicalContext.push(functionNode); + clearLocalDefs(); clearLocalUses(); @@ -244,24 +324,36 @@ final class Attr extends NodeOperatorVisitor { initScope(functionNode); initReturn(functionNode); - // Add all nested functions as symbols in this function - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { + // Add all nested declared functions as symbols in this function + for (final FunctionNode nestedFunction : functionNode.getDeclaredFunctions()) { final IdentNode ident = nestedFunction.getIdent(); - if (ident != null && nestedFunction.isStatement()) { - final Symbol functionSymbol = functionNode.defineSymbol(ident.getName(), IS_VAR, nestedFunction); + if (ident != null) { + assert nestedFunction.isDeclared(); + final Symbol functionSymbol = defineSymbol(functionNode, ident.getName(), IS_VAR, nestedFunction); newType(functionSymbol, Type.typeFor(ScriptFunction.class)); } } - if (functionNode.isScript()) { + if (functionNode.isProgram()) { initFromPropertyMap(functionNode); } // Add function name as local symbol - if (!functionNode.isStatement() && !functionNode.isAnonymous() && !functionNode.isScript()) { - final Symbol selfSymbol = functionNode.defineSymbol(functionNode.getIdent().getName(), IS_VAR, functionNode); - newType(selfSymbol, Type.OBJECT); - selfSymbol.setNode(functionNode); + if (!functionNode.isDeclared() && !functionNode.isProgram()) { + if(functionNode.getSymbol() != null) { + // a temporary left over from an earlier pass when the function was lazy + assert functionNode.getSymbol().isTemp(); + // remove it + functionNode.setSymbol(null); + } + final Symbol selfSymbol; + if(functionNode.isAnonymous()) { + selfSymbol = newTemporary(functionNode, Type.OBJECT, functionNode); + } else { + selfSymbol = defineSymbol(functionNode, functionNode.getIdent().getName(), IS_VAR, functionNode); + newType(selfSymbol, Type.OBJECT); + selfSymbol.setNode(functionNode); + } } /* @@ -282,32 +374,26 @@ final class Attr extends NodeOperatorVisitor { */ final List declaredSymbols = new ArrayList<>(); - for (final VarNode decl : functionNode.getDeclarations()) { - final IdentNode ident = decl.getName(); - // any declared symbols that aren't visited need to be typed as well, hence the list - declaredSymbols.add(functionNode.defineSymbol(ident.getName(), IS_VAR, new IdentNode(ident))); - } - - // Every nested function needs a definition in the outer function with its name. Add these. - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { - final VarNode varNode = nestedFunction.getFunctionVarNode(); - if (varNode != null) { - varNode.accept(this); - assert varNode.isFunctionVarNode() : varNode + " should be function var node"; + // This visitor will assign symbol to all declared variables, except function declarations (which are taken care + // in a separate step above) and "var" declarations in for loop initializers. + functionNode.accept(new NodeOperatorVisitor() { + @Override + public Node enterFunctionNode(FunctionNode nestedFn) { + // Don't descend into nested functions + return nestedFn == functionNode ? nestedFn : null; } - } - - for (final Node statement : functionNode.getStatements()) { - if (statement instanceof VarNode && ((VarNode)statement).isFunctionVarNode()) { - continue; //var nodes have already been processed, skip or they will generate additional defs/uses and false "can be undefined" + @Override + public Node enterVarNode(VarNode varNode) { + if(varNode.isStatement() && !varNode.isFunctionDeclaration()) { + final IdentNode ident = varNode.getName(); + // any declared symbols that aren't visited need to be typed as well, hence the list + declaredSymbols.add(defineSymbol(functionNode, ident.getName(), IS_VAR, new IdentNode(ident))); + } + return null; } - statement.accept(this); - } + }); - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { - LOG.info("Going into nested function " + functionNode.getName() + " -> " + nestedFunction.getName()); - nestedFunction.accept(this); - } + visitFunctionStatements(functionNode); //unknown parameters are promoted to object type. finalizeParameters(functionNode); @@ -343,10 +429,19 @@ final class Attr extends NodeOperatorVisitor { functionNode.setState(CompilationState.ATTR); end(functionNode, false); + lexicalContext.pop(functionNode); return null; } + private void visitFunctionStatements(final FunctionNode functionNode) { + final List newStatements = new ArrayList<>(functionNode.getStatements()); + for(ListIterator stmts = newStatements.listIterator(); stmts.hasNext();) { + stmts.set(stmts.next().accept(this)); + } + functionNode.setStatements(newStatements); + } + @Override public Node leaveCONVERT(final UnaryNode unaryNode) { assert false : "There should be no convert operators in IR during Attribution"; @@ -355,7 +450,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { final String name = identNode.getName(); start(identNode); @@ -372,7 +467,7 @@ final class Attr extends NodeOperatorVisitor { final Block block = getCurrentBlock(); final Symbol oldSymbol = identNode.getSymbol(); - Symbol symbol = block.findSymbol(name); + Symbol symbol = findSymbol(block, name); //If an existing symbol with the name is found, use that otherwise, declare a new one if (symbol != null) { @@ -396,22 +491,13 @@ final class Attr extends NodeOperatorVisitor { } identNode.setSymbol(symbol); - if (!getCurrentFunctionNode().isLocal(symbol)) { - // non-local: we need to put symbol in scope (if it isn't already) - if (!symbol.isScope()) { - final List lookupBlocks = findLookupBlocksHelper(getCurrentFunctionNode(), symbol.findFunction()); - for (final Block lookupBlock : lookupBlocks) { - final Symbol refSymbol = lookupBlock.findSymbol(name); - if (refSymbol != null) { // See NASHORN-837, function declaration in lexical scope: try {} catch (x){ function f() { use(x) } } f() - LOG.finest("Found a ref symbol that must be scope " + refSymbol); - refSymbol.setIsScope(); - } - } - } + // non-local: we need to put symbol in scope (if it isn't already) + if (!isLocal(getCurrentFunctionNode(), symbol) && !symbol.isScope()) { + symbol.setIsScope(); } } else { LOG.info("No symbol exists. Declare undefined: " + symbol); - symbol = block.useSymbol(name, identNode); + symbol = useSymbol(block, name, identNode); // we have never seen this before, it can be undefined newType(symbol, Type.OBJECT); // TODO unknown -we have explicit casts anyway? symbol.setCanBeUndefined(); @@ -420,9 +506,10 @@ final class Attr extends NodeOperatorVisitor { assert symbol != null; if(symbol.isGlobal()) { - getCurrentFunctionNode().setUsesGlobalSymbol(); + setUsesGlobalSymbol(); } else if(symbol.isScope()) { - getCurrentFunctionNode().setUsesScopeSymbol(symbol); + final Iterator blocks = lexicalContext.getBlocks(); + blocks.next().setUsesScopeSymbol(symbol, blocks); } if (symbol != oldSymbol && !identNode.isInitializedHere()) { @@ -435,15 +522,68 @@ final class Attr extends NodeOperatorVisitor { return null; } + /** + * Marks the current function as one using any global symbol. The function and all its parent functions will all be + * marked as needing parent scope. + * @see #needsParentScope() + */ + private void setUsesGlobalSymbol() { + for(final Iterator fns = lexicalContext.getFunctions(); fns.hasNext();) { + fns.next().setUsesAncestorScope(); + } + } + + /** + * Declare the use of a symbol in a block. + * + * @param block block in which the symbol is used + * @param name Name of symbol. + * @param node Using node + * + * @return Symbol for given name. + */ + private Symbol useSymbol(final Block block, final String name, final Node node) { + Symbol symbol = findSymbol(block, name); + + if (symbol == null) { + // If not found, declare as a free var. + symbol = defineSymbol(block, name, IS_GLOBAL, node); + } else { + node.setSymbol(symbol); + } + + return symbol; + } + + + /** + * Search for symbol in the lexical context starting from the given block. + * @param name Symbol name. + * @return Found symbol or null if not found. + */ + private Symbol findSymbol(final Block block, final String name) { + // Search up block chain to locate symbol. + + for(final Iterator blocks = lexicalContext.getBlocks(block); blocks.hasNext();) { + // Find name. + final Symbol symbol = blocks.next().getExistingSymbol(name); + // If found then we are good. + if(symbol != null) { + return symbol; + } + } + return null; + } + @Override - public Node leave(final IndexNode indexNode) { + public Node leaveIndexNode(final IndexNode indexNode) { newTemporary(Type.OBJECT, indexNode); //TORO return indexNode; } @SuppressWarnings("rawtypes") @Override - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { try { start(literalNode); assert !literalNode.isTokenType(TokenType.THIS) : "tokentype for " + literalNode + " is this"; //guard against old dead code case. literal nodes should never inherit tokens @@ -472,14 +612,14 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final ObjectNode objectNode) { + public Node leaveObjectNode(final ObjectNode objectNode) { newTemporary(Type.OBJECT, objectNode); end(objectNode); return objectNode; } @Override - public Node enter(final PropertyNode propertyNode) { + public Node enterPropertyNode(final PropertyNode propertyNode) { // assign a pseudo symbol to property name, see NASHORN-710 propertyNode.setSymbol(new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT)); end(propertyNode); @@ -487,31 +627,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final ReferenceNode referenceNode) { - final FunctionNode functionNode = referenceNode.getReference(); - if (functionNode != null) { - functionNode.addReferencingParentBlock(getCurrentBlock()); - } - return referenceNode; - } - - @Override - public Node leave(final ReferenceNode referenceNode) { - newTemporary(Type.OBJECT, referenceNode); //reference node type is always an object, i.e. the scriptFunction. the function return type varies though - - final FunctionNode functionNode = referenceNode.getReference(); - //assert !functionNode.getType().isUnknown() || functionNode.isLazy() : functionNode.getType(); - if (functionNode.isLazy()) { - LOG.info("Lazy function node call reference: " + functionNode.getName() + " => Promoting to OBJECT"); - functionNode.setReturnType(Type.OBJECT); - } - end(referenceNode); - - return referenceNode; - } - - @Override - public Node leave(final ReturnNode returnNode) { + public Node leaveReturnNode(final ReturnNode returnNode) { final Node expr = returnNode.getExpression(); if (expr != null) { @@ -530,7 +646,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final SwitchNode switchNode) { + public Node leaveSwitchNode(final SwitchNode switchNode) { Type type = Type.UNKNOWN; for (final CaseNode caseNode : switchNode.getCases()) { @@ -567,7 +683,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final TryNode tryNode) { + public Node leaveTryNode(final TryNode tryNode) { tryNode.setException(exceptionSymbol()); if (tryNode.getFinallyBody() != null) { @@ -580,13 +696,13 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final VarNode varNode) { + public Node enterVarNode(final VarNode varNode) { start(varNode); final IdentNode ident = varNode.getName(); final String name = ident.getName(); - final Symbol symbol = getCurrentBlock().defineSymbol(name, IS_VAR, ident); + final Symbol symbol = defineSymbol(getCurrentBlock(), name, IS_VAR, ident); assert symbol != null; LOG.info("VarNode " + varNode + " set symbol " + symbol); @@ -598,23 +714,15 @@ final class Attr extends NodeOperatorVisitor { symbol.setCanBeUndefined(); } - if (varNode.getInit() != null) { - varNode.getInit().accept(this); - } - return varNode; } @Override - public Node leave(final VarNode varNode) { + public Node leaveVarNode(final VarNode varNode) { final Node init = varNode.getInit(); final IdentNode ident = varNode.getName(); final String name = ident.getName(); - if (init != null) { - addLocalDef(name); - } - if (init == null) { // var x; with no init will be treated like a use of x by // visit(IdentNode) unless we remove the name @@ -623,8 +731,10 @@ final class Attr extends NodeOperatorVisitor { return varNode; } + addLocalDef(name); + final Symbol symbol = varNode.getSymbol(); - final boolean isScript = symbol.getBlock().getFunction().isScript(); //see NASHORN-56 + final boolean isScript = lexicalContext.getFunction(symbol.getBlock()).isProgram(); //see NASHORN-56 if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) { // Forbid integers as local vars for now as we have no way to treat them as undefined newType(symbol, init.getType()); @@ -718,11 +828,9 @@ final class Attr extends NodeOperatorVisitor { runtimeNode = new RuntimeNode(unaryNode, request, args); assert runtimeNode.getSymbol() == unaryNode.getSymbol(); //clone constructor should do this - runtimeNode.accept(this); - return runtimeNode; + return leaveRuntimeNode(runtimeNode); } - @Override public Node leaveNEW(final UnaryNode unaryNode) { newTemporary(Type.OBJECT, unaryNode); @@ -755,7 +863,7 @@ final class Attr extends NodeOperatorVisitor { runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args); assert runtimeNode.getSymbol() == unaryNode.getSymbol(); - runtimeNode.accept(this); + runtimeNode = (RuntimeNode)leaveRuntimeNode(runtimeNode); end(unaryNode); @@ -763,7 +871,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final RuntimeNode runtimeNode) { + public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { newTemporary(runtimeNode.getRequest().getReturnType(), runtimeNode); return runtimeNode; } @@ -823,12 +931,12 @@ final class Attr extends NodeOperatorVisitor { final IdentNode ident = (IdentNode)lhs; final String name = ident.getName(); - Symbol symbol = getCurrentBlock().findSymbol(name); + Symbol symbol = findSymbol(getCurrentBlock(), name); if (symbol == null) { - symbol = block.defineSymbol(name, IS_GLOBAL, ident); + symbol = defineSymbol(block, name, IS_GLOBAL, ident); binaryNode.setSymbol(symbol); - } else if (!getCurrentFunctionNode().isLocal(symbol)) { + } else if (!isLocal(getCurrentFunctionNode(), symbol)) { symbol.setIsScope(); } @@ -838,6 +946,12 @@ final class Attr extends NodeOperatorVisitor { return binaryNode; } + private boolean isLocal(FunctionNode function, Symbol symbol) { + final Block block = symbol.getBlock(); + // some temp symbols have no block, so can be assumed local + return block == null || lexicalContext.getFunction(block) == function; + } + @Override public Node enterASSIGN(final BinaryNode binaryNode) { return enterAssignmentNode(binaryNode); @@ -995,7 +1109,7 @@ final class Attr extends NodeOperatorVisitor { return leaveBinaryArithmetic(binaryNode); } - private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) { + private Node leaveCmp(final BinaryNode binaryNode) { final Node lhs = binaryNode.lhs(); final Node rhs = binaryNode.rhs(); @@ -1033,37 +1147,38 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveEQ(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.EQ); + return leaveCmp(binaryNode); } @Override public Node leaveEQ_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.EQ_STRICT); + return leaveCmp(binaryNode); } @Override public Node leaveGE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.GE); + return leaveCmp(binaryNode); } @Override public Node leaveGT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.GT); + return leaveCmp(binaryNode); } @Override public Node leaveIN(final BinaryNode binaryNode) { - try { - return new RuntimeNode(binaryNode, Request.IN).accept(this); - } finally { - end(binaryNode); - } + return leaveBinaryRuntimeOperator(binaryNode, Request.IN); } @Override public Node leaveINSTANCEOF(final BinaryNode binaryNode) { + return leaveBinaryRuntimeOperator(binaryNode, Request.INSTANCEOF); + } + + private Node leaveBinaryRuntimeOperator(final BinaryNode binaryNode, final Request request) { try { - return new RuntimeNode(binaryNode, Request.INSTANCEOF).accept(this); + // Don't do a full RuntimeNode.accept, as we don't want to double-visit the binary node operands + return leaveRuntimeNode(new RuntimeNode(binaryNode, request)); } finally { end(binaryNode); } @@ -1071,12 +1186,12 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveLE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.LE); + return leaveCmp(binaryNode); } @Override public Node leaveLT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.LT); + return leaveCmp(binaryNode); } @Override @@ -1091,12 +1206,12 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveNE(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.NE); + return leaveCmp(binaryNode); } @Override public Node leaveNE_STRICT(final BinaryNode binaryNode) { - return leaveCmp(binaryNode, Request.NE_STRICT); + return leaveCmp(binaryNode); } @Override @@ -1127,9 +1242,9 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final ForNode forNode) { + public Node leaveForNode(final ForNode forNode) { if (forNode.isForIn()) { - forNode.setIterator(newInternal(getCurrentFunctionNode(), getCurrentFunctionNode().uniqueName(ITERATOR_PREFIX.tag()), Type.OBJECT)); //NASHORN-73 + forNode.setIterator(newInternal(getCurrentFunctionNode().uniqueName(ITERATOR_PREFIX.tag()), Type.OBJECT)); //NASHORN-73 /* * Iterators return objects, so we need to widen the scope of the * init variable if it, for example, has been assigned double type @@ -1144,7 +1259,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node leave(final TernaryNode ternaryNode) { + public Node leaveTernaryNode(final TernaryNode ternaryNode) { final Node lhs = ternaryNode.rhs(); final Node rhs = ternaryNode.third(); @@ -1159,24 +1274,24 @@ final class Attr extends NodeOperatorVisitor { return ternaryNode; } - private static void initThis(final FunctionNode functionNode) { - final Symbol thisSymbol = functionNode.defineSymbol(THIS.tag(), IS_PARAM | IS_THIS, null); + private void initThis(final FunctionNode functionNode) { + final Symbol thisSymbol = defineSymbol(functionNode, THIS.tag(), IS_PARAM | IS_THIS, null); newType(thisSymbol, Type.OBJECT); thisSymbol.setNeedsSlot(true); functionNode.getThisNode().setSymbol(thisSymbol); LOG.info("Initialized scope symbol: " + thisSymbol); } - private static void initScope(final FunctionNode functionNode) { - final Symbol scopeSymbol = functionNode.defineSymbol(SCOPE.tag(), IS_VAR | IS_INTERNAL, null); + private void initScope(final FunctionNode functionNode) { + final Symbol scopeSymbol = defineSymbol(functionNode, SCOPE.tag(), IS_VAR | IS_INTERNAL, null); newType(scopeSymbol, Type.typeFor(ScriptObject.class)); scopeSymbol.setNeedsSlot(true); functionNode.getScopeNode().setSymbol(scopeSymbol); LOG.info("Initialized scope symbol: " + scopeSymbol); } - private static void initReturn(final FunctionNode functionNode) { - final Symbol returnSymbol = functionNode.defineSymbol(SCRIPT_RETURN.tag(), IS_VAR | IS_INTERNAL, null); + private void initReturn(final FunctionNode functionNode) { + final Symbol returnSymbol = defineSymbol(functionNode, SCRIPT_RETURN.tag(), IS_VAR | IS_INTERNAL, null); newType(returnSymbol, Type.OBJECT); returnSymbol.setNeedsSlot(true); functionNode.getResultNode().setSymbol(returnSymbol); @@ -1186,7 +1301,7 @@ final class Attr extends NodeOperatorVisitor { private void initVarArg(final FunctionNode functionNode) { if (functionNode.isVarArg()) { - final Symbol varArgsSymbol = functionNode.defineSymbol(VARARGS.tag(), IS_PARAM | IS_INTERNAL, null); + final Symbol varArgsSymbol = defineSymbol(functionNode, VARARGS.tag(), IS_PARAM | IS_INTERNAL, null); varArgsSymbol.setTypeOverride(Type.OBJECT_ARRAY); varArgsSymbol.setNeedsSlot(true); functionNode.getVarArgsNode().setSymbol(varArgsSymbol); @@ -1194,7 +1309,7 @@ final class Attr extends NodeOperatorVisitor { if (functionNode.needsArguments()) { final String argumentsName = functionNode.getArgumentsNode().getName(); - final Symbol argumentsSymbol = functionNode.defineSymbol(argumentsName, IS_VAR | IS_INTERNAL, null); + final Symbol argumentsSymbol = defineSymbol(functionNode, argumentsName, IS_VAR | IS_INTERNAL, null); newType(argumentsSymbol, Type.typeFor(ScriptObject.class)); argumentsSymbol.setNeedsSlot(true); functionNode.getArgumentsNode().setSymbol(argumentsSymbol); @@ -1204,9 +1319,9 @@ final class Attr extends NodeOperatorVisitor { } } - private static void initCallee(final FunctionNode functionNode) { + private void initCallee(final FunctionNode functionNode) { assert functionNode.getCalleeNode() != null : functionNode + " has no callee"; - final Symbol calleeSymbol = functionNode.defineSymbol(CALLEE.tag(), IS_PARAM | IS_INTERNAL, null); + final Symbol calleeSymbol = defineSymbol(functionNode, CALLEE.tag(), IS_PARAM | IS_INTERNAL, null); newType(calleeSymbol, Type.typeFor(ScriptFunction.class)); calleeSymbol.setNeedsSlot(true); functionNode.getCalleeNode().setSymbol(calleeSymbol); @@ -1226,7 +1341,7 @@ final class Attr extends NodeOperatorVisitor { for (final IdentNode param : functionNode.getParameters()) { addLocalDef(param.getName()); - final Symbol paramSymbol = functionNode.defineSymbol(param.getName(), IS_PARAM, param); + final Symbol paramSymbol = defineSymbol(functionNode, param.getName(), IS_PARAM, param); if (paramSymbol != null) { final Type callSiteParamType = functionNode.getSpecializedType(param); if (callSiteParamType != null) { @@ -1279,15 +1394,15 @@ final class Attr extends NodeOperatorVisitor { * Move any properties from a global map into the scope of this method * @param functionNode the function node for which to init scope vars */ - private static void initFromPropertyMap(final FunctionNode functionNode) { + private void initFromPropertyMap(final FunctionNode functionNode) { // For a script, add scope symbols as defined in the property map - assert functionNode.isScript(); + assert functionNode.isProgram(); final PropertyMap map = Context.getGlobalMap(); for (final Property property : map.getProperties()) { final String key = property.getKey(); - final Symbol symbol = functionNode.defineSymbol(key, IS_GLOBAL, null); + final Symbol symbol = defineSymbol(functionNode, key, IS_GLOBAL, null); newType(symbol, Type.OBJECT); LOG.info("Added global symbol from property map " + symbol); } @@ -1354,7 +1469,7 @@ final class Attr extends NodeOperatorVisitor { private static void ensureAssignmentSlots(final FunctionNode functionNode, final Node assignmentDest) { assignmentDest.accept(new NodeVisitor() { @Override - public Node leave(final IndexNode indexNode) { + public Node leaveIndexNode(final IndexNode indexNode) { final Node index = indexNode.getIndex(); index.getSymbol().setNeedsSlot(!index.getSymbol().isConstant()); return indexNode; @@ -1399,7 +1514,7 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final FunctionNode node) { + public Node enterFunctionNode(final FunctionNode node) { return node.isLazy() ? null : node; } @@ -1419,7 +1534,7 @@ final class Attr extends NodeOperatorVisitor { */ @SuppressWarnings("fallthrough") @Override - public Node leave(final BinaryNode binaryNode) { + public Node leaveBinaryNode(final BinaryNode binaryNode) { final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType()); switch (binaryNode.tokenType()) { default: @@ -1477,22 +1592,6 @@ final class Attr extends NodeOperatorVisitor { return binaryNode; } - private static List findLookupBlocksHelper(final FunctionNode currentFunction, final FunctionNode topFunction) { - if (currentFunction.findParentFunction() == topFunction) { - final List blocks = new LinkedList<>(); - - blocks.add(currentFunction.getParent()); - blocks.addAll(currentFunction.getReferencingParentBlocks()); - return blocks; - } - /* - * assumption: all parent blocks of an inner function will always be in the same outer function; - * therefore we can simply skip through intermediate functions. - * @see FunctionNode#addReferencingParentBlock(Block) - */ - return findLookupBlocksHelper(currentFunction.findParentFunction(), topFunction); - } - private static boolean isFunctionExpressionSelfReference(final Symbol symbol) { if (symbol.isVar() && symbol.getNode() == symbol.getBlock() && symbol.getNode() instanceof FunctionNode) { return ((FunctionNode)symbol.getNode()).getIdent().getName().equals(symbol.getName()); @@ -1509,16 +1608,12 @@ final class Attr extends NodeOperatorVisitor { return newTemporary(getCurrentFunctionNode(), type, node); } - private Symbol newInternal(final FunctionNode functionNode, final String name, final Type type) { - final Symbol iter = getCurrentFunctionNode().defineSymbol(name, IS_VAR | IS_INTERNAL, null); + private Symbol newInternal(final String name, final Type type) { + final Symbol iter = defineSymbol(getCurrentFunctionNode(), name, IS_VAR | IS_INTERNAL, null); iter.setType(type); // NASHORN-73 return iter; } - private Symbol newInternal(final String name, final Type type) { - return newInternal(getCurrentFunctionNode(), name, type); - } - private static void newType(final Symbol symbol, final Type type) { final Type oldType = symbol.getSymbolType(); symbol.setType(type); @@ -1577,13 +1672,13 @@ final class Attr extends NodeOperatorVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { toObject(block); return block; } @Override - public Node enter(final FunctionNode node) { + public Node enterFunctionNode(final FunctionNode node) { toObject(node); if (node.isLazy()) { return null; diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java index 35e74824958..7ca7f994311 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java @@ -194,6 +194,14 @@ public class ClassEmitter implements Emitter { defineCommonStatics(strictMode); } + /** + * Returns the name of the compile unit class name. + * @return the name of the compile unit class name. + */ + String getUnitClassName() { + return unitClassName; + } + /** * Convert a binary name to a package/class name. * @@ -244,7 +252,7 @@ public class ClassEmitter implements Emitter { // $getMap - get the ith entry from the constants table and cast to PropertyMap. final MethodEmitter getMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), GET_MAP.tag(), PropertyMap.class, int.class); getMapMethod.begin(); - getMapMethod.loadConstants(unitClassName) + getMapMethod.loadConstants() .load(Type.INT, 0) .arrayload() .checkcast(PropertyMap.class) @@ -254,7 +262,7 @@ public class ClassEmitter implements Emitter { // $setMap - overwrite an existing map. final MethodEmitter setMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), SET_MAP.tag(), void.class, int.class, PropertyMap.class); setMapMethod.begin(); - setMapMethod.loadConstants(unitClassName) + setMapMethod.loadConstants() .load(Type.INT, 0) .load(Type.OBJECT, 1) .arraystore(); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index ce6a1fcdfdf..1d09e9c98e0 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -76,18 +76,18 @@ import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; 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.LineNumberNode; import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; @@ -107,6 +107,7 @@ import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Lexer.RegexToken; import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; @@ -156,12 +157,20 @@ final class CodeGenerator extends NodeOperatorVisitor { /** How many regexp fields have been emitted */ private int regexFieldCount; + /** Used for temporary signaling between enterCallNode and enterFunctionNode to handle the special case of calling + * a just-defined anonymous function expression. */ + private boolean functionNodeIsCallee; + /** Map of shared scope call sites */ private final Map scopeCalls = new HashMap<>(); + private final LexicalContext lexicalContext = new LexicalContext(); + /** When should we stop caching regexp expressions in fields to limit bytecode size? */ private static final int MAX_REGEX_FIELDS = 2 * 1024; + private static final DebugLogger LOG = new DebugLogger("codegen", "nashorn.codegen.debug"); + /** * Constructor. * @@ -210,7 +219,7 @@ final class CodeGenerator extends NodeOperatorVisitor { final int flags = CALLSITE_SCOPE | getCallSiteFlags(); method.loadScope(); - if (symbol.isFastScope(getCurrentFunctionNode())) { + if (isFastScope(symbol)) { // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope. if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) { return loadSharedScopeVar(identNode.getType(), symbol, flags); @@ -221,8 +230,28 @@ final class CodeGenerator extends NodeOperatorVisitor { } } + /** + * Check if this symbol can be accessed directly with a putfield or getfield or dynamic load + * + * @param function function to check for fast scope + * @return true if fast scope + */ + private boolean isFastScope(final Symbol symbol) { + if (!symbol.isScope() || !symbol.getBlock().needsScope()) { + return false; + } + // Allow fast scope access if no function contains with or eval + for(final Iterator it = lexicalContext.getFunctions(getCurrentFunctionNode()); it.hasNext();) { + final FunctionNode func = it.next(); + if (func.hasWith() || func.hasEval()) { + return false; + } + } + return true; + } + private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) { - method.load(symbol.isFastScope(getCurrentFunctionNode()) ? getScopeProtoDepth(getCurrentBlock(), symbol) : -1); + method.load(isFastScope(symbol) ? getScopeProtoDepth(getCurrentBlock(), symbol) : -1); final SharedScopeCall scopeCall = getScopeGet(valueType, symbol, flags | CALLSITE_FAST_SCOPE); scopeCall.generateInvoke(method); return method; @@ -240,30 +269,18 @@ final class CodeGenerator extends NodeOperatorVisitor { return method; } - private static int getScopeProtoDepth(final Block currentBlock, final Symbol symbol) { - if (currentBlock == symbol.getBlock()) { - return 0; - } - - final int delta = currentBlock.needsScope() ? 1 : 0; - final Block parentBlock = currentBlock.getParent(); - - if (parentBlock != null) { - final int result = getScopeProtoDepth(parentBlock, symbol); - if (result != -1) { - return delta + result; + private int getScopeProtoDepth(final Block startingBlock, final Symbol symbol) { + int depth = 0; + final Block definingBlock = symbol.getBlock(); + for(final Iterator blocks = lexicalContext.getBlocks(startingBlock); blocks.hasNext();) { + final Block currentBlock = blocks.next(); + if (currentBlock == definingBlock) { + return depth; + } + if (currentBlock.needsScope()) { + ++depth; } } - - if (currentBlock instanceof FunctionNode) { - for (final Block lookupBlock : ((FunctionNode)currentBlock).getReferencingParentBlocks()) { - final int result = getScopeProtoDepth(lookupBlock, symbol); - if (result != -1) { - return delta + result; - } - } - } - return -1; } @@ -313,13 +330,13 @@ final class CodeGenerator extends NodeOperatorVisitor { node.accept(new NodeVisitor(getCurrentCompileUnit(), method) { @Override - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { loadIdent(identNode); return null; } @Override - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { if (!baseAlreadyOnStack) { load(accessNode.getBase()).convert(Type.OBJECT); } @@ -329,7 +346,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final IndexNode indexNode) { + public Node enterIndexNode(final IndexNode indexNode) { if (!baseAlreadyOnStack) { load(indexNode.getBase()).convert(Type.OBJECT); load(indexNode.getIndex()); @@ -338,6 +355,14 @@ final class CodeGenerator extends NodeOperatorVisitor { return null; } + @Override + public Node enterFunctionNode(FunctionNode functionNode) { + // function nodes will always leave a constructed function object on stack, no need to load the symbol + // separately as in enterDefault() + functionNode.accept(codegen); + return null; + } + @Override public Node enterDefault(final Node otherNode) { otherNode.accept(codegen); // generate code for whatever we are looking at. @@ -350,7 +375,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { if (accessNode.testResolved()) { return null; } @@ -422,10 +447,11 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { if (block.testResolved()) { return null; } + lexicalContext.push(block); method.label(block.getEntryLabel()); initLocals(block); @@ -434,14 +460,14 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node leave(final Block block) { + public Node leaveBlock(final Block block) { method.label(block.getBreakLabel()); symbolInfo(block); if (block.needsScope()) { popBlockScope(block); } - + lexicalContext.pop(block); return block; } @@ -467,7 +493,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { if (breakNode.testResolved()) { return null; } @@ -515,14 +541,13 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { if (callNode.testResolved()) { return null; } final List args = callNode.getArgs(); final Node function = callNode.getFunction(); - final FunctionNode currentFunction = getCurrentFunctionNode(); final Block currentBlock = getCurrentBlock(); function.accept(new NodeVisitor(getCurrentCompileUnit(), method) { @@ -531,7 +556,7 @@ final class CodeGenerator extends NodeOperatorVisitor { final Symbol symbol = identNode.getSymbol(); int scopeCallFlags = flags; method.loadScope(); - if (symbol.isFastScope(currentFunction)) { + if (isFastScope(symbol)) { method.load(getScopeProtoDepth(currentBlock, symbol)); scopeCallFlags |= CALLSITE_FAST_SCOPE; } else { @@ -593,7 +618,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final IdentNode node) { + public Node enterIdentNode(final IdentNode node) { final Symbol symbol = node.getSymbol(); if (symbol.isScope()) { @@ -606,7 +631,7 @@ final class CodeGenerator extends NodeOperatorVisitor { if (callNode.isEval()) { evalCall(node, flags); } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD - || (!symbol.isFastScope(currentFunction) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD) + || (!isFastScope(symbol) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD) || callNode.inWithBlock()) { scopeCall(node, flags); } else { @@ -621,7 +646,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final AccessNode node) { + public Node enterAccessNode(final AccessNode node) { load(node.getBase()); method.convert(Type.OBJECT); method.dup(); @@ -634,8 +659,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final ReferenceNode node) { - final FunctionNode callee = node.getReference(); + public Node enterFunctionNode(final FunctionNode callee) { final boolean isVarArg = callee.isVarArg(); final int argCount = isVarArg ? -1 : callee.getParameters().size(); @@ -653,12 +677,13 @@ final class CodeGenerator extends NodeOperatorVisitor { loadArgs(args, signature, isVarArg, argCount); method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature); assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType(); - + functionNodeIsCallee = true; + callee.accept(CodeGenerator.this); return null; } @Override - public Node enter(final IndexNode node) { + public Node enterIndexNode(final IndexNode node) { load(node.getBase()); method.convert(Type.OBJECT); method.dup(); @@ -694,7 +719,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { if (continueNode.testResolved()) { return null; } @@ -709,17 +734,17 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final DoWhileNode doWhileNode) { - return enter((WhileNode)doWhileNode); + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { + return enterWhileNode(doWhileNode); } @Override - public Node enter(final EmptyNode emptyNode) { + public Node enterEmptyNode(final EmptyNode emptyNode) { return null; } @Override - public Node enter(final ExecuteNode executeNode) { + public Node enterExecuteNode(final ExecuteNode executeNode) { if (executeNode.testResolved()) { return null; } @@ -731,7 +756,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { if (forNode.testResolved()) { return null; } @@ -813,7 +838,7 @@ final class CodeGenerator extends NodeOperatorVisitor { * @param block block with local vars. */ private void initLocals(final Block block) { - final FunctionNode function = block.getFunction(); + final FunctionNode function = lexicalContext.getFunction(block); final boolean isFunctionNode = block == function; /* @@ -915,7 +940,7 @@ final class CodeGenerator extends NodeOperatorVisitor { foc.makeObject(method); // runScript(): merge scope into global - if (isFunctionNode && function.isScript()) { + if (isFunctionNode && function.isProgram()) { method.invoke(ScriptRuntime.MERGE_SCOPE); } @@ -958,19 +983,29 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final FunctionNode functionNode) { - if (functionNode.isLazy()) { - return null; - } + public Node enterFunctionNode(final FunctionNode functionNode) { + final boolean isCallee = functionNodeIsCallee; + functionNodeIsCallee = false; if (functionNode.testResolved()) { return null; } + if(!(isCallee || functionNode == compiler.getFunctionNode())) { + newFunctionObject(functionNode); + } + + if (functionNode.isLazy()) { + return null; + } + + LOG.info("=== BEGIN " + functionNode.getName()); + lexicalContext.push(functionNode); + setCurrentCompileUnit(functionNode.getCompileUnit()); assert getCurrentCompileUnit() != null; - method = getCurrentCompileUnit().getClassEmitter().method(functionNode); + setCurrentMethodEmitter(getCurrentCompileUnit().getClassEmitter().method(functionNode)); functionNode.setMethodEmitter(method); // Mark end for variable tables. method.begin(); @@ -983,7 +1018,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node leave(final FunctionNode functionNode) { + public Node leaveFunctionNode(final FunctionNode functionNode) { // Mark end for variable tables. method.label(functionNode.getBreakLabel()); @@ -1001,16 +1036,18 @@ final class CodeGenerator extends NodeOperatorVisitor { throw e; } + lexicalContext.pop(functionNode); + LOG.info("=== END " + functionNode.getName()); return functionNode; } @Override - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { return null; } @Override - public Node enter(final IfNode ifNode) { + public Node enterIfNode(final IfNode ifNode) { if (ifNode.testResolved()) { return null; } @@ -1049,7 +1086,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final IndexNode indexNode) { + public Node enterIndexNode(final IndexNode indexNode) { if (indexNode.testResolved()) { return null; } @@ -1060,7 +1097,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final LineNumberNode lineNumberNode) { + public Node enterLineNumberNode(final LineNumberNode lineNumberNode) { if (lineNumberNode.testResolved()) { return null; } @@ -1068,7 +1105,6 @@ final class CodeGenerator extends NodeOperatorVisitor { final Label label = new Label("line:" + lineNumberNode.getLineNumber() + " (" + getCurrentFunctionNode().getName() + ")"); method.label(label); method.lineNumber(lineNumberNode.getLineNumber(), label); - return null; } @@ -1106,7 +1142,7 @@ final class CodeGenerator extends NodeOperatorVisitor { final String name = getCurrentFunctionNode().uniqueName(SPLIT_PREFIX.tag()); final String signature = methodDescriptor(type, Object.class, ScriptFunction.class, ScriptObject.class, type); - method = getCurrentCompileUnit().getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature); + setCurrentMethodEmitter(getCurrentCompileUnit().getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature)); method.setFunctionNode(getCurrentFunctionNode()); method.begin(); @@ -1212,7 +1248,7 @@ final class CodeGenerator extends NodeOperatorVisitor { method.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class)); classEmitter.needGetConstantMethod(cls); } else { - method.loadConstants(unitClassName).load(index).arrayload(); + method.loadConstants().load(index).arrayload(); if (cls != Object.class) { method.checkcast(cls); } @@ -1292,14 +1328,14 @@ final class CodeGenerator extends NodeOperatorVisitor { @SuppressWarnings("rawtypes") @Override - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { assert literalNode.getSymbol() != null : literalNode + " has no symbol"; load(literalNode).store(literalNode.getSymbol()); return null; } @Override - public Node enter(final ObjectNode objectNode) { + public Node enterObjectNode(final ObjectNode objectNode) { if (objectNode.testResolved()) { return null; } @@ -1372,10 +1408,10 @@ final class CodeGenerator extends NodeOperatorVisitor { } for (final Node element : elements) { - final PropertyNode propertyNode = (PropertyNode)element; - final Object key = propertyNode.getKey(); - final ReferenceNode getter = (ReferenceNode)propertyNode.getGetter(); - final ReferenceNode setter = (ReferenceNode)propertyNode.getSetter(); + final PropertyNode propertyNode = (PropertyNode)element; + final Object key = propertyNode.getKey(); + final FunctionNode getter = (FunctionNode)propertyNode.getGetter(); + final FunctionNode setter = (FunctionNode)propertyNode.getSetter(); if (getter == null && setter == null) { continue; @@ -1404,18 +1440,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final ReferenceNode referenceNode) { - if (referenceNode.testResolved()) { - return null; - } - - newFunctionObject(referenceNode.getReference()); - - return null; - } - - @Override - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { if (returnNode.testResolved()) { return null; } @@ -1556,7 +1581,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final RuntimeNode runtimeNode) { + public Node enterRuntimeNode(final RuntimeNode runtimeNode) { if (runtimeNode.testResolved()) { return null; } @@ -1637,7 +1662,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { if (splitNode.testResolved()) { return null; } @@ -1706,7 +1731,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node leave(final SplitNode splitNode) { + public Node leaveSplitNode(final SplitNode splitNode) { try { // Wrap up this method. method.loadResult(); @@ -1763,7 +1788,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { if (switchNode.testResolved()) { return null; } @@ -1895,7 +1920,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final ThrowNode throwNode) { + public Node enterThrowNode(final ThrowNode throwNode) { if (throwNode.testResolved()) { return null; } @@ -1922,7 +1947,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final TryNode tryNode) { + public Node enterTryNode(final TryNode tryNode) { if (tryNode.testResolved()) { return null; } @@ -1955,7 +1980,7 @@ final class CodeGenerator extends NodeOperatorVisitor { setCurrentBlock(catchBlock); try { - enter(catchBlock); + enterBlock(catchBlock); final CatchNode catchNode = (CatchNode)catchBlocks.get(i).getStatements().get(0); final IdentNode exception = catchNode.getException(); @@ -1966,6 +1991,7 @@ final class CodeGenerator extends NodeOperatorVisitor { // Generate catch body (inlined finally) and rethrow exception catchBody.accept(this); method.load(symbol).athrow(); + lexicalContext.pop(catchBlock); continue; } @@ -2012,7 +2038,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } } - leave(catchBlock); + leaveBlock(catchBlock); } finally { setCurrentBlock(saveBlock); } @@ -2027,7 +2053,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final VarNode varNode) { + public Node enterVarNode(final VarNode varNode) { final Node init = varNode.getInit(); if (varNode.testResolved() || init == null) { @@ -2049,7 +2075,7 @@ final class CodeGenerator extends NodeOperatorVisitor { int flags = CALLSITE_SCOPE | getCallSiteFlags(); final IdentNode identNode = varNode.getName(); final Type type = identNode.getType(); - if (varSymbol.isFastScope(getCurrentFunctionNode())) { + if (isFastScope(varSymbol)) { storeFastScopeVar(type, varSymbol, flags); } else { method.dynamicSet(type, identNode.getName(), flags); @@ -2065,7 +2091,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { if (whileNode.testResolved()) { return null; } @@ -2098,7 +2124,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final WithNode withNode) { + public Node enterWithNode(final WithNode withNode) { if (withNode.testResolved()) { return null; } @@ -2864,7 +2890,7 @@ final class CodeGenerator extends NodeOperatorVisitor { * Ternary visits. */ @Override - public Node enter(final TernaryNode ternaryNode) { + public Node enterTernaryNode(final TernaryNode ternaryNode) { if (ternaryNode.testResolved()) { return null; } @@ -3060,7 +3086,7 @@ final class CodeGenerator extends NodeOperatorVisitor { target.accept(new NodeVisitor(getCurrentCompileUnit(), method) { @Override - public Node enter(final IdentNode node) { + public Node enterIdentNode(final IdentNode node) { if (targetSymbol.isScope()) { method.load(scopeSymbol); depth++; @@ -3083,13 +3109,13 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final AccessNode node) { + public Node enterAccessNode(final AccessNode node) { enterBaseNode(); return null; } @Override - public Node enter(final IndexNode node) { + public Node enterIndexNode(final IndexNode node) { enterBaseNode(); final Node index = node.getIndex(); @@ -3155,8 +3181,6 @@ final class CodeGenerator extends NodeOperatorVisitor { } private void epilogue() { - final FunctionNode currentFunction = getCurrentFunctionNode(); - /** * Take the original target args from the stack and use them * together with the value to be stored to emit the store code @@ -3174,7 +3198,7 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final UnaryNode node) { + public Node enterUnaryNode(final UnaryNode node) { if(node.tokenType() == TokenType.CONVERT && node.getSymbol() != null) { method.convert(node.rhs().getType()); } @@ -3182,11 +3206,11 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final IdentNode node) { + public Node enterIdentNode(final IdentNode node) { final Symbol symbol = node.getSymbol(); assert symbol != null; if (symbol.isScope()) { - if (symbol.isFastScope(currentFunction)) { + if (isFastScope(symbol)) { storeFastScopeVar(node.getType(), symbol, CALLSITE_SCOPE | getCallSiteFlags()); } else { method.dynamicSet(node.getType(), node.getName(), CALLSITE_SCOPE | getCallSiteFlags()); @@ -3199,13 +3223,13 @@ final class CodeGenerator extends NodeOperatorVisitor { } @Override - public Node enter(final AccessNode node) { + public Node enterAccessNode(final AccessNode node) { method.dynamicSet(node.getProperty().getType(), node.getProperty().getName(), getCallSiteFlags()); return null; } @Override - public Node enter(final IndexNode node) { + public Node enterIndexNode(final IndexNode node) { method.dynamicSetIndex(getCallSiteFlags()); return null; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java index 0125efff65e..8b905f87e1d 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java @@ -14,16 +14,16 @@ import java.io.IOException; import java.util.EnumSet; import java.util.HashSet; import java.util.Set; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ReferenceNode; -import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.debug.PrintVisitor; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.ECMAErrors; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.Timing; @@ -65,17 +65,17 @@ enum CompilationPhase { outermostFunctionNode.accept(new NodeVisitor() { // self references are done with invokestatic and thus cannot have trampolines - never lazy @Override - public Node enter(final CallNode node) { + public Node enterCallNode(final CallNode node) { final Node callee = node.getFunction(); - if (callee instanceof ReferenceNode) { - neverLazy.add(((ReferenceNode)callee).getReference()); + if (callee instanceof FunctionNode) { + neverLazy.add(((FunctionNode)callee)); return null; } return node; } @Override - public Node enter(final FunctionNode node) { + public Node enterFunctionNode(final FunctionNode node) { if (node == outermostFunctionNode) { return node; } @@ -94,15 +94,24 @@ enum CompilationPhase { lazy.remove(node); } - for (final FunctionNode node : lazy) { - Compiler.LOG.fine("Marking " + node.getName() + " as lazy"); - node.setIsLazy(true); - final FunctionNode parent = node.findParentFunction(); - if (parent != null) { - Compiler.LOG.fine("Marking " + parent.getName() + " as having lazy children - it needs scope for all variables"); - parent.setHasLazyChildren(); + outermostFunctionNode.accept(new NodeOperatorVisitor() { + private final LexicalContext lexicalContext = new LexicalContext(); + @Override + public Node enterFunctionNode(FunctionNode functionNode) { + lexicalContext.push(functionNode); + if(lazy.contains(functionNode)) { + Compiler.LOG.fine("Marking " + functionNode.getName() + " as lazy"); + functionNode.setIsLazy(true); + lexicalContext.getParentFunction(functionNode).setHasLazyChildren(); + } + return functionNode; } - } + @Override + public Node leaveFunctionNode(FunctionNode functionNode) { + lexicalContext.pop(functionNode); + return functionNode; + } + }); } @Override @@ -241,6 +250,16 @@ enum CompilationPhase { final CodeGenerator codegen = new CodeGenerator(compiler); fn.accept(codegen); codegen.generateScopeCalls(); + fn.accept(new NodeOperatorVisitor() { + @Override + public Node enterFunctionNode(FunctionNode functionNode) { + if(functionNode.isLazy()) { + functionNode.resetResolved(); + return null; + } + return fn; + } + }); } catch (final VerifyError e) { if (env._verify_code || env._print_code) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index 87d26c1aab5..397f39a54b0 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -46,7 +46,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; 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; @@ -383,7 +382,7 @@ public final class Compiler { functionNode.accept(new NodeVisitor() { @Override - public Node enter(final FunctionNode node) { + public Node enterFunctionNode(final FunctionNode node) { if (node.isLazy()) { return null; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java index b302d6fe470..cd18524021d 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java @@ -34,20 +34,20 @@ import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CallNode.EvalArgs; -import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.DoWhileNode; import jdk.nashorn.internal.ir.ExecuteNode; 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.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; @@ -85,11 +85,13 @@ final class FinalizeTypes extends NodeOperatorVisitor { private static final DebugLogger LOG = new DebugLogger("finalize"); + private final LexicalContext lexicalContext = new LexicalContext(); + FinalizeTypes() { } @Override - public Node leave(final CallNode callNode) { + public Node leaveCallNode(final CallNode callNode) { final EvalArgs evalArgs = callNode.getEvalArgs(); if (evalArgs != null) { evalArgs.setCode(evalArgs.getCode().accept(this)); @@ -97,15 +99,14 @@ final class FinalizeTypes extends NodeOperatorVisitor { // AccessSpecializer - call return type may change the access for this location final Node function = callNode.getFunction(); - if (function instanceof ReferenceNode) { - setTypeOverride(callNode, ((ReferenceNode)function).getReference().getType()); + if (function instanceof FunctionNode) { + return setTypeOverride(callNode, ((FunctionNode)function).getReturnType()); } return callNode; } private Node leaveUnary(final UnaryNode unaryNode) { - unaryNode.setRHS(convert(unaryNode.rhs(), unaryNode.getType())); - return unaryNode; + return unaryNode.setRHS(convert(unaryNode.rhs(), unaryNode.getType())); } @Override @@ -126,8 +127,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveDECINC(final UnaryNode unaryNode) { - specialize(unaryNode); - return unaryNode; + return specialize(unaryNode).node; } @Override @@ -159,9 +159,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } } - binaryNode.setLHS(convert(lhs, type)); - binaryNode.setRHS(convert(rhs, type)); - return binaryNode; + return binaryNode.setLHS(convert(lhs, type)).setRHS(convert(rhs, type)); } @Override @@ -171,12 +169,13 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveASSIGN(final BinaryNode binaryNode) { - Type destType = specialize(binaryNode); + final SpecializedNode specialized = specialize(binaryNode); + final BinaryNode specBinaryNode = (BinaryNode)specialized.node; + Type destType = specialized.type; if (destType == null) { - destType = binaryNode.getType(); + destType = specBinaryNode.getType(); } - binaryNode.setRHS(convert(binaryNode.rhs(), destType)); - return binaryNode; + return specBinaryNode.setRHS(convert(specBinaryNode.rhs(), destType)); } @Override @@ -255,21 +254,21 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveCOMMALEFT(final BinaryNode binaryNode) { assert binaryNode.getSymbol() != null; - binaryNode.setRHS(discard(binaryNode.rhs())); + final BinaryNode newBinaryNode = (BinaryNode)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 - propagateType(binaryNode, binaryNode.lhs().getType()); - return binaryNode; + propagateType(newBinaryNode, newBinaryNode.lhs().getType()); + return newBinaryNode; } @Override public Node leaveCOMMARIGHT(final BinaryNode binaryNode) { assert binaryNode.getSymbol() != null; - binaryNode.setLHS(discard(binaryNode.lhs())); + 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 - propagateType(binaryNode, binaryNode.rhs().getType()); - return binaryNode; + propagateType(newBinaryNode, newBinaryNode.rhs().getType()); + return newBinaryNode; } @Override @@ -355,13 +354,20 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { + lexicalContext.push(block); updateSymbols(block); return block; } @Override - public Node leave(final CatchNode catchNode) { + public Node leaveBlock(Block block) { + lexicalContext.pop(block); + return super.leaveBlock(block); + } + + @Override + public Node leaveCatchNode(final CatchNode catchNode) { final Node exceptionCondition = catchNode.getExceptionCondition(); if (exceptionCondition != null) { catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN)); @@ -370,23 +376,23 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node enter(final DoWhileNode doWhileNode) { - return enter((WhileNode)doWhileNode); + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { + return enterWhileNode(doWhileNode); } @Override - public Node leave(final DoWhileNode doWhileNode) { - return leave((WhileNode)doWhileNode); + public Node leaveDoWhileNode(final DoWhileNode doWhileNode) { + return leaveWhileNode(doWhileNode); } @Override - public Node leave(final ExecuteNode executeNode) { + public Node leaveExecuteNode(final ExecuteNode executeNode) { executeNode.setExpression(discard(executeNode.getExpression())); return executeNode; } @Override - public Node leave(final ForNode forNode) { + public Node leaveForNode(final ForNode forNode) { final Node init = forNode.getInit(); final Node test = forNode.getTest(); final Node modify = forNode.getModify(); @@ -414,11 +420,12 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { if (functionNode.isLazy()) { return null; } + lexicalContext.push(functionNode); // If the function doesn't need a callee, we ensure its __callee__ symbol doesn't get a slot. We can't do // this earlier, as access to scoped variables, self symbol, etc. in previous phases can all trigger the // need for the callee. @@ -439,14 +446,20 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final IfNode ifNode) { + public Node leaveFunctionNode(FunctionNode functionNode) { + lexicalContext.pop(functionNode); + return super.leaveFunctionNode(functionNode); + } + + @Override + public Node leaveIfNode(final IfNode ifNode) { ifNode.setTest(convert(ifNode.getTest(), Type.BOOLEAN)); return ifNode; } @SuppressWarnings("rawtypes") @Override - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; final Node[] array = arrayLiteralNode.getValue(); @@ -464,7 +477,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final ReturnNode returnNode) { + public Node leaveReturnNode(final ReturnNode returnNode) { final Node expr = returnNode.getExpression(); if (expr != null) { returnNode.setExpression(convert(expr, getCurrentFunctionNode().getReturnType())); @@ -473,7 +486,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final RuntimeNode runtimeNode) { + public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { final List args = runtimeNode.getArgs(); for (final Node arg : args) { assert !arg.getType().isUnknown(); @@ -482,7 +495,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final SwitchNode switchNode) { + public Node leaveSwitchNode(final SwitchNode switchNode) { final Node expression = switchNode.getExpression(); final List cases = switchNode.getCases(); final boolean allInteger = switchNode.getTag().getSymbolType().isInteger(); @@ -501,33 +514,34 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final TernaryNode ternaryNode) { - ternaryNode.setLHS(convert(ternaryNode.lhs(), Type.BOOLEAN)); - return ternaryNode; + public Node leaveTernaryNode(final TernaryNode ternaryNode) { + return ternaryNode.setLHS(convert(ternaryNode.lhs(), Type.BOOLEAN)); } @Override - public Node leave(final ThrowNode throwNode) { + public Node leaveThrowNode(final ThrowNode throwNode) { throwNode.setExpression(convert(throwNode.getExpression(), Type.OBJECT)); return throwNode; } @Override - public Node leave(final VarNode varNode) { + public Node leaveVarNode(final VarNode varNode) { final Node rhs = varNode.getInit(); if (rhs != null) { - Type destType = specialize(varNode); + final SpecializedNode specialized = specialize(varNode); + final VarNode specVarNode = (VarNode)specialized.node; + Type destType = specialized.type; if (destType == null) { - destType = varNode.getType(); + destType = specVarNode.getType(); } - assert varNode.hasType() : varNode + " doesn't have a type"; - varNode.setInit(convert(rhs, destType)); + assert specVarNode.hasType() : specVarNode + " doesn't have a type"; + return specVarNode.setInit(convert(rhs, destType)); } return varNode; } @Override - public Node leave(final WhileNode whileNode) { + public Node leaveWhileNode(final WhileNode whileNode) { final Node test = whileNode.getTest(); if (test != null) { whileNode.setTest(convert(test, Type.BOOLEAN)); @@ -536,7 +550,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leave(final WithNode withNode) { + public Node leaveWithNode(final WithNode withNode) { withNode.setExpression(convert(withNode.getExpression(), Type.OBJECT)); return withNode; } @@ -555,14 +569,14 @@ final class FinalizeTypes extends NodeOperatorVisitor { * that scope and slot information is correct for every symbol * @param block block for which to to finalize type info. */ - private static void updateSymbols(final Block block) { + private void updateSymbols(final Block block) { if (!block.needsScope()) { return; // nothing to do } - assert !(block instanceof FunctionNode) || block.getFunction() == block; + final FunctionNode functionNode = lexicalContext.getFunction(block); + assert !(block instanceof FunctionNode) || functionNode == block; - final FunctionNode functionNode = block.getFunction(); final List symbols = block.getFrame().getSymbols(); final boolean allVarsInScope = functionNode.allVarsInScope(); final boolean isVarArg = functionNode.isVarArg(); @@ -631,10 +645,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { break; } - binaryNode.setLHS(convert(lhs, widest)); - binaryNode.setRHS(convert(rhs, widest)); - - return binaryNode; + return binaryNode.setLHS(convert(lhs, widest)).setRHS(convert(rhs, widest)); } /** @@ -656,9 +667,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } private Node leaveBinary(final BinaryNode binaryNode, final Type lhsType, final Type rhsType) { - binaryNode.setLHS(convert(binaryNode.lhs(), lhsType)); - binaryNode.setRHS(convert(binaryNode.rhs(), rhsType)); - return binaryNode; + return binaryNode.setLHS(convert(binaryNode.lhs(), lhsType)).setRHS(convert(binaryNode.rhs(), rhsType)); } /** @@ -679,7 +688,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { if (!exclude.contains(identNode)) { setCanBePrimitive(identNode.getSymbol()); } @@ -687,26 +696,36 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { setCanBePrimitive(accessNode.getProperty().getSymbol()); return null; } @Override - public Node enter(final IndexNode indexNode) { + public Node 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 indexNode; } }); } - private static Type specialize(final Assignment assignment) { + private static class SpecializedNode { + final Node node; + final Type type; + + SpecializedNode(Node node, Type type) { + this.node = node; + this.type = type; + } + } + + private static SpecializedNode specialize(final Assignment assignment) { final Node node = ((Node)assignment); - final Node lhs = assignment.getAssignmentDest(); + final T lhs = assignment.getAssignmentDest(); final Node rhs = assignment.getAssignmentSource(); if (!canHaveCallSiteType(lhs)) { - return null; + return new SpecializedNode(node, null); } final Type to; @@ -718,13 +737,13 @@ final class FinalizeTypes extends NodeOperatorVisitor { if (!isSupportedCallSiteType(to)) { //meaningless to specialize to boolean or object - return null; + return new SpecializedNode(node, null); } - setTypeOverride(lhs, to); - propagateType(node, to); + final Node newNode = assignment.setAssignmentDest(setTypeOverride(lhs, to)); + propagateType(newNode, to); - return to; + return new SpecializedNode(newNode, to); } @@ -736,7 +755,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { * @return true if node can have a callsite type */ private static boolean canHaveCallSiteType(final Node node) { - return node instanceof TypeOverride && ((TypeOverride)node).canHaveCallSiteType(); + return node instanceof TypeOverride && ((TypeOverride)node).canHaveCallSiteType(); } /** @@ -762,7 +781,8 @@ final class FinalizeTypes extends NodeOperatorVisitor { * @param node node for which to change type * @param to new type */ - private static void setTypeOverride(final Node node, final Type to) { + @SuppressWarnings("unchecked") + private static 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); @@ -771,7 +791,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { } } LOG.info("Type override for lhs in '" + node + "' => " + to); - ((TypeOverride)node).setType(to); + return ((TypeOverride)node).setType(to); } /** @@ -816,8 +836,8 @@ final class FinalizeTypes extends NodeOperatorVisitor { } } else { if (canHaveCallSiteType(node) && isSupportedCallSiteType(to)) { - setTypeOverride(node, to); - return resultNode; + assert node instanceof TypeOverride; + return setTypeOverride(node, to); } resultNode = new UnaryNode(node.getSource(), Token.recast(node.getToken(), TokenType.CONVERT), node); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java index af2b02ab706..fbc62644835 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java @@ -31,12 +31,12 @@ import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.TernaryNode; import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.JSType; @@ -54,7 +54,7 @@ final class FoldConstants extends NodeVisitor { } @Override - public Node leave(final UnaryNode unaryNode) { + public Node leaveUnaryNode(final UnaryNode unaryNode) { final LiteralNode literalNode = new UnaryNodeConstantEvaluator(unaryNode).eval(); if (literalNode != null) { LOG.info("Unary constant folded " + unaryNode + " to " + literalNode); @@ -64,7 +64,7 @@ final class FoldConstants extends NodeVisitor { } @Override - public Node leave(final BinaryNode binaryNode) { + public Node leaveBinaryNode(final BinaryNode binaryNode) { final LiteralNode literalNode = new BinaryNodeConstantEvaluator(binaryNode).eval(); if (literalNode != null) { LOG.info("Binary constant folded " + binaryNode + " to " + literalNode); @@ -74,7 +74,7 @@ final class FoldConstants extends NodeVisitor { } @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { if (functionNode.isLazy()) { return null; } @@ -82,13 +82,13 @@ final class FoldConstants extends NodeVisitor { } @Override - public Node leave(final FunctionNode functionNode) { + public Node leaveFunctionNode(final FunctionNode functionNode) { functionNode.setState(CompilationState.CONSTANT_FOLDED); return functionNode; } @Override - public Node leave(final IfNode ifNode) { + public Node leaveIfNode(final IfNode ifNode) { final Node test = ifNode.getTest(); if (test instanceof LiteralNode) { final Block shortCut = ((LiteralNode)test).isTrue() ? ifNode.getPass() : ifNode.getFail(); @@ -101,7 +101,7 @@ final class FoldConstants extends NodeVisitor { } @Override - public Node leave(final TernaryNode ternaryNode) { + public Node leaveTernaryNode(final TernaryNode ternaryNode) { final Node test = ternaryNode.lhs(); if (test instanceof LiteralNode) { return ((LiteralNode)test).isTrue() ? ternaryNode.rhs() : ternaryNode.third(); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java index 5f3740a7240..057d2d4e454 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java @@ -155,7 +155,7 @@ public final class FunctionSignature { true, functionNode.needsCallee(), functionNode.getReturnType(), - (functionNode.isVarArg() && !functionNode.isScript()) ? + (functionNode.isVarArg() && !functionNode.isProgram()) ? null : functionNode.getParameters()); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index 5baa7af535e..715ddc6f4e7 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -37,8 +37,8 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; +import java.util.Iterator; import java.util.List; -import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; @@ -52,11 +52,12 @@ import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; 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.LabelNode; import jdk.nashorn.internal.ir.LabeledNode; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LineNumberNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; @@ -69,7 +70,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.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Token; @@ -103,6 +103,8 @@ final class Lower extends NodeOperatorVisitor { private List statements; + private LexicalContext lexicalContext = new LexicalContext(); + /** * Constructor. * @@ -114,14 +116,15 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { final Node savedLastStatement = lastStatement; final List savedStatements = statements; - + lexicalContext.push(block); try { this.statements = new ArrayList<>(); + NodeVisitor visitor = this; for (final Node statement : block.getStatements()) { - statement.accept(this); + statement.accept(visitor); /* * This is slightly unsound, for example if we have a loop with * a guarded statement like if (x) continue in the body and the @@ -133,7 +136,7 @@ final class Lower extends NodeOperatorVisitor { */ if (lastStatement != null && lastStatement.isTerminal()) { copyTerminal(block, lastStatement); - break; + visitor = new DeadCodeVarDeclarationVisitor(); } } block.setStatements(statements); @@ -141,18 +144,19 @@ final class Lower extends NodeOperatorVisitor { } finally { this.statements = savedStatements; this.lastStatement = savedLastStatement; + lexicalContext.pop(block); } return null; } @Override - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { return enterBreakOrContinue(breakNode); } @Override - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { final Node function = markerFunction(callNode.getFunction()); callNode.setFunction(function); checkEval(callNode); //check if this is an eval call and store the information @@ -160,44 +164,44 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final CaseNode caseNode) { + public Node leaveCaseNode(final CaseNode caseNode) { caseNode.copyTerminalFlags(caseNode.getBody()); return caseNode; } @Override - public Node leave(final CatchNode catchNode) { + public Node leaveCatchNode(final CatchNode catchNode) { catchNode.copyTerminalFlags(catchNode.getBody()); addStatement(catchNode); return catchNode; } @Override - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { return enterBreakOrContinue(continueNode); } @Override - public Node enter(final DoWhileNode doWhileNode) { - return enter((WhileNode)doWhileNode); + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { + return enterWhileNode(doWhileNode); } @Override - public Node leave(final DoWhileNode doWhileNode) { - return leave((WhileNode)doWhileNode); + public Node leaveDoWhileNode(final DoWhileNode doWhileNode) { + return leaveWhileNode(doWhileNode); } @Override - public Node enter(final EmptyNode emptyNode) { + public Node enterEmptyNode(final EmptyNode emptyNode) { return null; } @Override - public Node leave(final ExecuteNode executeNode) { + public Node leaveExecuteNode(final ExecuteNode executeNode) { final Node expr = executeNode.getExpression(); - if (getCurrentFunctionNode().isScript()) { - if (!(expr instanceof Block)) { + if (getCurrentFunctionNode().isProgram()) { + if (!(expr instanceof Block) || expr instanceof FunctionNode) { // it's not a block, but can be a function if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) { executeNode.setExpression(new BinaryNode(executeNode.getSource(), Token.recast(executeNode.getToken(), TokenType.ASSIGN), getCurrentFunctionNode().getResultNode(), @@ -213,13 +217,13 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { nest(forNode); return forNode; } @Override - public Node leave(final ForNode forNode) { + public Node leaveForNode(final ForNode forNode) { final Node test = forNode.getTest(); final Block body = forNode.getBody(); @@ -247,18 +251,16 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { LOG.info("START FunctionNode: " + functionNode.getName()); if (functionNode.isLazy()) { LOG.info("LAZY: " + functionNode.getName()); return null; } - + lexicalContext.push(functionNode); initFunctionNode(functionNode); - Node initialEvalResult = LiteralNode.newInstance(functionNode, ScriptRuntime.UNDEFINED); - nest(functionNode); /* @@ -272,60 +274,40 @@ final class Lower extends NodeOperatorVisitor { statements = new ArrayList<>(); lastStatement = null; - // for initial eval result is the last declared function - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { - final IdentNode ident = nestedFunction.getIdent(); - if (ident != null && nestedFunction.isStatement()) { - initialEvalResult = new IdentNode(ident); - } - } - if (functionNode.needsSelfSymbol()) { //function needs to start with var funcIdent = __callee_; statements.add(functionNode.getSelfSymbolInit().accept(this)); } + NodeVisitor visitor = this; try { - // Every nested function needs a definition in the outer function with its name. Add these. - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { - final VarNode varNode = nestedFunction.getFunctionVarNode(); - if (varNode != null) { - final LineNumberNode lineNumberNode = nestedFunction.getFunctionVarLineNumberNode(); - if (lineNumberNode != null) { - lineNumberNode.accept(this); - } - varNode.accept(this); - varNode.setIsFunctionVarNode(); - } - } - - if (functionNode.isScript()) { - new ExecuteNode(functionNode.getSource(), functionNode.getFirstToken(), functionNode.getFinish(), initialEvalResult).accept(this); - } - //do the statements - this fills the block with code + boolean needsInitialEvalResult = functionNode.isProgram(); for (final Node statement : functionNode.getStatements()) { - statement.accept(this); + // If this function is a program, then insert an assignment to the initial eval result after all + // function declarations. + if(needsInitialEvalResult && !(statement instanceof LineNumberNode || (statement instanceof VarNode && ((VarNode)statement).isFunctionDeclaration()))) { + addInitialEvalResult(functionNode); + needsInitialEvalResult = false; + } + statement.accept(visitor); //If there are unused terminated endpoints in the function, we need // to add a "return undefined" in those places for correct semantics LOG.info("Checking lastStatement="+lastStatement+" for terminal flags"); if (lastStatement != null && lastStatement.hasTerminalFlags()) { copyTerminal(functionNode, lastStatement); - break; + assert !needsInitialEvalResult; + visitor = new DeadCodeVarDeclarationVisitor(); } } - + if(needsInitialEvalResult) { + addInitialEvalResult(functionNode); + } functionNode.setStatements(statements); if (!functionNode.isTerminal()) { guaranteeReturn(functionNode); } - - //lower all nested functions - for (final FunctionNode nestedFunction : functionNode.getFunctions()) { - nestedFunction.accept(this); - } - } finally { statements = savedStatements; lastStatement = savedLastStatement; @@ -333,19 +315,67 @@ final class Lower extends NodeOperatorVisitor { LOG.info("END FunctionNode: " + functionNode.getName()); unnest(functionNode); + lexicalContext.pop(functionNode); functionNode.setState(CompilationState.LOWERED); return null; } + /** + * This visitor is used to go over statements after a terminal statement. Those statements are dead code, but the + * var declarations in them still have the effect of declaring a local variable on the function level. Therefore, + * they aren't really dead code and must be preserved. Note that they're only preserved as no-op declarations; their + * initializers are wiped out as those are, in fact, dead code. + */ + private class DeadCodeVarDeclarationVisitor extends NodeOperatorVisitor { + DeadCodeVarDeclarationVisitor() { + } + + @Override + public Node enterVarNode(VarNode varNode) { + // Can't ever see a function declaration, as this visitor is only ever used after a terminal statement was + // encountered, and all function declarations precede any terminal statements. + assert !varNode.isFunctionDeclaration(); + if(varNode.getInit() == null) { + // No initializer, just pass it to Lower. + return varNode.accept(Lower.this); + } + // Wipe out the initializer and then pass it to Lower. + return varNode.setInit(null).accept(Lower.this); + } + } + + private void addInitialEvalResult(final FunctionNode functionNode) { + new ExecuteNode(functionNode.getSource(), functionNode.getFirstToken(), functionNode.getFinish(), + getInitialEvalResult(functionNode)).accept(this); + } + + /** + * Result of initial result of evaluating a particular program, which is either the last function it declares, or + * undefined if it doesn't declare any functions. + * @param program + * @return the initial result of evaluating the program + */ + private static Node getInitialEvalResult(final FunctionNode program) { + IdentNode lastFnName = null; + for (final FunctionNode fn : program.getDeclaredFunctions()) { + assert fn.isDeclared(); + final IdentNode fnName = fn.getIdent(); + if(fnName != null) { + lastFnName = fnName; + } + } + return lastFnName != null ? new IdentNode(lastFnName) : LiteralNode.newInstance(program, ScriptRuntime.UNDEFINED); + } + @Override - public Node enter(final IfNode ifNode) { + public Node enterIfNode(final IfNode ifNode) { return nest(ifNode); } @Override - public Node leave(final IfNode ifNode) { + public Node leaveIfNode(final IfNode ifNode) { final Node pass = ifNode.getPass(); final Node fail = ifNode.getFail(); @@ -360,7 +390,7 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node enter(LabelNode labelNode) { + public Node enterLabelNode(LabelNode labelNode) { final Block body = labelNode.getBody(); body.accept(this); copyTerminal(labelNode, body); @@ -369,13 +399,13 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node enter(final LineNumberNode lineNumberNode) { + public Node enterLineNumberNode(final LineNumberNode lineNumberNode) { addStatement(lineNumberNode, false); // don't put it in lastStatement cache return null; } @Override - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { final TryNode tryNode = returnNode.getTryChain(); final Node expr = returnNode.getExpression(); @@ -413,19 +443,19 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final ReturnNode returnNode) { + public Node leaveReturnNode(final ReturnNode returnNode) { addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor return returnNode; } @Override - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { nest(switchNode); return switchNode; } @Override - public Node leave(final SwitchNode switchNode) { + public Node leaveSwitchNode(final SwitchNode switchNode) { unnest(switchNode); final List cases = switchNode.getCases(); @@ -446,13 +476,13 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final ThrowNode throwNode) { + public Node leaveThrowNode(final ThrowNode throwNode) { addStatement(throwNode); //ThrowNodes are always terminal, marked as such in constructor return throwNode; } @Override - public Node enter(final TryNode tryNode) { + public Node enterTryNode(final TryNode tryNode) { final Block finallyBody = tryNode.getFinallyBody(); final long token = tryNode.getToken(); final int finish = tryNode.getFinish(); @@ -538,26 +568,19 @@ final class Lower extends NodeOperatorVisitor { // set outer tryNode's body to innerTryNode final Block outerBody; - outerBody = new Block(source, token, finish, tryNode.getBody().getParent(), getCurrentFunctionNode()); + outerBody = new Block(source, token, finish); outerBody.setStatements(new ArrayList(Arrays.asList(innerTryNode))); tryNode.setBody(outerBody); tryNode.setCatchBlocks(null); - - // now before we go on, we have to fix the block parents - // (we repair the block tree after the insertion so that all references are intact) - innerTryNode.getBody().setParent(tryNode.getBody()); - for (final Block block : innerTryNode.getCatchBlocks()) { - block.setParent(tryNode.getBody()); - } } // create a catch-all that inlines finally and rethrows - final Block catchBlock = new Block(source, token, finish, getCurrentBlock(), getCurrentFunctionNode()); + final Block catchBlock = new Block(source, token, finish); //this catch block should get define symbol - final Block catchBody = new Block(source, token, finish, catchBlock, getCurrentFunctionNode()); - final Node catchAllFinally = finallyBody.clone(); + final Block catchBody = new Block(source, token, finish); + final Node catchAllFinally = finallyBody.copy(); catchBody.addStatement(new ExecuteNode(source, finallyBody.getToken(), finallyBody.getFinish(), catchAllFinally)); setTerminal(catchBody, true); @@ -584,7 +607,7 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final TryNode tryNode) { + public Node leaveTryNode(final TryNode tryNode) { final Block finallyBody = tryNode.getFinallyBody(); boolean allTerminal = tryNode.getBody().isTerminal() && (finallyBody == null || finallyBody.isTerminal()); @@ -608,18 +631,18 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final VarNode varNode) { + public Node leaveVarNode(final VarNode varNode) { addStatement(varNode); return varNode; } @Override - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { return nest(whileNode); } @Override - public Node leave(final WhileNode whileNode) { + public Node leaveWhileNode(final WhileNode whileNode) { final Node test = whileNode.getTest(); if (test == null) { @@ -653,7 +676,7 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leave(final WithNode withNode) { + public Node leaveWithNode(final WithNode withNode) { if (withNode.getBody().isTerminal()) { setTerminal(withNode, true); } @@ -682,28 +705,10 @@ final class Lower extends NodeOperatorVisitor { */ private static Node markerFunction(final Node function) { if (function instanceof IdentNode) { - return new IdentNode((IdentNode)function) { - @Override - public boolean isFunction() { - return true; - } - }; - } else if (function instanceof AccessNode) { - return new AccessNode((AccessNode)function) { - @Override - public boolean isFunction() { - return true; - } - }; - } else if (function instanceof IndexNode) { - return new IndexNode((IndexNode)function) { - @Override - public boolean isFunction() { - return true; - } - }; + return ((IdentNode)function).setIsFunction(); + } else if (function instanceof BaseNode) { + return ((BaseNode)function).setIsFunction(); } - return function; } @@ -746,7 +751,7 @@ final class Lower extends NodeOperatorVisitor { if (args.size() >= 1 && EVAL.tag().equals(callee.getName())) { final CallNode.EvalArgs evalArgs = new CallNode.EvalArgs( - args.get(0).clone().accept(this), //clone as we use this for the "is eval case". original evaluated separately for "is not eval case" + args.get(0).copy().accept(this), //clone as we use this for the "is eval case". original evaluated separately for "is not eval case" getCurrentFunctionNode().getThisNode(), evalLocation(callee), getCurrentFunctionNode().isStrictMode()); @@ -773,13 +778,13 @@ final class Lower extends NodeOperatorVisitor { loopBody.accept(new NodeVisitor() { @Override - public Node leave(final BreakNode node) { + public Node leaveBreakNode(final BreakNode node) { escapes.add(node); return node; } @Override - public Node leave(final ContinueNode node) { + public Node leaveContinueNode(final ContinueNode node) { // all inner loops have been popped. if (nesting.contains(node.getTargetNode())) { escapes.add(node); @@ -794,7 +799,7 @@ final class Lower extends NodeOperatorVisitor { private void guaranteeReturn(final FunctionNode functionNode) { Node resultNode; - if (functionNode.isScript()) { + if (functionNode.isProgram()) { resultNode = functionNode.getResultNode(); // the eval result, symbol assigned in Attr } else { if (lastStatement != null && lastStatement.isTerminal() || lastStatement instanceof ReturnNode) { @@ -859,18 +864,15 @@ final class Lower extends NodeOperatorVisitor { * @return true if try block is inside the target, false otherwise. */ private boolean isNestedTry(final TryNode tryNode, final Block target) { - for (Block current = getCurrentBlock(); current != target; current = current.getParent()) { - if (tryNode.getBody() == current) { + for(Iterator blocks = lexicalContext.getBlocks(getCurrentBlock()); blocks.hasNext();) { + final Block block = blocks.next(); + if(block == target) { + return false; + } + if(tryNode.isChildBlock(block)) { return true; } - - for (final Block catchBlock : tryNode.getCatchBlocks()) { - if (catchBlock == current) { - return true; - } - } } - return false; } @@ -899,7 +901,7 @@ final class Lower extends NodeOperatorVisitor { continue; } - finallyBody = (Block)finallyBody.clone(); + finallyBody = (Block)finallyBody.copy(); final boolean hasTerminalFlags = finallyBody.hasTerminalFlags(); new ExecuteNode(finallyBody.getSource(), finallyBody.getToken(), finallyBody.getFinish(), finallyBody).accept(this); @@ -974,6 +976,3 @@ final class Lower extends NodeOperatorVisitor { } } - - - diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java index 4cd0f5246b5..ae40ed33bee 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java @@ -651,11 +651,10 @@ public class MethodEmitter implements Emitter { /** * Load the constants array - * @param unitClassName name of the compile unit from which to load constants * @return this method emitter */ - MethodEmitter loadConstants(final String unitClassName) { - getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor()); + MethodEmitter loadConstants() { + getStatic(classEmitter.getUnitClassName(), CONSTANTS.tag(), CONSTANTS.descriptor()); assert peekType().isArray() : peekType(); return this; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java index b338ced5f47..f9a84f9181e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java @@ -41,6 +41,7 @@ import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.LabelNode; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; @@ -49,6 +50,7 @@ import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.SplitNode; import jdk.nashorn.internal.ir.SwitchNode; import jdk.nashorn.internal.ir.WhileNode; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.Source; @@ -70,6 +72,8 @@ final class Splitter extends NodeVisitor { /** Cache for calculated block weights. */ private final Map weightCache = new HashMap<>(); + private final LexicalContext lexicalContext = new LexicalContext(); + /** Weight threshold for when to start a split. */ public static final long SPLIT_THRESHOLD = Options.getIntProperty("nashorn.compiler.splitter.threshold", 32 * 1024); @@ -112,7 +116,7 @@ final class Splitter extends NodeVisitor { } if (weight >= SPLIT_THRESHOLD) { - weight = splitBlock(functionNode); + weight = splitBlock(functionNode, functionNode); } if (functionNode.isSplit()) { @@ -132,9 +136,20 @@ final class Splitter extends NodeVisitor { } // Recursively split nested functions - for (final FunctionNode function : functionNode.getFunctions()) { - new Splitter(compiler, function, outermostCompileUnit).split(); - } + functionNode.accept(new NodeOperatorVisitor() { + @Override + public Node enterFunctionNode(FunctionNode function) { + if(function == functionNode) { + // Don't process outermost function (it was already processed) but descend into it to find nested + // functions. + return function; + } + // Process a nested function + new Splitter(compiler, function, outermostCompileUnit).split(); + // Don't descend into a a nested function; Splitter.split() has taken care of nested-in-nested functions. + return null; + } + }); functionNode.setState(CompilationState.SPLIT); } @@ -155,7 +170,7 @@ final class Splitter extends NodeVisitor { * * @return new weight for the resulting block. */ - private long splitBlock(final Block block) { + private long splitBlock(final Block block, final FunctionNode function) { functionNode.setIsSplit(); final List splits = new ArrayList<>(); @@ -167,7 +182,7 @@ final class Splitter extends NodeVisitor { if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) { if (!statements.isEmpty()) { - splits.add(createBlockSplitNode(block, statements, statementsWeight)); + splits.add(createBlockSplitNode(block, function, statements, statementsWeight)); statements = new ArrayList<>(); statementsWeight = 0; } @@ -183,7 +198,7 @@ final class Splitter extends NodeVisitor { } if (!statements.isEmpty()) { - splits.add(createBlockSplitNode(block, statements, statementsWeight)); + splits.add(createBlockSplitNode(block, function, statements, statementsWeight)); } block.setStatements(splits); @@ -199,13 +214,13 @@ final class Splitter extends NodeVisitor { * * @return New split node. */ - private SplitNode createBlockSplitNode(final Block parent, final List statements, final long weight) { + private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List statements, final long weight) { final Source source = parent.getSource(); final long token = parent.getToken(); final int finish = parent.getFinish(); - final String name = parent.getFunction().uniqueName(SPLIT_PREFIX.tag()); + final String name = function.uniqueName(SPLIT_PREFIX.tag()); - final Block newBlock = new Block(source, token, finish, parent, functionNode); + final Block newBlock = new Block(source, token, finish); newBlock.setFrame(new Frame(parent.getFrame())); newBlock.setStatements(statements); @@ -217,15 +232,17 @@ final class Splitter extends NodeVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { if (block.isCatchBlock()) { return null; } + lexicalContext.push(block); final long weight = WeighNodes.weigh(block, weightCache); if (weight < SPLIT_THRESHOLD) { weightCache.put(block, weight); + lexicalContext.pop(block); return null; } @@ -233,23 +250,24 @@ final class Splitter extends NodeVisitor { } @Override - public Node leave(final Block block) { + public Node leaveBlock(final Block block) { assert !block.isCatchBlock(); // Block was heavier than SLIT_THRESHOLD in enter, but a sub-block may have // been split already, so weigh again before splitting. long weight = WeighNodes.weigh(block, weightCache); if (weight >= SPLIT_THRESHOLD) { - weight = splitBlock(block); + weight = splitBlock(block, lexicalContext.getFunction(block)); } weightCache.put(block, weight); + lexicalContext.pop(block); return block; } @SuppressWarnings("rawtypes") @Override - public Node leave(final LiteralNode literal) { + public Node leaveLiteralNode(final LiteralNode literal) { long weight = WeighNodes.weigh(literal); if (weight < SPLIT_THRESHOLD) { @@ -294,17 +312,12 @@ final class Splitter extends NodeVisitor { } @Override - public Node enter(final FunctionNode node) { - if (node.isLazy()) { - return null; + public Node enterFunctionNode(final FunctionNode node) { + if(node == functionNode && !node.isLazy()) { + lexicalContext.push(node); + node.visitStatements(this); + lexicalContext.pop(node); } - - final List statements = node.getStatements(); - - for (final Node statement : statements) { - statement.accept(this); - } - return null; } @@ -321,38 +334,38 @@ final class Splitter extends NodeVisitor { } @Override - public Node enter(final LabelNode labelNode) { + public Node enterLabelNode(final LabelNode labelNode) { registerJumpTarget(labelNode.getBreakNode()); registerJumpTarget(labelNode.getContinueNode()); return labelNode; } @Override - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { registerJumpTarget(whileNode); return whileNode; } @Override - public Node enter(final DoWhileNode doWhileNode) { + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { registerJumpTarget(doWhileNode); return doWhileNode; } @Override - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { registerJumpTarget(forNode); return forNode; } @Override - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { registerJumpTarget(switchNode); return switchNode; } @Override - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { for (final SplitNode split : splitStack) { split.setHasReturn(true); } @@ -360,25 +373,25 @@ final class Splitter extends NodeVisitor { } @Override - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { searchJumpTarget(continueNode.getTargetNode(), continueNode.getTargetLabel()); return continueNode; } @Override - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { searchJumpTarget(breakNode.getTargetNode(), breakNode.getTargetLabel()); return breakNode; } @Override - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { splitStack.addFirst(splitNode); return splitNode; } @Override - public Node leave(final SplitNode splitNode) { + public Node leaveSplitNode(final SplitNode splitNode) { assert splitNode == splitStack.peekFirst(); splitStack.removeFirst(); return splitNode; diff --git a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java index 9f2e8be44e0..18bd95527c4 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java @@ -47,7 +47,6 @@ import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.SplitNode; @@ -80,7 +79,7 @@ final class WeighNodes extends NodeOperatorVisitor { private static final long LITERAL_WEIGHT = 10; private static final long LOOP_WEIGHT = 4; private static final long NEW_WEIGHT = 6; - private static final long REFERENCE_WEIGHT = 20; + private static final long FUNC_EXPR_WEIGHT = 20; private static final long RETURN_WEIGHT = 2; private static final long SPLIT_WEIGHT = 40; private static final long SWITCH_WEIGHT = 8; @@ -94,36 +93,37 @@ final class WeighNodes extends NodeOperatorVisitor { /** Optional cache for weight of block nodes. */ private final Map weightCache; - /* + private final FunctionNode topFunction; + + /** * Constructor * * @param weightCache cache of already calculated block weights */ - private WeighNodes(final Map weightCache) { + private WeighNodes(FunctionNode topFunction, final Map weightCache) { super(null, null); + this.topFunction = topFunction; this.weightCache = weightCache; } static long weigh(final Node node) { - final WeighNodes weighNodes = new WeighNodes(null); - node.accept(weighNodes); - return weighNodes.weight; + return weigh(node, null); } static long weigh(final Node node, final Map weightCache) { - final WeighNodes weighNodes = new WeighNodes(weightCache); + final WeighNodes weighNodes = new WeighNodes(node instanceof FunctionNode ? (FunctionNode)node : null, weightCache); node.accept(weighNodes); return weighNodes.weight; } @Override - public Node leave(final AccessNode accessNode) { + public Node leaveAccessNode(final AccessNode accessNode) { weight += ACCESS_WEIGHT; return accessNode; } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { if (weightCache != null && weightCache.containsKey(block)) { weight += weightCache.get(block); return null; @@ -133,78 +133,79 @@ final class WeighNodes extends NodeOperatorVisitor { } @Override - public Node leave(final BreakNode breakNode) { + public Node leaveBreakNode(final BreakNode breakNode) { weight += BREAK_WEIGHT; return breakNode; } @Override - public Node leave(final CallNode callNode) { + public Node leaveCallNode(final CallNode callNode) { weight += CALL_WEIGHT; return callNode; } @Override - public Node leave(final CatchNode catchNode) { + public Node leaveCatchNode(final CatchNode catchNode) { weight += CATCH_WEIGHT; return catchNode; } @Override - public Node leave(final ContinueNode continueNode) { + public Node leaveContinueNode(final ContinueNode continueNode) { weight += CONTINUE_WEIGHT; return continueNode; } @Override - public Node leave(final DoWhileNode doWhileNode) { + public Node leaveDoWhileNode(final DoWhileNode doWhileNode) { weight += LOOP_WEIGHT; return doWhileNode; } @Override - public Node leave(final ExecuteNode executeNode) { + public Node leaveExecuteNode(final ExecuteNode executeNode) { return executeNode; } @Override - public Node leave(final ForNode forNode) { + public Node leaveForNode(final ForNode forNode) { weight += LOOP_WEIGHT; return forNode; } @Override - public Node enter(final FunctionNode functionNode) { - final List statements = functionNode.getStatements(); - - for (final Node statement : statements) { - statement.accept(this); + public Node enterFunctionNode(final FunctionNode functionNode) { + if(functionNode == topFunction) { + // the function being weighted; descend into its statements + functionNode.visitStatements(this); + } else { + // just a reference to inner function from outer function + weight += FUNC_EXPR_WEIGHT; } - return null; } @Override - public Node leave(final IdentNode identNode) { + public Node leaveIdentNode(final IdentNode identNode) { weight += ACCESS_WEIGHT + identNode.getName().length() * 2; return identNode; } @Override - public Node leave(final IfNode ifNode) { + public Node leaveIfNode(final IfNode ifNode) { weight += IF_WEIGHT; return ifNode; } @Override - public Node leave(final IndexNode indexNode) { + public Node leaveIndexNode(final IndexNode indexNode) { weight += ACCESS_WEIGHT; return indexNode; } @SuppressWarnings("rawtypes") @Override - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { weight += LITERAL_WEIGHT; if (literalNode instanceof ArrayLiteralNode) { @@ -230,67 +231,61 @@ final class WeighNodes extends NodeOperatorVisitor { } @Override - public Node leave(final PropertyNode propertyNode) { + public Node leavePropertyNode(final PropertyNode propertyNode) { weight += LITERAL_WEIGHT; return propertyNode; } @Override - public Node leave(final ReferenceNode referenceNode) { - weight += REFERENCE_WEIGHT; - return referenceNode; - } - - @Override - public Node leave(final ReturnNode returnNode) { + public Node leaveReturnNode(final ReturnNode returnNode) { weight += RETURN_WEIGHT; return returnNode; } @Override - public Node leave(final RuntimeNode runtimeNode) { + public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { weight += CALL_WEIGHT; return runtimeNode; } @Override - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { weight += SPLIT_WEIGHT; return null; } @Override - public Node leave(final SwitchNode switchNode) { + public Node leaveSwitchNode(final SwitchNode switchNode) { weight += SWITCH_WEIGHT; return switchNode; } @Override - public Node leave(final ThrowNode throwNode) { + public Node leaveThrowNode(final ThrowNode throwNode) { weight += THROW_WEIGHT; return throwNode; } @Override - public Node leave(final TryNode tryNode) { + public Node leaveTryNode(final TryNode tryNode) { weight += THROW_WEIGHT; return tryNode; } @Override - public Node leave(final VarNode varNode) { + public Node leaveVarNode(final VarNode varNode) { weight += VAR_WEIGHT; return varNode; } @Override - public Node leave(final WhileNode whileNode) { + public Node leaveWhileNode(final WhileNode whileNode) { weight += LOOP_WEIGHT; return whileNode; } @Override - public Node leave(final WithNode withNode) { + public Node leaveWithNode(final WithNode withNode) { weight += WITH_WEIGHT; return withNode; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java index 481e3855447..b7b76684147 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java @@ -36,7 +36,7 @@ import jdk.nashorn.internal.runtime.Source; * IR representation of a property access (period operator.) * */ -public class AccessNode extends BaseNode implements TypeOverride { +public class AccessNode extends BaseNode implements TypeOverride { /** Property ident. */ private IdentNode property; @@ -56,9 +56,7 @@ public class AccessNode extends BaseNode implements TypeOverride { super(source, token, finish, base); this.start = base.getStart(); - this.property = property; - - this.property.setIsPropertyName(); + this.property = property.setIsPropertyName(); } /** @@ -106,10 +104,10 @@ public class AccessNode extends BaseNode implements TypeOverride { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterAccessNode(this) != null) { base = base.accept(visitor); property = (IdentNode)property.accept(visitor); - return visitor.leave(this); + return visitor.leaveAccessNode(this); } return this; @@ -150,13 +148,14 @@ public class AccessNode extends BaseNode implements TypeOverride { } @Override - public void setType(final Type type) { + public AccessNode setType(final Type type) { if (DEBUG_FIELDS && !Type.areEquivalent(getSymbol().getSymbolType(), type)) { ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType()); } - property.setType(type); + property = property.setType(type); getSymbol().setTypeOverride(type); //always a temp so this is fine. hasCallSiteType = true; + return this; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java index 8107a8725f0..0c531bc2906 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java @@ -46,4 +46,11 @@ public interface Assignment { * @return get the assignment source node */ public Node getAssignmentSource(); + + /** + * Set assignment destination node. + * @param n the assignment destination node. + * @return a node equivalent to this one except for the requested change. + */ + public Node setAssignmentDest(D n); } diff --git a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java index ea632d1b672..26a28368877 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java @@ -38,6 +38,8 @@ public abstract class BaseNode extends Node implements FunctionCall { /** Base Node. */ protected Node base; + private boolean function; + /** * Constructor * @@ -96,6 +98,15 @@ public abstract class BaseNode extends Node implements FunctionCall { @Override public boolean isFunction() { - return false; + return function; + } + + /** + * Mark this node as being the callee operand of a {@link CallNode}. + * @return a base node identical to this one in all aspects except with its function flag set. + */ + public BaseNode setIsFunction() { + function = true; + return this; } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java index 26964ba5ca5..42c7a6cceda 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java @@ -35,7 +35,7 @@ import jdk.nashorn.internal.runtime.Source; */ public class BinaryNode extends UnaryNode { /** Left hand side argument. */ - protected Node lhs; + private Node lhs; /** * Constructor @@ -139,6 +139,11 @@ public class BinaryNode extends UnaryNode { return isAssignment() ? lhs() : null; } + @Override + public Node setAssignmentDest(Node n) { + return setLHS(n); + } + @Override public Node getAssignmentSource() { return rhs(); @@ -163,10 +168,9 @@ public class BinaryNode extends UnaryNode { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - lhs = lhs.accept(visitor); - rhs = rhs.accept(visitor); - return visitor.leave(this); + if (visitor.enterBinaryNode(this) != null) { + // TODO: good cause for a separate visitMembers: we could delegate to UnaryNode.visitMembers + return visitor.leaveBinaryNode((BinaryNode)setLHS(lhs.accept(visitor)).setRHS(rhs().accept(visitor))); } return this; @@ -229,8 +233,12 @@ public class BinaryNode extends UnaryNode { /** * Set the left hand side expression for this node * @param lhs new left hand side expression + * @return a node equivalent to this one except for the requested change. */ - public void setLHS(final Node lhs) { - this.lhs = lhs; + public BinaryNode setLHS(final Node lhs) { + if(this.lhs == lhs) return this; + final BinaryNode n = (BinaryNode)clone(); + n.lhs = lhs; + return n; } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk/nashorn/internal/ir/Block.java index e729d307b8c..6f138f85f10 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Block.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java @@ -25,14 +25,6 @@ package jdk.nashorn.internal.ir; -import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; -import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; -import static jdk.nashorn.internal.ir.Symbol.IS_LET; -import static jdk.nashorn.internal.ir.Symbol.IS_PARAM; -import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE; -import static jdk.nashorn.internal.ir.Symbol.IS_VAR; -import static jdk.nashorn.internal.ir.Symbol.KINDMASK; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; @@ -40,9 +32,9 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import jdk.nashorn.internal.codegen.Frame; import jdk.nashorn.internal.codegen.Label; -import jdk.nashorn.internal.ir.annotations.Reference; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.Source; @@ -51,14 +43,6 @@ import jdk.nashorn.internal.runtime.Source; * basis for script body. */ public class Block extends Node { - /** Parent context */ - @Reference - private Block parent; - - /** Owning function - a FunctionNode has itself as function */ - @Reference - protected FunctionNode function; - /** List of statements */ protected List statements; @@ -83,14 +67,10 @@ public class Block extends Node { * @param source source code * @param token token * @param finish finish - * @param parent reference to parent block - * @param function function node this block is in */ - public Block(final Source source, final long token, final int finish, final Block parent, final FunctionNode function) { + public Block(final Source source, final long token, final int finish) { super(source, token, finish); - this.parent = parent; - this.function = function; this.statements = new ArrayList<>(); this.symbols = new HashMap<>(); this.entryLabel = new Label("block_entry"); @@ -106,8 +86,6 @@ public class Block extends Node { protected Block(final Block block, final CopyState cs) { super(block); - this.parent = block.parent; - this.function = block.function; this.statements = new ArrayList<>(); for (final Node statement : block.getStatements()) { statements.add(cs.existingOrCopy(statement)); @@ -122,55 +100,7 @@ public class Block extends Node { @Override protected Node copy(final CopyState cs) { - return fixBlockChain(new Block(this, cs)); - } - - /** - * Whenever a clone that contains a hierarchy of blocks is created, - * this function has to be called to ensure that the parents point - * to the correct parent blocks or two different ASTs would not - * be completely separated. - * - * @return the argument - */ - static Block fixBlockChain(final Block root) { - root.accept(new NodeVisitor() { - private Block parent = root.getParent(); - private final FunctionNode function = root.getFunction(); - - @Override - public Node enter(final Block block) { - assert block.getFunction() == function; - block.setParent(parent); - parent = block; - - return block; - } - - @Override - public Node leave(final Block block) { - parent = block.getParent(); - - return block; - } - - @Override - public Node enter(final FunctionNode functionNode) { - assert functionNode.getFunction() == function; - - return enter((Block)functionNode); - } - - @Override - public Node leave(final FunctionNode functionNode) { - assert functionNode.getFunction() == function; - - return leave((Block)functionNode); - } - - }); - - return root; + return new Block(this, cs); } /** @@ -188,17 +118,12 @@ public class Block extends Node { } /** - * Prepend a statement to the statement list + * Prepend statements to the statement list * - * @param statement Statement node to add + * @param prepended statement to add */ - public void prependStatement(final Node statement) { - if (statement != null) { - final List newStatements = new ArrayList<>(); - newStatements.add(statement); - newStatements.addAll(statements); - setStatements(newStatements); - } + public void prependStatements(final List prepended) { + statements.addAll(0, prepended); } /** @@ -210,39 +135,6 @@ public class Block extends Node { statements.addAll(statementList); } - /** - * Add a new function to the function list. - * - * @param functionNode Function node to add. - */ - public void addFunction(final FunctionNode functionNode) { - assert parent != null : "Parent context missing."; - - parent.addFunction(functionNode); - } - - /** - * Add a list of functions to the function list. - * - * @param functionNodes Function nodes to add. - */ - public void addFunctions(final List functionNodes) { - assert parent != null : "Parent context missing."; - - parent.addFunctions(functionNodes); - } - - /** - * Set the function list to a new one - * - * @param functionNodes the nodes to set - */ - public void setFunctions(final List functionNodes) { - assert parent != null : "Parent context missing."; - - parent.setFunctions(functionNodes); - } - /** * Assist in IR navigation. * @@ -257,13 +149,9 @@ public class Block extends Node { try { // Ignore parent to avoid recursion. - if (visitor.enter(this) != null) { - for (int i = 0, count = statements.size(); i < count; i++) { - final Node statement = statements.get(i); - statements.set(i, statement.accept(visitor)); - } - - return visitor.leave(this); + if (visitor.enterBlock(this) != null) { + visitStatements(visitor); + return visitor.leaveBlock(this); } } finally { visitor.setCurrentBlock(saveBlock); @@ -281,51 +169,13 @@ public class Block extends Node { } /** - * Search for symbol. - * - * @param name Symbol name. - * - * @return Found symbol or null if not found. + * Retrieves an existing symbol defined in the current block. + * @param name the name of the symbol + * @return an existing symbol with the specified name defined in the current block, or null if this block doesn't + * define a symbol with this name. */ - public Symbol findSymbol(final String name) { - // Search up block chain to locate symbol. - - for (Block block = this; block != null; block = block.getParent()) { - // Find name. - final Symbol symbol = block.symbols.get(name); - // If found then we are good. - if (symbol != null) { - return symbol; - } - } - return null; - } - - /** - * Search for symbol in current function. - * - * @param name Symbol name. - * - * @return Found symbol or null if not found. - */ - public Symbol findLocalSymbol(final String name) { - // Search up block chain to locate symbol. - for (Block block = this; block != null; block = block.getParent()) { - // Find name. - final Symbol symbol = block.symbols.get(name); - // If found then we are good. - if (symbol != null) { - return symbol; - } - - // If searched function then we are done. - if (block == block.function) { - break; - } - } - - // Not found. - return null; + public Symbol getExistingSymbol(final String name) { + return symbols.get(name); } /** @@ -338,122 +188,6 @@ public class Block extends Node { return statements.size() == 1 && statements.get(0) instanceof CatchNode; } - /** - * Test to see if a symbol is local to the function. - * - * @param symbol Symbol to test. - * @return True if a local symbol. - */ - public boolean isLocal(final Symbol symbol) { - // some temp symbols have no block, so can be assumed local - final Block block = symbol.getBlock(); - return block == null || block.getFunction() == function; - } - - /** - * Declare the definition of a new symbol. - * - * @param name Name of symbol. - * @param symbolFlags Symbol flags. - * @param node Defining Node. - * - * @return Symbol for given name or null for redefinition. - */ - public Symbol defineSymbol(final String name, final int symbolFlags, final Node node) { - int flags = symbolFlags; - Symbol symbol = findSymbol(name); // Locate symbol. - - if ((flags & KINDMASK) == IS_GLOBAL) { - flags |= IS_SCOPE; - } - - if (symbol != null) { - // Symbol was already defined. Check if it needs to be redefined. - if ((flags & KINDMASK) == IS_PARAM) { - if (!function.isLocal(symbol)) { - // Not defined in this function. Create a new definition. - symbol = null; - } else if (symbol.isParam()) { - // Duplicate parameter. Null return will force an error. - assert false : "duplicate parameter"; - return null; - } - } else if ((flags & KINDMASK) == IS_VAR) { - if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & Symbol.IS_LET) == Symbol.IS_LET) { - assert !((flags & IS_LET) == IS_LET && symbol.getBlock() == this) : "duplicate let variable in block"; - // Always create a new definition. - symbol = null; - } else { - // Not defined in this function. Create a new definition. - if (!function.isLocal(symbol) || symbol.less(IS_VAR)) { - symbol = null; - } - } - } - } - - if (symbol == null) { - // If not found, then create a new one. - Block symbolBlock; - - // Determine where to create it. - if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { - symbolBlock = this; - } else { - symbolBlock = getFunction(); - } - - // Create and add to appropriate block. - symbol = new Symbol(name, flags, node, symbolBlock); - symbolBlock.putSymbol(name, symbol); - - if ((flags & Symbol.KINDMASK) != IS_GLOBAL) { - symbolBlock.getFrame().addSymbol(symbol); - symbol.setNeedsSlot(true); - } - } else if (symbol.less(flags)) { - symbol.setFlags(flags); - } - - if (node != null) { - node.setSymbol(symbol); - } - - return symbol; - } - - /** - * Declare the use of a symbol. - * - * @param name Name of symbol. - * @param node Using node - * - * @return Symbol for given name. - */ - public Symbol useSymbol(final String name, final Node node) { - Symbol symbol = findSymbol(name); - - if (symbol == null) { - // If not found, declare as a free var. - symbol = defineSymbol(name, IS_GLOBAL, node); - } else { - node.setSymbol(symbol); - } - - return symbol; - } - - /** - * Add parent name to the builder. - * - * @param sb String bulder. - */ - public void addParentName(final StringBuilder sb) { - if (parent != null) { - parent.addParentName(sb); - } - } - @Override public void toString(final StringBuilder sb) { for (final Node statement : statements) { @@ -511,16 +245,6 @@ public class Block extends Node { return frame; } - /** - * Get the FunctionNode for this block, i.e. the function it - * belongs to - * - * @return the function node - */ - public FunctionNode getFunction() { - return function; - } - /** * Reset the frame for this block * @@ -530,24 +254,6 @@ public class Block extends Node { this.frame = frame; } - /** - * Get the parent block - * - * @return parent block, or null if none exists - */ - public Block getParent() { - return parent; - } - - /** - * Set the parent block - * - * @param parent the new parent block - */ - public void setParent(final Block parent) { - this.parent = parent; - } - /** * Get the list of statements in this block * @@ -557,6 +263,15 @@ public class Block extends Node { return Collections.unmodifiableList(statements); } + /** + * Applies the specified visitor to all statements in the block. + * @param visitor the visitor. + */ + public void visitStatements(NodeVisitor visitor) { + for (ListIterator stmts = statements.listIterator(); stmts.hasNext();) { + stmts.set(stmts.next().accept(visitor)); + } + } /** * Reset the statement list for this block * @@ -592,4 +307,29 @@ public class Block extends Node { needsScope = true; } + /** + * Marks this block as using a specified scoped symbol. The block and its parent blocks up to but not + * including the block defining the symbol will be marked as needing parent scope. The block defining the symbol + * will be marked as one that needs to have its own scope. + * @param symbol the symbol being used. + * @param ancestors the iterator over block's containing lexical context + */ + public void setUsesScopeSymbol(final Symbol symbol, Iterator ancestors) { + if(symbol.getBlock() == this) { + setNeedsScope(); + } else { + setUsesParentScopeSymbol(symbol, ancestors); + } + } + + /** + * Invoked when this block uses a scope symbol defined in one of its ancestors. + * @param symbol the scope symbol being used + * @param ancestors iterator over ancestor blocks + */ + void setUsesParentScopeSymbol(final Symbol symbol, Iterator ancestors) { + if(ancestors.hasNext()) { + ancestors.next().setUsesScopeSymbol(symbol, ancestors); + } + } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java index 81c572d4b1b..7ad0dc6d143 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java @@ -64,8 +64,8 @@ public class BreakNode extends LabeledNode { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterBreakNode(this) != null) { + return visitor.leaveBreakNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java index 387369e62be..3410709caa6 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java @@ -37,7 +37,7 @@ import jdk.nashorn.internal.runtime.Source; * IR representation for a function call. * */ -public class CallNode extends Node implements TypeOverride { +public class CallNode extends Node implements TypeOverride { private Type type; @@ -176,13 +176,13 @@ public class CallNode extends Node implements TypeOverride { if (hasCallSiteType()) { return type; } - assert !function.getType().isUnknown(); - return function.getType(); + return function instanceof FunctionNode ? ((FunctionNode)function).getReturnType() : Type.OBJECT; } @Override - public void setType(final Type type) { + public CallNode setType(final Type type) { this.type = type; + return this; } private boolean hasCallSiteType() { @@ -208,14 +208,14 @@ public class CallNode extends Node implements TypeOverride { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterCallNode(this) != null) { function = function.accept(visitor); for (int i = 0, count = args.size(); i < count; i++) { args.set(i, args.get(i).accept(visitor)); } - return visitor.leave(this); + return visitor.leaveCallNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java index 928ba5bec61..61b892179d1 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java @@ -79,7 +79,7 @@ public class CaseNode extends BreakableNode { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterCaseNode(this) != null) { if (test != null) { test = test.accept(visitor); } @@ -87,7 +87,7 @@ public class CaseNode extends BreakableNode { body = (Block)body.accept(visitor); } - return visitor.leave(this); + return visitor.leaveCaseNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java index 187c3949ec2..005ffa8e008 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java @@ -84,7 +84,7 @@ public class CatchNode extends Node { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterCatchNode(this) != null) { exception = (IdentNode)exception.accept(visitor); if (exceptionCondition != null) { @@ -92,7 +92,7 @@ public class CatchNode extends Node { } body = (Block)body.accept(visitor); - return visitor.leave(this); + return visitor.leaveCatchNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java index 2063d6b2525..cbc7bff2a60 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java @@ -61,8 +61,8 @@ public class ContinueNode extends LabeledNode { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterContinueNode(this) != null) { + return visitor.leaveContinueNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java index 476643a1c2a..3939795e248 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java @@ -63,11 +63,11 @@ public class DoWhileNode extends WhileNode { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterDoWhileNode(this) != null) { body = (Block)body.accept(visitor); test = test.accept(visitor); - return visitor.leave(this); + return visitor.leaveDoWhileNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java index 0bfacd5d5a0..15330a37288 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java @@ -57,8 +57,8 @@ public class EmptyNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterEmptyNode(this) != null) { + return visitor.leaveEmptyNode(this); } return this; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java index 501468bb9a6..8ae7d556f3c 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java @@ -85,9 +85,9 @@ public class ExecuteNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterExecuteNode(this) != null) { setExpression(expression.accept(visitor)); - return visitor.leave(this); + return visitor.leaveExecuteNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/ForNode.java b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java index 53b56752acc..e55054dde1f 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ForNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ForNode.java @@ -76,7 +76,7 @@ public class ForNode extends WhileNode { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterForNode(this) != null) { if (init != null) { init = init.accept(visitor); } @@ -91,7 +91,7 @@ public class ForNode extends WhileNode { body = (Block)body.accept(visitor); - return visitor.leave(this); + return visitor.leaveForNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java index 7fd77cd0471..2b0e109b7fa 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -34,7 +34,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; -import java.util.LinkedList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; @@ -47,7 +47,7 @@ import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.Parser; -import jdk.nashorn.internal.runtime.Debug; +import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.Source; import jdk.nashorn.internal.runtime.UserAccessorProperty; import jdk.nashorn.internal.runtime.linker.LinkerCallSite; @@ -57,6 +57,8 @@ import jdk.nashorn.internal.runtime.linker.LinkerCallSite; */ public class FunctionNode extends Block { + private static final Type FUNCTION_TYPE = Type.typeFor(ScriptFunction.class); + /** Function kinds */ public enum Kind { /** a normal function - nothing special */ @@ -112,9 +114,6 @@ public class FunctionNode extends Block { /** List of parameters. */ private List parameters; - /** List of nested functions. */ - private List functions; - /** First token of function. **/ private long firstToken; @@ -157,10 +156,6 @@ public class FunctionNode extends Block { /** Pending control list. */ private final Stack controlStack; - /** Variable declarations in the function's scope */ - @Ignore - private final List declarations; - /** VarNode for this function statement */ @Ignore //this is explicit code anyway and should not be traversed after lower private VarNode funcVarNode; @@ -184,33 +179,35 @@ public class FunctionNode extends Block { private int flags; /** Is anonymous function flag. */ - private static final int IS_ANONYMOUS = 0b0000_0000_0000_0001; - /** Is statement flag */ - private static final int IS_STATEMENT = 0b0000_0000_0000_0010; + private static final int IS_ANONYMOUS = 1 << 0; + /** Is the function created in a function declaration (as opposed to a function expression) */ + private static final int IS_DECLARED = 1 << 1; /** is this a strict mode function? */ - private static final int IS_STRICT_MODE = 0b0000_0000_0000_0100; + private static final int IS_STRICT_MODE = 1 << 2; /** Does the function use the "arguments" identifier ? */ - private static final int USES_ARGUMENTS = 0b0000_0000_0000_1000; + private static final int USES_ARGUMENTS = 1 << 3; /** Are we lowered ? */ - private static final int IS_LOWERED = 0b0000_0000_0001_0000; + private static final int IS_LOWERED = 1 << 4; /** Has this node been split because it was too large? */ - private static final int IS_SPLIT = 0b0000_0000_0010_0000; + private static final int IS_SPLIT = 1 << 5; /** Does the function call eval? */ - private static final int HAS_EVAL = 0b0000_0000_0100_0000; + private static final int HAS_EVAL = 1 << 6; /** Does the function contain a with block ? */ - private static final int HAS_WITH = 0b0000_0000_1000_0000; + private static final int HAS_WITH = 1 << 7; /** Does a descendant function contain a with or eval? */ - private static final int HAS_DESCENDANT_WITH_OR_EVAL = 0b0000_0001_0000_0000; + private static final int HAS_DESCENDANT_WITH_OR_EVAL = 1 << 8; /** Does the function define "arguments" identifier as a parameter of nested function name? */ - private static final int DEFINES_ARGUMENTS = 0b0000_0010_0000_0000; + private static final int DEFINES_ARGUMENTS = 1 << 9; /** Does the function need a self symbol? */ - private static final int NEEDS_SELF_SYMBOL = 0b0000_0100_0000_0000; + private static final int NEEDS_SELF_SYMBOL = 1 << 10; /** Does this function or any of its descendants use variables from an ancestor function's scope (incl. globals)? */ - private static final int USES_ANCESTOR_SCOPE = 0b0000_1000_0000_0000; + private static final int USES_ANCESTOR_SCOPE = 1 << 11; /** Is this function lazily compiled? */ - private static final int IS_LAZY = 0b0001_0000_0000_0000; + private static final int IS_LAZY = 1 << 12; /** Does this function have lazy, yet uncompiled children */ - private static final int HAS_LAZY_CHILDREN = 0b0010_0000_0000_0000; + private static final int HAS_LAZY_CHILDREN = 1 << 13; + /** Does this function have lazy, yet uncompiled children */ + private static final int IS_PROGRAM = 1 << 14; /** Does this function or any nested functions contain a with or an eval? */ private static final int HAS_DEEP_WITH_OR_EVAL = HAS_EVAL | HAS_WITH | HAS_DESCENDANT_WITH_OR_EVAL; @@ -225,14 +222,6 @@ public class FunctionNode extends Block { /** What is the return type of this function? */ private Type returnType = Type.UNKNOWN; - /** - * Used to keep track of a function's parent blocks. - * This is needed when a (finally body) block is cloned than contains inner functions. - * Does not include function.getParent(). - */ - @Ignore - private List referencingParentBlocks; - /** * Constructor * @@ -240,42 +229,28 @@ public class FunctionNode extends Block { * @param token token * @param finish finish * @param namespace the namespace - * @param parent the parent block * @param ident the identifier * @param name the name of the function */ - @SuppressWarnings("LeakingThisInConstructor") - public FunctionNode(final Source source, final long token, final int finish, final Namespace namespace, final Block parent, final IdentNode ident, final String name) { - super(source, token, finish, parent, null); + public FunctionNode(final Source source, final long token, final int finish, final Namespace namespace, final IdentNode ident, final String name) { + super(source, token, finish); this.ident = ident; this.name = name; this.kind = Kind.NORMAL; this.parameters = new ArrayList<>(); - this.functions = new ArrayList<>(); this.firstToken = token; this.lastToken = token; this.namespace = namespace; this.labelStack = new Stack<>(); this.controlStack = new Stack<>(); - this.declarations = new ArrayList<>(); - // my block -> function is this. We added @SuppressWarnings("LeakingThisInConstructor") as NetBeans identifies - // it as such a leak - this is a false positive as we're setting this into a field of the object being - // constructed, so it can't be seen from other threads. - this.function = this; this.compilationState = EnumSet.of(CompilationState.INITIALIZED); this.specializedTypes = new HashMap<>(); } - @SuppressWarnings("LeakingThisInConstructor") private FunctionNode(final FunctionNode functionNode, final CopyState cs) { super(functionNode, cs); - this.functions = new ArrayList<>(); - for (final FunctionNode f : functionNode.getFunctions()) { - this.functions.add((FunctionNode)cs.existingOrCopy(f)); - } - this.ident = (IdentNode)cs.existingOrCopy(functionNode.ident); this.name = functionNode.name; this.kind = functionNode.kind; @@ -296,22 +271,12 @@ public class FunctionNode extends Block { this.calleeNode = (IdentNode)cs.existingOrCopy(functionNode.calleeNode); this.labelStack = new Stack<>(); this.controlStack = new Stack<>(); - this.declarations = new ArrayList<>(); - - for (final VarNode decl : functionNode.getDeclarations()) { - declarations.add((VarNode) cs.existingOrCopy(decl)); //TODO same? - } this.flags = functionNode.flags; this.funcVarNode = (VarNode)cs.existingOrCopy(functionNode.funcVarNode); /** VarNode for this function statement */ - // my block -> function is this. We added @SuppressWarnings("LeakingThisInConstructor") as NetBeans identifies - // it as such a leak - this is a false positive as we're setting this into a field of the object being - // constructed, so it can't be seen from other threads. - this.function = this; - this.compilationState = EnumSet.copyOf(functionNode.compilationState); this.specializedTypes = new HashMap<>(); } @@ -319,21 +284,21 @@ public class FunctionNode extends Block { @Override protected Node copy(final CopyState cs) { // deep clone all parent blocks - return fixBlockChain(new FunctionNode(this, cs)); + return new FunctionNode(this, cs); } @Override public Node accept(final NodeVisitor visitor) { - final FunctionNode saveFunctionNode = visitor.getCurrentFunctionNode(); - final Block saveBlock = visitor.getCurrentBlock(); + final FunctionNode saveFunctionNode = visitor.getCurrentFunctionNode(); + final Block saveBlock = visitor.getCurrentBlock(); + final MethodEmitter saveMethodEmitter = visitor.getCurrentMethodEmitter(); + final CompileUnit saveCompileUnit = visitor.getCurrentCompileUnit(); visitor.setCurrentFunctionNode(this); - visitor.setCurrentCompileUnit(getCompileUnit()); - visitor.setCurrentMethodEmitter(getMethodEmitter()); visitor.setCurrentBlock(this); try { - if (visitor.enter(this) != null) { + if (visitor.enterFunctionNode(this) != null) { if (ident != null) { ident = (IdentNode)ident.accept(visitor); } @@ -342,51 +307,25 @@ public class FunctionNode extends Block { parameters.set(i, (IdentNode)parameters.get(i).accept(visitor)); } - for (int i = 0, count = functions.size(); i < count; i++) { - functions.set(i, (FunctionNode)functions.get(i).accept(visitor)); - } - for (int i = 0, count = statements.size(); i < count; i++) { statements.set(i, statements.get(i).accept(visitor)); } - return visitor.leave(this); + return visitor.leaveFunctionNode(this); } } finally { visitor.setCurrentBlock(saveBlock); visitor.setCurrentFunctionNode(saveFunctionNode); - visitor.setCurrentCompileUnit(saveFunctionNode != null ? saveFunctionNode.getCompileUnit() : null); - visitor.setCurrentMethodEmitter(saveFunctionNode != null ? saveFunctionNode.getMethodEmitter() : null); + visitor.setCurrentCompileUnit(saveCompileUnit); + visitor.setCurrentMethodEmitter(saveMethodEmitter); } return this; } - /** - * Locate the parent function. - * - * @return Parent function. - */ - public FunctionNode findParentFunction() { - return getParent() != null ? getParent().getFunction() : null; - } - - /** - * Add parent name to the builder. - * - * @param sb String builder. - */ - @Override - public void addParentName(final StringBuilder sb) { - if (!isScript()) { - sb.append(getName()); - sb.append("$"); - } - } - @Override public boolean needsScope() { - return super.needsScope() || isScript(); + return super.needsScope() || isProgram(); } /** @@ -544,12 +483,18 @@ public class FunctionNode extends Block { } /** - * Determine if script function. - * - * @return True if script function. + * Returns true if the function is the top-level program. + * @return True if this function node represents the top-level program. */ - public boolean isScript() { - return getParent() == null; + public boolean isProgram() { + return (flags & IS_PROGRAM) != 0; + } + + /** + * Marks the function as representing the top-level program. + */ + public void setProgram() { + flags |= IS_PROGRAM; } /** @@ -589,31 +534,31 @@ public class FunctionNode extends Block { /** * Flag this function as using the {@code with} keyword + * @param ancestors the iterator over functions in this functions's containing lexical context */ - public void setHasWith() { + public void setHasWith(final Iterator ancestors) { if(!hasWith()) { this.flags |= HAS_WITH; // with requires scope in parents. // TODO: refine this. with should not force all variables in parents to be in scope, only those that are // actually referenced as identifiers by name - markParentForWithOrEval(); + markParentForWithOrEval(ancestors); } } - private void markParentForWithOrEval() { + private void markParentForWithOrEval(final Iterator ancestors) { // If this is invoked, then either us or a descendant uses with or eval, meaning we must have our own scope. setNeedsScope(); - final FunctionNode parentFunction = findParentFunction(); - if(parentFunction != null) { - parentFunction.setDescendantHasWithOrEval(); + if(ancestors.hasNext()) { + ancestors.next().setDescendantHasWithOrEval(ancestors); } } - private void setDescendantHasWithOrEval() { + private void setDescendantHasWithOrEval(final Iterator ancestors) { if((flags & HAS_DESCENDANT_WITH_OR_EVAL) == 0) { flags |= HAS_DESCENDANT_WITH_OR_EVAL; - markParentForWithOrEval(); + markParentForWithOrEval(ancestors); } } @@ -628,11 +573,12 @@ public class FunctionNode extends Block { /** * Flag this function as calling the {@code eval} function + * @param ancestors the iterator over functions in this functions's containing lexical context */ - public void setHasEval() { + public void setHasEval(final Iterator ancestors) { if(!hasEval()) { this.flags |= HAS_EVAL; - markParentForWithOrEval(); + markParentForWithOrEval(ancestors); } } @@ -665,11 +611,34 @@ public class FunctionNode extends Block { } /** - * Get all nested functions - * @return list of nested functions in this function + * Returns a list of functions declared by this function. Only includes declared functions, and does not include any + * function expressions that might occur in its body. + * @return a list of functions declared by this function. */ - public List getFunctions() { - return Collections.unmodifiableList(functions); + public List getDeclaredFunctions() { + // Note that the function does not have a dedicated list of declared functions, but rather relies on the + // invariant that all function declarations are at the beginning of the statement list as VarNode with a + // FunctionNode marked as statement with its variable initializer. Every VarNode is also preceded by a + // LineNumberNode. This invariant is established by the parser and has to be preserved in visitors. + final List fns = new ArrayList<>(); + for (final Node stmt : statements) { + if(stmt instanceof LineNumberNode) { + continue; + } else if(stmt instanceof VarNode) { + final Node init = ((VarNode)stmt).getInit(); + if(init instanceof FunctionNode) { + final FunctionNode fn = (FunctionNode)init; + if(fn.isDeclared()) { + fns.add(fn); + continue; + } + } + } + // Node is neither a LineNumberNode, nor a function declaration VarNode. Since all function declarations are + // at the start of the function, we've reached the end of function declarations. + break; + } + return fns; } /** @@ -801,7 +770,7 @@ public class FunctionNode extends Block { public boolean needsArguments() { // uses "arguments" or calls eval, but it does not redefine "arguments", and finally, it's not a script, since // for top-level script, "arguments" is picked up from Context by Global.init() instead. - return (flags & MAYBE_NEEDS_ARGUMENTS) != 0 && (flags & DEFINES_ARGUMENTS) == 0 && !isScript(); + return (flags & MAYBE_NEEDS_ARGUMENTS) != 0 && (flags & DEFINES_ARGUMENTS) == 0 && !isProgram(); } /** @@ -820,7 +789,7 @@ public class FunctionNode extends Block { * @return true if the function needs parent scope. */ public boolean needsParentScope() { - return (flags & NEEDS_PARENT_SCOPE) != 0 || isScript(); + return (flags & NEEDS_PARENT_SCOPE) != 0 || isProgram(); } /** @@ -880,7 +849,7 @@ public class FunctionNode extends Block { * @return true if all variables should be in scope */ public boolean allVarsInScope() { - return isScript() || (flags & HAS_ALL_VARS_IN_SCOPE) != 0; + return isProgram() || (flags & HAS_ALL_VARS_IN_SCOPE) != 0; } /** @@ -989,19 +958,19 @@ public class FunctionNode extends Block { } /** - * Check if this function is a statement - * @return true if function is a statement + * Check if this function is created as a function declaration (as opposed to function expression) + * @return true if function is declared. */ - public boolean isStatement() { - return (flags & IS_STATEMENT) != 0; + public boolean isDeclared() { + return (flags & IS_DECLARED) != 0; } /** - * Flag this function as a statement + * Flag this function as being created as a function declaration (as opposed to a function expression). * @see Parser */ - public void setIsStatement() { - this.flags |= IS_STATEMENT; + public void setIsDeclared() { + this.flags |= IS_DECLARED; } /** @@ -1049,35 +1018,16 @@ public class FunctionNode extends Block { } /** - * Marks this function as one using any global symbol. The function and all its parent functions will all be marked - * as needing parent scope. - * @see #needsParentScope() + * Marks this function as using any of its ancestors' scopes. */ - public void setUsesGlobalSymbol() { + public void setUsesAncestorScope() { this.flags |= USES_ANCESTOR_SCOPE; - final FunctionNode parentFn = findParentFunction(); - if(parentFn != null) { - parentFn.setUsesGlobalSymbol(); - } } - /** - * Marks this function as using a specified scoped symbol. The function and its parent functions up to but not - * including the function defining the symbol will be marked as needing parent scope. The function defining the - * symbol will be marked as one that needs to have its own scope. - * @param symbol the symbol being used. - * @see #needsParentScope() - */ - public void setUsesScopeSymbol(final Symbol symbol) { - if(symbol.getBlock() == this) { - setNeedsScope(); - } else { - this.flags |= USES_ANCESTOR_SCOPE; - final FunctionNode parentFn = findParentFunction(); - if (parentFn != null) { - parentFn.setUsesScopeSymbol(symbol); - } - } + @Override + void setUsesParentScopeSymbol(Symbol symbol, Iterator ancestors) { + setUsesAncestorScope(); + super.setUsesParentScopeSymbol(symbol, ancestors); } /** @@ -1152,7 +1102,7 @@ public class FunctionNode extends Block { @Override public Type getType() { - return getReturnType(); + return FUNCTION_TYPE; } /** @@ -1211,56 +1161,6 @@ public class FunctionNode extends Block { return (flags & IS_LOWERED) != 0; } - /** - * Add a new function to the function list. - * - * @param functionNode Function node to add. - */ - @Override - public void addFunction(final FunctionNode functionNode) { - assert functionNode != null; - functions.add(functionNode); - } - - /** - * Add a list of functions to the function list. - * - * @param functionNodes Function nodes to add. - */ - @Override - public void addFunctions(final List functionNodes) { - functions.addAll(functionNodes); - } - - /** - * Set a function list - * - * @param functionNodes to set - */ - @Override - public void setFunctions(final List functionNodes) { - this.functions = functionNodes; - } - - /** - * Add a variable declaration that should be visible to the entire function - * scope. Parser does this. - * - * @param varNode a var node - */ - public void addDeclaration(final VarNode varNode) { - declarations.add(varNode); - } - - /** - * Return all variable declarations from this function scope - * - * @return all VarNodes in scope - */ - public List getDeclarations() { - return Collections.unmodifiableList(declarations); - } - /** * Get the compile unit used to compile this function * @see Compiler @@ -1294,32 +1194,4 @@ public class FunctionNode extends Block { public void setMethodEmitter(final MethodEmitter method) { this.method = method; } - - /** - * Each FunctionNode maintains a list of reference to its parent blocks. - * Add a parent block to this function. - * - * @param parentBlock a block to remember as parent - */ - public void addReferencingParentBlock(final Block parentBlock) { - assert parentBlock.getFunction() == function.findParentFunction() : Debug.id(parentBlock.getFunction()) + "!=" + Debug.id(function.findParentFunction()); // all parent blocks must be in the same function - if (parentBlock != function.getParent()) { - if (referencingParentBlocks == null) { - referencingParentBlocks = new LinkedList<>(); - } - referencingParentBlocks.add(parentBlock); - } - } - - /** - * Get the known parent blocks to this function - * - * @return list of parent blocks - */ - public List getReferencingParentBlocks() { - if (referencingParentBlocks == null) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(referencingParentBlocks); - } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java index b0570a25ce5..889a870041e 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java @@ -38,18 +38,18 @@ import jdk.nashorn.internal.runtime.Source; /** * IR representation for an identifier. */ -public class IdentNode extends Node implements PropertyKey, TypeOverride, FunctionCall { +public class IdentNode extends Node implements PropertyKey, TypeOverride, FunctionCall { + private static final int PROPERTY_NAME = 1 << 0; + private static final int INITIALIZED_HERE = 1 << 1; + private static final int FUNCTION = 1 << 2; + /** Identifier. */ private final String name; /** Type for a callsite, e.g. X in a get()X or a set(X)V */ private Type callSiteType; - /** flag for an ident that is the property name of an AccessNode. */ - private boolean isPropertyName; - - /** flag for an ident on the left hand side of var lhs = rhs;. */ - private boolean isInitializedHere; + private byte flags; /** * Constructor @@ -71,9 +71,8 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi */ public IdentNode(final IdentNode identNode) { super(identNode); - this.name = identNode.getName(); - this.isPropertyName = identNode.isPropertyName; - this.isInitializedHere = identNode.isInitializedHere; + this.name = identNode.getName(); + this.flags = identNode.flags; } @Override @@ -92,12 +91,17 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi } @Override - public void setType(final Type type) { + public IdentNode setType(final Type type) { if (DEBUG_FIELDS && getSymbol() != null && !Type.areEquivalent(getSymbol().getSymbolType(), type)) { ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType()); } - this.callSiteType = 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; + } + final IdentNode n = (IdentNode)clone(); + n.callSiteType = type; + return n; } @Override @@ -131,8 +135,8 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterIdentNode(this) != null) { + return visitor.leaveIdentNode(this); } return this; @@ -179,14 +183,18 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi * @return true if this is a property name */ public boolean isPropertyName() { - return isPropertyName; + return (flags & PROPERTY_NAME) != 0; } /** * Flag this IdentNode as a property name + * @return a node equivalent to this one except for the requested change. */ - public void setIsPropertyName() { - isPropertyName = true; + public IdentNode setIsPropertyName() { + if(isPropertyName()) return this; + final IdentNode n = (IdentNode)clone(); + n.flags |= PROPERTY_NAME; + return n; } /** @@ -194,14 +202,18 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi * @return true if IdentNode is initialized on creation */ public boolean isInitializedHere() { - return isInitializedHere; + return (flags & INITIALIZED_HERE) != 0; } /** * Flag IdentNode to be initialized on creation + * @return a node equivalent to this one except for the requested change. */ - public void setIsInitializedHere() { - isInitializedHere = true; + public IdentNode setIsInitializedHere() { + if(isInitializedHere()) return this; + final IdentNode n = (IdentNode)clone(); + n.flags |= INITIALIZED_HERE; + return n; } /** @@ -216,6 +228,17 @@ public class IdentNode extends Node implements PropertyKey, TypeOverride, Functi @Override public boolean isFunction() { - return false; + return (flags & FUNCTION) != 0; + } + + /** + * Mark this node as being the callee operand of a {@link CallNode}. + * @return an ident node identical to this one in all aspects except with its function flag set. + */ + public IdentNode setIsFunction() { + if(isFunction()) return this; + final IdentNode n = (IdentNode)clone(); + n.flags |= FUNCTION; + return n; } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/IfNode.java b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java index 81148c3867c..3ddcf1dc440 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IfNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IfNode.java @@ -75,7 +75,7 @@ public class IfNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterIfNode(this) != null) { test = test.accept(visitor); pass = (Block)pass.accept(visitor); @@ -84,7 +84,7 @@ public class IfNode extends Node { fail = (Block)fail.accept(visitor); } - return visitor.leave(this); + return visitor.leaveIfNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java index 9feb5ebf2bf..4745bf64211 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java @@ -36,7 +36,7 @@ import jdk.nashorn.internal.runtime.Source; * IR representation of an indexed access (brackets operator.) * */ -public class IndexNode extends BaseNode implements TypeOverride { +public class IndexNode extends BaseNode implements TypeOverride { /** Property ident. */ private Node index; @@ -92,10 +92,10 @@ public class IndexNode extends BaseNode implements TypeOverride { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterIndexNode(this) != null) { base = base.accept(visitor); index = index.accept(visitor); - return visitor.leave(this); + return visitor.leaveIndexNode(this); } return this; @@ -144,12 +144,13 @@ public class IndexNode extends BaseNode implements TypeOverride { } @Override - public void setType(final Type type) { + public IndexNode setType(final Type type) { if (DEBUG_FIELDS && !Type.areEquivalent(getSymbol().getSymbolType(), type)) { ObjectClassGenerator.LOG.info(getClass().getName() + " " + this + " => " + type + " instead of " + getType()); } hasCallSiteType = true; getSymbol().setTypeOverride(type); + return this; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java index c61bfcbd107..756ea2dfb9b 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java @@ -81,10 +81,10 @@ public class LabelNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterLabelNode(this) != null) { label = (IdentNode)label.accept(visitor); body = (Block)body.accept(visitor); - return visitor.leave(this); + return visitor.leaveLabelNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java b/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java new file mode 100644 index 00000000000..2db1f7963e5 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/ir/LexicalContext.java @@ -0,0 +1,198 @@ +package jdk.nashorn.internal.ir; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A class that tracks the current lexical context of node visitation as a stack of {@link Block} nodes. Has special + * methods to retrieve useful subsets of the context. + */ +public class LexicalContext implements Cloneable { + private final Deque lexicalContext; + + /** + * Creates a new empty lexical context. + */ + public LexicalContext() { + lexicalContext = new ArrayDeque<>(); + } + + /** + * Pushes a new block on top of the context, making it the innermost open block. + * @param block the new block + */ + public void push(Block block) { + //new Exception(block.toString()).printStackTrace(); + lexicalContext.push(block); + } + + /** + * Pops the innermost block off the context. + * @param the block expected to be popped, used to detect unbalanced pushes/pops + */ + public void pop(Block block) { + final Block popped = lexicalContext.pop(); + assert popped == block; + } + + /** + * Returns an iterator over all blocks in the context, with the top block (innermost lexical context) first. + * @return an iterator over all blocks in the context. + */ + public Iterator getBlocks() { + return lexicalContext.iterator(); + } + + /** + * Returns an iterator over all functions in the context, with the top (innermost open) function first. + * @return an iterator over all functions in the context. + */ + public Iterator getFunctions() { + return new FunctionIterator(getBlocks()); + } + + private static final class FunctionIterator implements Iterator { + private final Iterator it; + private FunctionNode next; + + FunctionIterator(Iterator it) { + this.it = it; + next = findNext(); + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public FunctionNode next() { + if(next == null) { + throw new NoSuchElementException(); + } + FunctionNode lnext = next; + next = findNext(); + return lnext; + } + + private FunctionNode findNext() { + while(it.hasNext()) { + final Block block = it.next(); + if(block instanceof FunctionNode) { + return ((FunctionNode)block); + } + } + return null; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + /** + * Returns an iterator over all ancestors block of the given block, with its parent block first. + * @param block the block whose ancestors are returned + * @return an iterator over all ancestors block of the given block. + */ + public Iterator getAncestorBlocks(Block block) { + final Iterator it = getBlocks(); + while(it.hasNext()) { + final Block b = it.next(); + if(block == b) { + return it; + } + } + throw new AssertionError("Block is not on the current lexical context stack"); + } + + /** + * Returns an iterator over a block and all its ancestors blocks, with the block first. + * @param block the block that is the starting point of the iteration. + * @return an iterator over a block and all its ancestors. + */ + public Iterator getBlocks(final Block block) { + final Iterator it = getAncestorBlocks(block); + return new Iterator() { + boolean blockReturned = false; + @Override + public boolean hasNext() { + return it.hasNext() || !blockReturned; + } + @Override + public Block next() { + if(blockReturned) { + return it.next(); + } + blockReturned = true; + return block; + } + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * Returns the closest function node to the block. If the block is itself a function, it is returned. + * @param block the block + * @return the function closest to the block. + * @see #getParentFunction(Block) + */ + public FunctionNode getFunction(Block block) { + if(block instanceof FunctionNode) { + return (FunctionNode)block; + } + return getParentFunction(block); + } + + /** + * Returns the closest function node to the block and all its ancestor functions. If the block is itself a function, + * it is returned too. + * @param block the block + * @return the closest function node to the block and all its ancestor functions. + */ + public Iterator getFunctions(final Block block) { + return new FunctionIterator(getBlocks(block)); + } + + /** + * Returns the containing function of the block. If the block is itself a function, its parent function is returned. + * @param block the block + * @return the containing function of the block. + * @see #getFunction(Block) + */ + public FunctionNode getParentFunction(Block block) { + return getFirstFunction(getAncestorBlocks(block)); + } + + private static FunctionNode getFirstFunction(Iterator it) { + while(it.hasNext()) { + final Block ancestor = it.next(); + if(ancestor instanceof FunctionNode) { + return (FunctionNode)ancestor; + } + } + return null; + } + + /** + * Returns the innermost block in the context. + * @return the innermost block in the context. + */ + public Block getCurrentBlock() { + return lexicalContext.element(); + } + + /** + * Returns the innermost function in the context. + * @return the innermost function in the context. + */ + public FunctionNode getCurrentFunction() { + return getFirstFunction(getBlocks()); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java index ef1c05e13e8..c7912ff09e0 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java @@ -63,8 +63,8 @@ public class LineNumberNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterLineNumberNode(this) != null) { + return visitor.leaveLineNumberNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java index f1bf1b80c64..cc424b7aad3 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java @@ -46,7 +46,7 @@ import jdk.nashorn.internal.runtime.Undefined; */ public abstract class LiteralNode extends Node implements PropertyKey { /** Literal value */ - protected T value; + protected final T value; /** * Constructor @@ -67,8 +67,17 @@ public abstract class LiteralNode extends Node implements PropertyKey { * @param literalNode source node */ protected LiteralNode(final LiteralNode literalNode) { + this(literalNode, literalNode.value); + } + + /** + * A copy constructor with value change. + * @param literalNode the original literal node + * @param newValue new value for this node + */ + protected LiteralNode(final LiteralNode literalNode, final T newValue) { super(literalNode); - this.value = literalNode.value; + this.value = newValue; } @Override @@ -217,8 +226,8 @@ public abstract class LiteralNode extends Node implements PropertyKey { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); + if (visitor.enterLiteralNode(this) != null) { + return visitor.leaveLiteralNode(this); } return this; @@ -544,6 +553,10 @@ public abstract class LiteralNode extends Node implements PropertyKey { super(literalNode); } + private NodeLiteralNode(final LiteralNode literalNode, final Node value) { + super(literalNode, value); + } + @Override protected Node copy(final CopyState cs) { return new NodeLiteralNode(this); @@ -551,11 +564,14 @@ public abstract class LiteralNode extends Node implements PropertyKey { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterLiteralNode(this) != null) { if (value != null) { - value = value.accept(visitor); + final Node newValue = value.accept(visitor); + if(value != newValue) { + return visitor.leaveLiteralNode(new NodeLiteralNode(this, newValue)); + } } - return visitor.leave(this); + return visitor.leaveLiteralNode(this); } return this; @@ -878,14 +894,14 @@ public abstract class LiteralNode extends Node implements PropertyKey { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterLiteralNode(this) != null) { for (int i = 0; i < value.length; i++) { final Node element = value[i]; if (element != null) { value[i] = element.accept(visitor); } } - return visitor.leave(this); + return visitor.leaveLiteralNode(this); } return this; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/Location.java b/nashorn/src/jdk/nashorn/internal/ir/Location.java index 16ee680dabf..c8e01dd35f8 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Location.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Location.java @@ -65,7 +65,11 @@ public class Location implements Cloneable { @Override protected Object clone() { - return new Location(this); + try { + return super.clone(); + } catch(CloneNotSupportedException e) { + throw new AssertionError(e); + } } @Override diff --git a/nashorn/src/jdk/nashorn/internal/ir/Node.java b/nashorn/src/jdk/nashorn/internal/ir/Node.java index 24ad87936bb..c5f01337a2b 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Node.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Node.java @@ -165,11 +165,18 @@ public abstract class Node extends Location { return true; } - setIsResolved(); + setIsResolved(true); return false; } + /** + * Reset the resolved flag. + */ + public void resetResolved() { + setIsResolved(false); + } + /** * Is this a debug info node like LineNumberNode etc? * @@ -234,8 +241,7 @@ public abstract class Node extends Location { * * @return Deep copy of the Node. */ - @Override - public final Node clone() { + public final Node copy() { return copy(new CopyState()); } @@ -349,10 +355,10 @@ public abstract class Node extends Location { } /** - * Flag this node as resolved, i.e. code has been generated for it + * Flag this node as resolved or not, i.e. code has been generated for it */ - public void setIsResolved() { - this.isResolved = true; + private void setIsResolved(boolean isResolved) { + this.isResolved = isResolved; } /** diff --git a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java index 8b720de41b0..f6724a62c45 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java @@ -72,12 +72,12 @@ public class ObjectNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterObjectNode(this) != null) { for (int i = 0, count = elements.size(); i < count; i++) { elements.set(i, elements.get(i).accept(visitor)); } - return visitor.leave(this); + return visitor.leaveObjectNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java index 75103377b39..a6bc49de894 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java @@ -88,7 +88,7 @@ public class PropertyNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterPropertyNode(this) != null) { key = (PropertyKey)((Node)key).accept(visitor); if (value != null) { @@ -103,7 +103,7 @@ public class PropertyNode extends Node { setter = setter.accept(visitor); } - return visitor.leave(this); + return visitor.leavePropertyNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java b/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java deleted file mode 100644 index 3cae7b522c9..00000000000 --- a/nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java +++ /dev/null @@ -1,91 +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.ir.annotations.Reference; -import jdk.nashorn.internal.ir.visitor.NodeVisitor; -import jdk.nashorn.internal.runtime.Source; - -/** - * IR representation of a reference to another entity (function.) - */ -public class ReferenceNode extends Node { - /** Node referenced. */ - @Reference - private final FunctionNode reference; - - /** - * Constructor - * - * @param source the source - * @param token token - * @param finish finish - * @param reference the function node to reference - */ - public ReferenceNode(final Source source, final long token, final int finish, final FunctionNode reference) { - super(source, token, finish); - - this.reference = reference; - } - - private ReferenceNode(final ReferenceNode referenceNode) { - super(referenceNode); - - this.reference = referenceNode.reference; - } - - @Override - protected Node copy(final CopyState cs) { - return new ReferenceNode(this); - } - - @Override - public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - return visitor.leave(this); - } - - return this; - } - - @Override - public void toString(final StringBuilder sb) { - if (reference == null) { - sb.append("null"); - } else { - reference.toString(sb); - } - } - - /** - * Get there function node reference that this node points tp - * @return a function node reference - */ - public FunctionNode getReference() { - return reference; - } - -} diff --git a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java index 35395b30d79..1400f395868 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java @@ -100,12 +100,12 @@ public class ReturnNode extends Node { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterReturnNode(this) != null) { if (expression != null) { expression = expression.accept(visitor); } - return visitor.leave(this); + return visitor.leaveReturnNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java b/nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java index bfc47d1871a..461007cdcd8 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.runtime.Source; * IR representation for a runtime call. * */ -public class RuntimeNode extends Node implements TypeOverride { +public class RuntimeNode extends Node implements TypeOverride { /** * Request enum used for meta-information about the runtime request @@ -393,8 +393,9 @@ public class RuntimeNode extends Node implements TypeOverride { } @Override - public void setType(final Type type) { + public RuntimeNode setType(final Type type) { this.callSiteType = type; + return this; } @Override @@ -408,12 +409,12 @@ public class RuntimeNode extends Node implements TypeOverride { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterRuntimeNode(this) != null) { for (int i = 0, count = args.size(); i < count; i++) { args.set(i, args.get(i).accept(visitor)); } - return visitor.leave(this); + return visitor.leaveRuntimeNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java index c09a4f025a6..b751cdcbec0 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java @@ -108,10 +108,10 @@ public class SplitNode extends Node { visitor.setCurrentMethodEmitter(getMethodEmitter()); try { - if (visitor.enter(this) != null) { + if (visitor.enterSplitNode(this) != null) { body = body.accept(visitor); - return visitor.leave(this); + return visitor.leaveSplitNode(this); } } finally { visitor.setCurrentCompileUnit(saveCompileUnit); diff --git a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java index 068398ee375..23d9c7eaee7 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java @@ -85,7 +85,7 @@ public class SwitchNode extends BreakableNode { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterSwitchNode(this) != null) { expression = expression.accept(visitor); for (int i = 0, count = cases.size(); i < count; i++) { @@ -94,7 +94,7 @@ public class SwitchNode extends BreakableNode { //the default case is in the cases list and should not be explicitly traversed! - return visitor.leave(this); + return visitor.leaveSwitchNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java index a58a7c14961..603b8b08329 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java @@ -38,31 +38,31 @@ import jdk.nashorn.internal.runtime.options.Options; */ public final class Symbol implements Comparable { - /** Symbol flags. Kind ordered by precedence. */ - public static final int IS_TEMP = 0b0000_0001; + /** Symbol kinds. Kind ordered by precedence. */ + public static final int IS_TEMP = 1; /** Is this Global */ - public static final int IS_GLOBAL = 0b0000_0010; + public static final int IS_GLOBAL = 2; /** Is this a variable */ - public static final int IS_VAR = 0b0000_0011; + public static final int IS_VAR = 3; /** Is this a parameter */ - public static final int IS_PARAM = 0b0000_0100; + public static final int IS_PARAM = 4; /** Is this a constant */ - public static final int IS_CONSTANT = 0b0000_0101; - - static final int KINDMASK = 0b0000_1111; + public static final int IS_CONSTANT = 5; + /** Mask for kind flags */ + public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits /** Is this scope */ - public static final int IS_SCOPE = 0b0000_0001_0000; + public static final int IS_SCOPE = 1 << 4; /** Is this a this symbol */ - public static final int IS_THIS = 0b0000_0010_0000; + public static final int IS_THIS = 1 << 5; /** Can this symbol ever be undefined */ - public static final int CAN_BE_UNDEFINED = 0b0000_0100_0000; + public static final int CAN_BE_UNDEFINED = 1 << 6; /** Can this symbol ever have primitive types */ - public static final int CAN_BE_PRIMITIVE = 0b0000_1000_0000; + public static final int CAN_BE_PRIMITIVE = 1 << 7; /** Is this a let */ - public static final int IS_LET = 0b0001_0000_0000; + public static final int IS_LET = 1 << 8; /** Is this an internal symbol, never represented explicitly in source code */ - public static final int IS_INTERNAL = 0b0010_0000_0000; + public static final int IS_INTERNAL = 1 << 9; /** Null or name identifying symbol. */ private final String name; @@ -269,15 +269,6 @@ public final class Symbol implements Comparable { return type.isCategory2() ? 2 : 1; } - /** - * Return the defining function (scope.) - * - * @return Defining function. - */ - public FunctionNode findFunction() { - return block != null ? block.getFunction() : null; - } - @Override public boolean equals(final Object other) { if (!(other instanceof Symbol)) { @@ -486,27 +477,6 @@ public final class Symbol implements Comparable { flags |= IS_LET; } - /** - * Check if this symbol can be accessed directly with a putfield or getfield or dynamic load - * - * @param currentFunction function to check for fast scope - * @return true if fast scope - */ - public boolean isFastScope(final FunctionNode currentFunction) { - if (!isScope() || !block.needsScope()) { - return false; - } - // Allow fast scope access if no parent function contains with or eval - FunctionNode func = currentFunction; - while (func != null) { - if (func.hasWith() || func.hasEval()) { - return false; - } - func = func.findParentFunction(); - } - return true; - } - /** * Get the block in which the symbol is defined * @return a block @@ -651,7 +621,7 @@ public final class Symbol implements Comparable { * @return true if this this is a global scope symbol */ public boolean isTopLevel() { - return block instanceof FunctionNode && ((FunctionNode) block).isScript(); + return block instanceof FunctionNode && ((FunctionNode) block).isProgram(); } diff --git a/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java index a82991f9ab9..de333851d95 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java @@ -77,11 +77,11 @@ public class TernaryNode extends BinaryNode { @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - lhs = lhs.accept(visitor); - rhs = rhs.accept(visitor); - third = third.accept(visitor); - return visitor.leave(this); + if (visitor.enterTernaryNode(this) != null) { + final Node newLhs = lhs().accept(visitor); + final Node newRhs = rhs().accept(visitor); + final Node newThird = third.accept(visitor); + return visitor.leaveTernaryNode((TernaryNode)setThird(newThird).setLHS(newLhs).setRHS(newRhs)); } return this; @@ -133,8 +133,12 @@ public class TernaryNode extends BinaryNode { /** * Reset the "third" node for this ternary expression, i.e. "z" in x ? y : z * @param third a node + * @return a node equivalent to this one except for the requested change. */ - public void setThird(final Node third) { - this.third = third; + public TernaryNode setThird(final Node third) { + if(this.third == third) return this; + final TernaryNode n = (TernaryNode)clone(); + n.third = third; + return n; } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java index efa63d962be..ab6d59e2969 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java @@ -75,9 +75,9 @@ public class ThrowNode extends Node { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterThrowNode(this) != null) { setExpression(expression.accept(visitor)); - return visitor.leave(this); + return visitor.leaveThrowNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java index b6aa439d4ed..7d3864bc0a2 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java @@ -101,7 +101,7 @@ public class TryNode extends Node { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterTryNode(this) != null) { // Need to do first for termination analysis. if (finallyBody != null) { finallyBody = (Block)finallyBody.accept(visitor); @@ -115,7 +115,7 @@ public class TryNode extends Node { } this.catchBlocks = newCatchBlocks; - return visitor.leave(this); + return visitor.leaveTryNode(this); } return this; @@ -154,6 +154,15 @@ public class TryNode extends Node { return catches; } + /** + * Returns true if the specified block is the body of this try block, or any of its catch blocks. + * @param block the block + * @return true if the specified block is the body of this try block, or any of its catch blocks. + */ + public boolean isChildBlock(Block block) { + return body == block || catchBlocks.contains(block); + } + /** * Get the catch blocks for this try block * @return a list of blocks diff --git a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java index 8321318a5ef..61c1fe20a3f 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java +++ b/nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java @@ -36,15 +36,17 @@ import jdk.nashorn.internal.codegen.types.Type; * 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 { +public interface TypeOverride { /** * Set the override type * * @param type the type + * @return a node equivalent to this one except for the requested change. */ - public void setType(final Type type); + public T setType(final Type type); /** * Returns true if this node can have a callsite override, e.g. all scope ident nodes diff --git a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java index 491151fa296..d823c0583fa 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java @@ -41,7 +41,7 @@ import jdk.nashorn.internal.runtime.Source; */ public class UnaryNode extends Node implements Assignment { /** Right hand side argument. */ - protected Node rhs; + private Node rhs; /** * Constructor @@ -103,6 +103,11 @@ public class UnaryNode extends Node implements Assignment { return isAssignment() ? rhs() : null; } + @Override + public Node setAssignmentDest(Node n) { + return setRHS(n); + } + @Override public Node getAssignmentSource() { return getAssignmentDest(); @@ -132,9 +137,8 @@ public class UnaryNode extends Node implements Assignment { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - rhs = rhs.accept(visitor); - return visitor.leave(this); + if (visitor.enterUnaryNode(this) != null) { + return visitor.leaveUnaryNode(setRHS(rhs.accept(visitor))); } return this; @@ -212,10 +216,12 @@ public class UnaryNode extends Node implements Assignment { * @see BinaryNode * * @param rhs right hand side or expression node + * @return a node equivalent to this one except for the requested change. */ - public void setRHS(final Node rhs) { - this.rhs = rhs; + public UnaryNode setRHS(final Node rhs) { + if(this.rhs == rhs) return this; + final UnaryNode n = (UnaryNode)clone(); + n.rhs = rhs; + return n; } - - } diff --git a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java index 07b6f8eca50..b719c99dab5 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/VarNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/VarNode.java @@ -38,8 +38,8 @@ public class VarNode extends Node implements Assignment { /** Initialization expression. */ private Node init; - /** Is this a function var node */ - private boolean isFunctionVarNode; + /** Is this a var statement (as opposed to a "var" in a for loop statement) */ + private final boolean isStatement; /** * Constructor @@ -51,20 +51,34 @@ public class VarNode extends Node implements Assignment { * @param init init node or null if just a declaration */ public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init) { + this(source, token, finish, name, init, true); + } + + /** + * Constructor + * + * @param source the source + * @param token token + * @param finish finish + * @param name name of variable + * @param init init node or null if just a declaration + * @param isStatement if this is a var statement (true), or a for-loop initializer (false) + */ + public VarNode(final Source source, final long token, final int finish, final IdentNode name, final Node init, boolean isStatement) { super(source, token, finish); - this.name = name; + this.name = init == null ? name : name.setIsInitializedHere(); this.init = init; - if (init != null) { - this.name.setIsInitializedHere(); - } + this.isStatement = isStatement; } + private VarNode(final VarNode varNode, final CopyState cs) { super(varNode); this.name = (IdentNode)cs.existingOrCopy(varNode.name); this.init = cs.existingOrCopy(varNode.init); + this.isStatement = varNode.isStatement; } @Override @@ -82,6 +96,11 @@ public class VarNode extends Node implements Assignment { return isAssignment() ? name : null; } + @Override + public Node setAssignmentDest(IdentNode n) { + return setName(n); + } + @Override public Node getAssignmentSource() { return isAssignment() ? getInit() : null; @@ -127,16 +146,19 @@ public class VarNode extends Node implements Assignment { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { - name = (IdentNode)name.accept(visitor); - - if (init != null) { - init = init.accept(visitor); + if (visitor.enterVarNode(this) != null) { + final IdentNode newName = (IdentNode)name.accept(visitor); + final Node newInit = init == null ? null : init.accept(visitor); + final VarNode newThis; + if(name != newName || init != newInit) { + newThis = (VarNode)clone(); + newThis.init = newInit; + newThis.name = newInit == null ? newName : newName.setIsInitializedHere(); + } else { + newThis = this; } - - return visitor.leave(this); + return visitor.leaveVarNode(newThis); } - return this; } @@ -162,9 +184,13 @@ public class VarNode extends Node implements Assignment { /** * Reset the initialization expression * @param init new initialization expression + * @return a node equivalent to this one except for the requested change. */ - public void setInit(final Node init) { - this.init = init; + public VarNode setInit(final Node init) { + if(this.init == init) return this; + final VarNode n = (VarNode)clone(); + n.init = init; + return n; } /** @@ -179,30 +205,26 @@ public class VarNode extends Node implements Assignment { * Reset the identifier for this VarNode * @param name new IdentNode representing the variable being set or declared */ - public void setName(final IdentNode name) { - this.name = name; + private VarNode setName(final IdentNode name) { + if(this.name == name) return this; + final VarNode n = (VarNode)clone(); + n.name = name; + return n; } /** - * Check if this is a virtual assignment of a function node. Function nodes declared - * with a name are hoisted to the top of the scope and appear as symbols too. This is - * implemented by representing them as virtual VarNode assignments added to the code - * during lowering - * - * @see FunctionNode - * - * @return true if this is a virtual function declaration + * Returns true if this is a var statement (as opposed to a var initializer in a for loop). + * @return true if this is a var statement (as opposed to a var initializer in a for loop). */ - public boolean isFunctionVarNode() { - return isFunctionVarNode; + public boolean isStatement() { + return isStatement; } /** - * Flag this var node as a virtual function var node assignment as described in - * {@link VarNode#isFunctionVarNode()} + * Returns true if this is a function declaration. + * @return true if this is a function declaration. */ - public void setIsFunctionVarNode() { - this.isFunctionVarNode = true; + public boolean isFunctionDeclaration() { + return init instanceof FunctionNode && ((FunctionNode)init).isDeclared(); } - } diff --git a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java index c51659b855b..8db31c088ff 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java @@ -88,11 +88,11 @@ public class WhileNode extends BreakableNode { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterWhileNode(this) != null) { test = test.accept(visitor); body = (Block)body.accept(visitor); - return visitor.leave(this); + return visitor.leaveWhileNode(this); } return this; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java index 52f4e9b57c1..f5ad3b1379a 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java @@ -73,10 +73,10 @@ public class WithNode extends Node { */ @Override public Node accept(final NodeVisitor visitor) { - if (visitor.enter(this) != null) { + if (visitor.enterWithNode(this) != null) { expression = expression.accept(visitor); body = (Block)body.accept(visitor); - return visitor.leave(this); + return visitor.leaveWithNode(this); } return this; diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index 68fb68b024b..a8c3c4a420c 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -112,7 +112,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { enterDefault(accessNode); type("MemberExpression"); @@ -132,7 +132,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { enterDefault(block); type("BlockStatement"); @@ -154,7 +154,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final BinaryNode binaryNode) { + public Node enterBinaryNode(final BinaryNode binaryNode) { enterDefault(binaryNode); final String name; @@ -183,7 +183,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { enterDefault(breakNode); type("BreakStatement"); @@ -201,7 +201,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { enterDefault(callNode); type("CallExpression"); @@ -217,7 +217,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final CaseNode caseNode) { + public Node enterCaseNode(final CaseNode caseNode) { enterDefault(caseNode); type("SwitchCase"); @@ -238,7 +238,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final CatchNode catchNode) { + public Node enterCatchNode(final CatchNode catchNode) { enterDefault(catchNode); type("CatchClause"); @@ -264,7 +264,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { enterDefault(continueNode); type("ContinueStatement"); @@ -282,7 +282,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final DoWhileNode doWhileNode) { + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { enterDefault(doWhileNode); type("DoWhileStatement"); @@ -299,7 +299,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final EmptyNode emptyNode) { + public Node enterEmptyNode(final EmptyNode emptyNode) { enterDefault(emptyNode); type("EmptyStatement"); @@ -308,7 +308,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ExecuteNode executeNode) { + public Node enterExecuteNode(final ExecuteNode executeNode) { enterDefault(executeNode); type("ExpressionStatement"); @@ -321,7 +321,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { enterDefault(forNode); if (forNode.isForIn() || (forNode.isForEach() && forNode.getInit() != null)) { @@ -384,14 +384,14 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { enterDefault(functionNode); - final boolean program = functionNode.isScript(); + final boolean program = functionNode.isProgram(); final String name; if (program) { name = "Program"; - } else if (functionNode.isStatement()) { + } else if (functionNode.isDeclared()) { name = "FunctionDeclaration"; } else { name = "FunctionExpression"; @@ -419,20 +419,11 @@ public final class JSONWriter extends NodeVisitor { } // body consists of nested functions and statements - final List funcs = functionNode.getFunctions(); final List stats = functionNode.getStatements(); - final int size = stats.size() + funcs.size(); + final int size = stats.size(); int idx = 0; arrayStart("body"); - for (final Node func : funcs) { - func.accept(this); - if (idx != (size - 1)) { - comma(); - } - idx++; - } - for (final Node stat : stats) { if (! stat.isDebug()) { stat.accept(this); @@ -448,7 +439,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { enterDefault(identNode); final String name = identNode.getName(); @@ -464,7 +455,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final IfNode ifNode) { + public Node enterIfNode(final IfNode ifNode) { enterDefault(ifNode); type("IfStatement"); @@ -490,7 +481,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final IndexNode indexNode) { + public Node enterIndexNode(final IndexNode indexNode) { enterDefault(indexNode); type("MemberExpression"); @@ -510,7 +501,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final LabelNode labelNode) { + public Node enterLabelNode(final LabelNode labelNode) { enterDefault(labelNode); type("LabeledStatement"); @@ -527,13 +518,13 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final LineNumberNode lineNumberNode) { + public Node enterLineNumberNode(final LineNumberNode lineNumberNode) { return null; } @SuppressWarnings("rawtypes") @Override - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { enterDefault(literalNode); if (literalNode instanceof LiteralNode.ArrayLiteralNode) { @@ -569,7 +560,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ObjectNode objectNode) { + public Node enterObjectNode(final ObjectNode objectNode) { enterDefault(objectNode); type("ObjectExpression"); @@ -581,7 +572,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final PropertyNode propertyNode) { + public Node enterPropertyNode(final PropertyNode propertyNode) { final Node key = propertyNode.getKey(); final Node value = propertyNode.getValue(); @@ -647,7 +638,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { enterDefault(returnNode); type("ReturnStatement"); @@ -665,7 +656,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final RuntimeNode runtimeNode) { + public Node enterRuntimeNode(final RuntimeNode runtimeNode) { final RuntimeNode.Request req = runtimeNode.getRequest(); if (req == RuntimeNode.Request.DEBUGGER) { @@ -680,12 +671,12 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { return null; } @Override - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { enterDefault(switchNode); type("SwitchStatement"); @@ -701,7 +692,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final TernaryNode ternaryNode) { + public Node enterTernaryNode(final TernaryNode ternaryNode) { enterDefault(ternaryNode); type("ConditionalExpression"); @@ -722,7 +713,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final ThrowNode throwNode) { + public Node enterThrowNode(final ThrowNode throwNode) { enterDefault(throwNode); type("ThrowStatement"); @@ -735,7 +726,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final TryNode tryNode) { + public Node enterTryNode(final TryNode tryNode) { enterDefault(tryNode); type("TryStatement"); @@ -760,7 +751,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final UnaryNode unaryNode) { + public Node enterUnaryNode(final UnaryNode unaryNode) { enterDefault(unaryNode); final TokenType tokenType = unaryNode.tokenType(); @@ -816,7 +807,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final VarNode varNode) { + public Node enterVarNode(final VarNode varNode) { enterDefault(varNode); type("VariableDeclaration"); @@ -852,7 +843,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { enterDefault(whileNode); type("WhileStatement"); @@ -869,7 +860,7 @@ public final class JSONWriter extends NodeVisitor { } @Override - public Node enter(final WithNode withNode) { + public Node enterWithNode(final WithNode withNode) { enterDefault(withNode); type("WithStatement"); diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java index 11b8dbd54ed..d2f40d1ae95 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java @@ -42,7 +42,6 @@ import jdk.nashorn.internal.ir.IndexNode; import jdk.nashorn.internal.ir.LabelNode; import jdk.nashorn.internal.ir.LineNumberNode; import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.SplitNode; @@ -138,13 +137,13 @@ public final class PrintVisitor extends NodeVisitor { * Visits. */ @Override - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { accessNode.toString(sb); return null; } @Override - public Node enter(final Block block) { + public Node enterBlock(final Block block) { sb.append(' '); sb.append('{'); @@ -152,21 +151,6 @@ public final class PrintVisitor extends NodeVisitor { final boolean isFunction = block instanceof FunctionNode; - if (isFunction) { - final FunctionNode function = (FunctionNode)block; - final List functions = function.getFunctions(); - - for (final FunctionNode f : functions) { - sb.append(EOLN); - indent(); - f.accept(this); - } - - if (!functions.isEmpty()) { - sb.append(EOLN); - } - } - final List statements = block.getStatements(); boolean lastLineNumber = false; @@ -224,25 +208,25 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { breakNode.toString(sb); return null; } @Override - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { callNode.toString(sb); return null; } @Override - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { continueNode.toString(sb); return null; } @Override - public Node enter(final DoWhileNode doWhileNode) { + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { sb.append("do"); doWhileNode.getBody().accept(this); sb.append(' '); @@ -252,7 +236,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final ExecuteNode executeNode) { + public Node enterExecuteNode(final ExecuteNode executeNode) { final Node expression = executeNode.getExpression(); if (expression instanceof UnaryNode) { @@ -265,7 +249,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { forNode.toString(sb); forNode.getBody().accept(this); @@ -273,15 +257,15 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { functionNode.toString(sb); - enter((Block)functionNode); + enterBlock(functionNode); return null; } @Override - public Node enter(final IfNode ifNode) { + public Node enterIfNode(final IfNode ifNode) { ifNode.toString(sb); ifNode.getPass().accept(this); @@ -296,13 +280,13 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final IndexNode indexNode) { + public Node enterIndexNode(final IndexNode indexNode) { indexNode.toString(sb); return null; } @Override - public Node enter(final LabelNode labeledNode) { + public Node enterLabelNode(final LabelNode labeledNode) { indent -= TABWIDTH; indent(); indent += TABWIDTH; @@ -313,7 +297,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final LineNumberNode lineNumberNode) { + public Node enterLineNumberNode(final LineNumberNode lineNumberNode) { if (printLineNumbers) { lineNumberNode.toString(sb); } @@ -323,25 +307,19 @@ public final class PrintVisitor extends NodeVisitor { @Override - public Node enter(final ReferenceNode referenceNode) { - referenceNode.toString(sb); - return null; - } - - @Override - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { returnNode.toString(sb); return null; } @Override - public Node enter(final RuntimeNode runtimeNode) { + public Node enterRuntimeNode(final RuntimeNode runtimeNode) { runtimeNode.toString(sb); return null; } @Override - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { splitNode.toString(sb); sb.append(EOLN); indent += TABWIDTH; @@ -350,7 +328,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node leave(final SplitNode splitNode) { + public Node leaveSplitNode(final SplitNode splitNode) { sb.append(""); sb.append(EOLN); indent -= TABWIDTH; @@ -359,7 +337,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { switchNode.toString(sb); sb.append(" {"); @@ -383,13 +361,13 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final ThrowNode throwNode) { + public Node enterThrowNode(final ThrowNode throwNode) { throwNode.toString(sb); return null; } @Override - public Node enter(final TryNode tryNode) { + public Node enterTryNode(final TryNode tryNode) { tryNode.toString(sb); tryNode.getBody().accept(this); @@ -412,13 +390,19 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final VarNode varNode) { - varNode.toString(sb); + public Node enterVarNode(final VarNode varNode) { + sb.append("var "); + varNode.getName().toString(sb); + final Node init = varNode.getInit(); + if(init != null) { + sb.append(" = "); + init.accept(this); + } return null; } @Override - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { whileNode.toString(sb); whileNode.getBody().accept(this); @@ -426,7 +410,7 @@ public final class PrintVisitor extends NodeVisitor { } @Override - public Node enter(final WithNode withNode) { + public Node enterWithNode(final WithNode withNode) { withNode.toString(sb); withNode.getBody().accept(this); diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java index 6856282e069..0021b7d2dfe 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java +++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java @@ -53,7 +53,7 @@ public class NodeOperatorVisitor extends NodeVisitor { } @Override - public final Node enter(final UnaryNode unaryNode) { + public final Node enterUnaryNode(final UnaryNode unaryNode) { switch (unaryNode.tokenType()) { case ADD: return enterADD(unaryNode); @@ -81,12 +81,12 @@ public class NodeOperatorVisitor extends NodeVisitor { case INCPOSTFIX: return enterDECINC(unaryNode); default: - return super.enter(unaryNode); + return super.enterUnaryNode(unaryNode); } } @Override - public final Node leave(final UnaryNode unaryNode) { + public final Node leaveUnaryNode(final UnaryNode unaryNode) { switch (unaryNode.tokenType()) { case ADD: return leaveADD(unaryNode); @@ -114,12 +114,12 @@ public class NodeOperatorVisitor extends NodeVisitor { case INCPOSTFIX: return leaveDECINC(unaryNode); default: - return super.leave(unaryNode); + return super.leaveUnaryNode(unaryNode); } } @Override - public final Node enter(final BinaryNode binaryNode) { + public final Node enterBinaryNode(final BinaryNode binaryNode) { switch (binaryNode.tokenType()) { case ADD: return enterADD(binaryNode); @@ -198,12 +198,12 @@ public class NodeOperatorVisitor extends NodeVisitor { case SUB: return enterSUB(binaryNode); default: - return super.enter(binaryNode); + return super.enterBinaryNode(binaryNode); } } @Override - public final Node leave(final BinaryNode binaryNode) { + public final Node leaveBinaryNode(final BinaryNode binaryNode) { switch (binaryNode.tokenType()) { case ADD: return leaveADD(binaryNode); @@ -282,7 +282,7 @@ public class NodeOperatorVisitor extends NodeVisitor { case SUB: return leaveSUB(binaryNode); default: - return super.leave(binaryNode); + return super.leaveBinaryNode(binaryNode); } } diff --git a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java index 9ce6fd02b3e..f10d8c036e6 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java +++ b/nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java @@ -49,7 +49,6 @@ import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.SplitNode; @@ -153,7 +152,7 @@ public abstract class NodeVisitor { * @param accessNode the node * @return processed node, null if traversal should end, null if traversal should end */ - public Node enter(final AccessNode accessNode) { + public Node enterAccessNode(final AccessNode accessNode) { return enterDefault(accessNode); } @@ -163,7 +162,7 @@ public abstract class NodeVisitor { * @param accessNode the node * @return processed node, null if traversal should end */ - public Node leave(final AccessNode accessNode) { + public Node leaveAccessNode(final AccessNode accessNode) { return leaveDefault(accessNode); } @@ -173,7 +172,7 @@ public abstract class NodeVisitor { * @param block the node * @return processed node, null if traversal should end */ - public Node enter(final Block block) { + public Node enterBlock(final Block block) { return enterDefault(block); } @@ -183,7 +182,7 @@ public abstract class NodeVisitor { * @param block the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final Block block) { + public Node leaveBlock(final Block block) { return leaveDefault(block); } @@ -193,7 +192,7 @@ public abstract class NodeVisitor { * @param binaryNode the node * @return processed node */ - public Node enter(final BinaryNode binaryNode) { + public Node enterBinaryNode(final BinaryNode binaryNode) { return enterDefault(binaryNode); } @@ -203,7 +202,7 @@ public abstract class NodeVisitor { * @param binaryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final BinaryNode binaryNode) { + public Node leaveBinaryNode(final BinaryNode binaryNode) { return leaveDefault(binaryNode); } @@ -213,7 +212,7 @@ public abstract class NodeVisitor { * @param breakNode the node * @return processed node, null if traversal should end */ - public Node enter(final BreakNode breakNode) { + public Node enterBreakNode(final BreakNode breakNode) { return enterDefault(breakNode); } @@ -223,7 +222,7 @@ public abstract class NodeVisitor { * @param breakNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final BreakNode breakNode) { + public Node leaveBreakNode(final BreakNode breakNode) { return leaveDefault(breakNode); } @@ -233,7 +232,7 @@ public abstract class NodeVisitor { * @param callNode the node * @return processed node, null if traversal should end */ - public Node enter(final CallNode callNode) { + public Node enterCallNode(final CallNode callNode) { return enterDefault(callNode); } @@ -243,7 +242,7 @@ public abstract class NodeVisitor { * @param callNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final CallNode callNode) { + public Node leaveCallNode(final CallNode callNode) { return leaveDefault(callNode); } @@ -253,7 +252,7 @@ public abstract class NodeVisitor { * @param caseNode the node * @return processed node, null if traversal should end */ - public Node enter(final CaseNode caseNode) { + public Node enterCaseNode(final CaseNode caseNode) { return enterDefault(caseNode); } @@ -263,7 +262,7 @@ public abstract class NodeVisitor { * @param caseNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final CaseNode caseNode) { + public Node leaveCaseNode(final CaseNode caseNode) { return leaveDefault(caseNode); } @@ -273,7 +272,7 @@ public abstract class NodeVisitor { * @param catchNode the node * @return processed node, null if traversal should end */ - public Node enter(final CatchNode catchNode) { + public Node enterCatchNode(final CatchNode catchNode) { return enterDefault(catchNode); } @@ -283,7 +282,7 @@ public abstract class NodeVisitor { * @param catchNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final CatchNode catchNode) { + public Node leaveCatchNode(final CatchNode catchNode) { return leaveDefault(catchNode); } @@ -293,7 +292,7 @@ public abstract class NodeVisitor { * @param continueNode the node * @return processed node, null if traversal should end */ - public Node enter(final ContinueNode continueNode) { + public Node enterContinueNode(final ContinueNode continueNode) { return enterDefault(continueNode); } @@ -303,7 +302,7 @@ public abstract class NodeVisitor { * @param continueNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ContinueNode continueNode) { + public Node leaveContinueNode(final ContinueNode continueNode) { return leaveDefault(continueNode); } @@ -313,7 +312,7 @@ public abstract class NodeVisitor { * @param doWhileNode the node * @return processed node */ - public Node enter(final DoWhileNode doWhileNode) { + public Node enterDoWhileNode(final DoWhileNode doWhileNode) { return enterDefault(doWhileNode); } @@ -323,7 +322,7 @@ public abstract class NodeVisitor { * @param doWhileNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final DoWhileNode doWhileNode) { + public Node leaveDoWhileNode(final DoWhileNode doWhileNode) { return leaveDefault(doWhileNode); } @@ -333,7 +332,7 @@ public abstract class NodeVisitor { * @param emptyNode the node * @return processed node */ - public Node enter(final EmptyNode emptyNode) { + public Node enterEmptyNode(final EmptyNode emptyNode) { return enterDefault(emptyNode); } @@ -343,7 +342,7 @@ public abstract class NodeVisitor { * @param emptyNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final EmptyNode emptyNode) { + public Node leaveEmptyNode(final EmptyNode emptyNode) { return leaveDefault(emptyNode); } @@ -353,7 +352,7 @@ public abstract class NodeVisitor { * @param executeNode the node * @return processed node, null if traversal should end */ - public Node enter(final ExecuteNode executeNode) { + public Node enterExecuteNode(final ExecuteNode executeNode) { return enterDefault(executeNode); } @@ -363,7 +362,7 @@ public abstract class NodeVisitor { * @param executeNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ExecuteNode executeNode) { + public Node leaveExecuteNode(final ExecuteNode executeNode) { return leaveDefault(executeNode); } @@ -373,7 +372,7 @@ public abstract class NodeVisitor { * @param forNode the node * @return processed node, null if traversal should end */ - public Node enter(final ForNode forNode) { + public Node enterForNode(final ForNode forNode) { return enterDefault(forNode); } @@ -383,7 +382,7 @@ public abstract class NodeVisitor { * @param forNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ForNode forNode) { + public Node leaveForNode(final ForNode forNode) { return leaveDefault(forNode); } @@ -393,7 +392,7 @@ public abstract class NodeVisitor { * @param functionNode the node * @return processed node */ - public Node enter(final FunctionNode functionNode) { + public Node enterFunctionNode(final FunctionNode functionNode) { return enterDefault(functionNode); } @@ -403,7 +402,7 @@ public abstract class NodeVisitor { * @param functionNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final FunctionNode functionNode) { + public Node leaveFunctionNode(final FunctionNode functionNode) { return leaveDefault(functionNode); } @@ -413,7 +412,7 @@ public abstract class NodeVisitor { * @param identNode the node * @return processed node, null if traversal should end */ - public Node enter(final IdentNode identNode) { + public Node enterIdentNode(final IdentNode identNode) { return enterDefault(identNode); } @@ -423,7 +422,7 @@ public abstract class NodeVisitor { * @param identNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final IdentNode identNode) { + public Node leaveIdentNode(final IdentNode identNode) { return leaveDefault(identNode); } @@ -433,7 +432,7 @@ public abstract class NodeVisitor { * @param ifNode the node * @return processed node, null if traversal should end */ - public Node enter(final IfNode ifNode) { + public Node enterIfNode(final IfNode ifNode) { return enterDefault(ifNode); } @@ -443,7 +442,7 @@ public abstract class NodeVisitor { * @param ifNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final IfNode ifNode) { + public Node leaveIfNode(final IfNode ifNode) { return leaveDefault(ifNode); } @@ -453,7 +452,7 @@ public abstract class NodeVisitor { * @param indexNode the node * @return processed node, null if traversal should end */ - public Node enter(final IndexNode indexNode) { + public Node enterIndexNode(final IndexNode indexNode) { return enterDefault(indexNode); } @@ -463,7 +462,7 @@ public abstract class NodeVisitor { * @param indexNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final IndexNode indexNode) { + public Node leaveIndexNode(final IndexNode indexNode) { return leaveDefault(indexNode); } @@ -473,7 +472,7 @@ public abstract class NodeVisitor { * @param labelNode the node * @return processed node, null if traversal should end */ - public Node enter(final LabelNode labelNode) { + public Node enterLabelNode(final LabelNode labelNode) { return enterDefault(labelNode); } @@ -483,7 +482,7 @@ public abstract class NodeVisitor { * @param labelNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final LabelNode labelNode) { + public Node leaveLabelNode(final LabelNode labelNode) { return leaveDefault(labelNode); } @@ -493,7 +492,7 @@ public abstract class NodeVisitor { * @param lineNumberNode the node * @return processed node, null if traversal should end */ - public Node enter(final LineNumberNode lineNumberNode) { + public Node enterLineNumberNode(final LineNumberNode lineNumberNode) { return enterDefault(lineNumberNode); } @@ -503,7 +502,7 @@ public abstract class NodeVisitor { * @param lineNumberNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final LineNumberNode lineNumberNode) { + public Node leaveLineNumberNode(final LineNumberNode lineNumberNode) { return leaveDefault(lineNumberNode); } @@ -513,8 +512,7 @@ public abstract class NodeVisitor { * @param literalNode the node * @return processed node */ - @SuppressWarnings("rawtypes") - public Node enter(final LiteralNode literalNode) { + public Node enterLiteralNode(final LiteralNode literalNode) { return enterDefault(literalNode); } @@ -524,8 +522,7 @@ public abstract class NodeVisitor { * @param literalNode the node * @return processed node, which will replace the original one, or the original node */ - @SuppressWarnings("rawtypes") - public Node leave(final LiteralNode literalNode) { + public Node leaveLiteralNode(final LiteralNode literalNode) { return leaveDefault(literalNode); } @@ -535,7 +532,7 @@ public abstract class NodeVisitor { * @param objectNode the node * @return processed node */ - public Node enter(final ObjectNode objectNode) { + public Node enterObjectNode(final ObjectNode objectNode) { return enterDefault(objectNode); } @@ -545,7 +542,7 @@ public abstract class NodeVisitor { * @param objectNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ObjectNode objectNode) { + public Node leaveObjectNode(final ObjectNode objectNode) { return leaveDefault(objectNode); } @@ -555,7 +552,7 @@ public abstract class NodeVisitor { * @param propertyNode the node * @return processed node, null if traversal should end */ - public Node enter(final PropertyNode propertyNode) { + public Node enterPropertyNode(final PropertyNode propertyNode) { return enterDefault(propertyNode); } @@ -565,37 +562,17 @@ public abstract class NodeVisitor { * @param propertyNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final PropertyNode propertyNode) { + public Node leavePropertyNode(final PropertyNode propertyNode) { return leaveDefault(propertyNode); } - /** - * Callback for entering a ReferenceNode - * - * @param referenceNode the node - * @return processed node, null if traversal should end - */ - public Node enter(final ReferenceNode referenceNode) { - return enterDefault(referenceNode); - } - - /** - * Callback for leaving a ReferenceNode - * - * @param referenceNode the node - * @return processed node, which will replace the original one, or the original node - */ - public Node leave(final ReferenceNode referenceNode) { - return leaveDefault(referenceNode); - } - /** * Callback for entering a ReturnNode * * @param returnNode the node * @return processed node, null if traversal should end */ - public Node enter(final ReturnNode returnNode) { + public Node enterReturnNode(final ReturnNode returnNode) { return enterDefault(returnNode); } @@ -605,7 +582,7 @@ public abstract class NodeVisitor { * @param returnNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ReturnNode returnNode) { + public Node leaveReturnNode(final ReturnNode returnNode) { return leaveDefault(returnNode); } @@ -615,7 +592,7 @@ public abstract class NodeVisitor { * @param runtimeNode the node * @return processed node, null if traversal should end */ - public Node enter(final RuntimeNode runtimeNode) { + public Node enterRuntimeNode(final RuntimeNode runtimeNode) { return enterDefault(runtimeNode); } @@ -625,7 +602,7 @@ public abstract class NodeVisitor { * @param runtimeNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final RuntimeNode runtimeNode) { + public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { return leaveDefault(runtimeNode); } @@ -635,7 +612,7 @@ public abstract class NodeVisitor { * @param splitNode the node * @return processed node, null if traversal should end */ - public Node enter(final SplitNode splitNode) { + public Node enterSplitNode(final SplitNode splitNode) { return enterDefault(splitNode); } @@ -645,7 +622,7 @@ public abstract class NodeVisitor { * @param splitNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final SplitNode splitNode) { + public Node leaveSplitNode(final SplitNode splitNode) { return leaveDefault(splitNode); } @@ -655,7 +632,7 @@ public abstract class NodeVisitor { * @param switchNode the node * @return processed node, null if traversal should end */ - public Node enter(final SwitchNode switchNode) { + public Node enterSwitchNode(final SwitchNode switchNode) { return enterDefault(switchNode); } @@ -665,7 +642,7 @@ public abstract class NodeVisitor { * @param switchNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final SwitchNode switchNode) { + public Node leaveSwitchNode(final SwitchNode switchNode) { return leaveDefault(switchNode); } @@ -675,7 +652,7 @@ public abstract class NodeVisitor { * @param ternaryNode the node * @return processed node, null if traversal should end */ - public Node enter(final TernaryNode ternaryNode) { + public Node enterTernaryNode(final TernaryNode ternaryNode) { return enterDefault(ternaryNode); } @@ -685,7 +662,7 @@ public abstract class NodeVisitor { * @param ternaryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final TernaryNode ternaryNode) { + public Node leaveTernaryNode(final TernaryNode ternaryNode) { return leaveDefault(ternaryNode); } @@ -695,7 +672,7 @@ public abstract class NodeVisitor { * @param throwNode the node * @return processed node, null if traversal should end */ - public Node enter(final ThrowNode throwNode) { + public Node enterThrowNode(final ThrowNode throwNode) { return enterDefault(throwNode); } @@ -705,7 +682,7 @@ public abstract class NodeVisitor { * @param throwNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final ThrowNode throwNode) { + public Node leaveThrowNode(final ThrowNode throwNode) { return leaveDefault(throwNode); } @@ -715,7 +692,7 @@ public abstract class NodeVisitor { * @param tryNode the node * @return processed node, null if traversal should end */ - public Node enter(final TryNode tryNode) { + public Node enterTryNode(final TryNode tryNode) { return enterDefault(tryNode); } @@ -725,7 +702,7 @@ public abstract class NodeVisitor { * @param tryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final TryNode tryNode) { + public Node leaveTryNode(final TryNode tryNode) { return leaveDefault(tryNode); } @@ -735,7 +712,7 @@ public abstract class NodeVisitor { * @param unaryNode the node * @return processed node, null if traversal should end */ - public Node enter(final UnaryNode unaryNode) { + public Node enterUnaryNode(final UnaryNode unaryNode) { return enterDefault(unaryNode); } @@ -745,7 +722,7 @@ public abstract class NodeVisitor { * @param unaryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final UnaryNode unaryNode) { + public Node leaveUnaryNode(final UnaryNode unaryNode) { return leaveDefault(unaryNode); } @@ -755,7 +732,7 @@ public abstract class NodeVisitor { * @param varNode the node * @return processed node, null if traversal should end */ - public Node enter(final VarNode varNode) { + public Node enterVarNode(final VarNode varNode) { return enterDefault(varNode); } @@ -765,7 +742,7 @@ public abstract class NodeVisitor { * @param varNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final VarNode varNode) { + public Node leaveVarNode(final VarNode varNode) { return leaveDefault(varNode); } @@ -775,7 +752,7 @@ public abstract class NodeVisitor { * @param whileNode the node * @return processed node, null if traversal should end */ - public Node enter(final WhileNode whileNode) { + public Node enterWhileNode(final WhileNode whileNode) { return enterDefault(whileNode); } @@ -785,7 +762,7 @@ public abstract class NodeVisitor { * @param whileNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final WhileNode whileNode) { + public Node leaveWhileNode(final WhileNode whileNode) { return leaveDefault(whileNode); } @@ -795,7 +772,7 @@ public abstract class NodeVisitor { * @param withNode the node * @return processed node, null if traversal should end */ - public Node enter(final WithNode withNode) { + public Node enterWithNode(final WithNode withNode) { return enterDefault(withNode); } @@ -805,7 +782,7 @@ public abstract class NodeVisitor { * @param withNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leave(final WithNode withNode) { + public Node leaveWithNode(final WithNode withNode) { return leaveDefault(withNode); } diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index 166fed91f9e..b810043ebba 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -56,10 +56,10 @@ import static jdk.nashorn.internal.parser.TokenType.WHILE; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; - import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -76,17 +76,18 @@ import jdk.nashorn.internal.ir.EmptyNode; import jdk.nashorn.internal.ir.ExecuteNode; 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.LabelNode; +import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LineNumberNode; import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; import jdk.nashorn.internal.ir.PropertyKey; import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReferenceNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.SwitchNode; @@ -97,7 +98,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.FunctionNode.CompilationState; import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.JSErrorType; @@ -117,11 +117,8 @@ public class Parser extends AbstractParser { /** Is scripting mode. */ private final boolean scripting; - /** Current function being parsed. */ - private FunctionNode function; - - /** Current parsing block. */ - private Block block; + private final LexicalContext lexicalContext = new LexicalContext(); + private List functionDeclarations; /** Namespace for function names where not explicitly given */ private final Namespace namespace; @@ -277,7 +274,9 @@ loop: * @return New block. */ private Block newBlock() { - return block = new Block(source, token, Token.descPosition(token), block, function); + final Block block = new Block(source, token, Token.descPosition(token)); + lexicalContext.push(block); + return block; } /** @@ -290,19 +289,23 @@ loop: // Build function name. final StringBuilder sb = new StringBuilder(); - if (block != null) { - block.addParentName(sb); + final FunctionNode parentFunction = getFunction(); + if(parentFunction != null && !parentFunction.isProgram()) { + sb.append(parentFunction.getName()).append('$'); } sb.append(ident != null ? ident.getName() : FUNCTION_PREFIX.tag()); final String name = namespace.uniqueName(sb.toString()); - assert function != null || name.equals(RUN_SCRIPT.tag()) : "name = " + name;// must not rename runScript(). + assert parentFunction != null || name.equals(RUN_SCRIPT.tag()) : "name = " + name;// must not rename runScript(). // Start new block. - final FunctionNode functionBlock = new FunctionNode(source, token, Token.descPosition(token), namespace, block, ident, name); - block = function = functionBlock; - function.setStrictMode(isStrictMode); - function.setState(errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED); + final FunctionNode functionBlock = new FunctionNode(source, token, Token.descPosition(token), namespace, ident, name); + if(parentFunction == null) { + functionBlock.setProgram(); + } + functionBlock.setStrictMode(isStrictMode); + functionBlock.setState(errors.hasErrors() ? CompilationState.PARSE_ERROR : CompilationState.PARSED); + lexicalContext.push(functionBlock); return functionBlock; } @@ -310,9 +313,8 @@ loop: /** * Restore the current block. */ - private void restoreBlock() { - block = block.getParent(); - function = block.getFunction(); + private void restoreBlock(Block block) { + lexicalContext.pop(block); } /** @@ -322,19 +324,22 @@ loop: private Block getBlock(final boolean needsBraces) { // Set up new block. Captures LBRACE. final Block newBlock = newBlock(); - pushControlNode(newBlock); - - // Block opening brace. - if (needsBraces) { - expect(LBRACE); - } - try { - // Accumulate block statements. - statementList(); + pushControlNode(newBlock); + + // Block opening brace. + if (needsBraces) { + expect(LBRACE); + } + + try { + // Accumulate block statements. + statementList(); + } finally { + popControlNode(); + } } finally { - restoreBlock(); - popControlNode(); + restoreBlock(newBlock); } final int possibleEnd = Token.descPosition(token) + Token.descLength(token); @@ -364,7 +369,7 @@ loop: // Accumulate statements. statement(); } finally { - restoreBlock(); + restoreBlock(newBlock); } return newBlock; @@ -378,7 +383,10 @@ loop: final String name = ident.getName(); if (EVAL.tag().equals(name)) { - function.setHasEval(); + final Iterator it = lexicalContext.getFunctions(); + if(it.hasNext()) { + it.next().setHasEval(it); + } } } @@ -390,7 +398,7 @@ loop: final String name = ident.getName(); if (ARGUMENTS.tag().equals(name)) { - function.setUsesArguments(); + getFunction().setUsesArguments(); } } @@ -481,7 +489,7 @@ loop: * @return null or the found label node. */ private LabelNode findLabel(final IdentNode ident) { - for (final LabelNode labelNode : function.getLabelStack()) { + for (final LabelNode labelNode : getFunction().getLabelStack()) { if (labelNode.getLabel().equals(ident)) { return labelNode; } @@ -495,14 +503,14 @@ loop: * @param labelNode Label to add. */ private void pushLabel(final LabelNode labelNode) { - function.getLabelStack().push(labelNode); + getFunction().getLabelStack().push(labelNode); } /** * Remove a label from the label stack. */ private void popLabel() { - function.getLabelStack().pop(); + getFunction().getLabelStack().pop(); } /** @@ -512,6 +520,7 @@ loop: private void pushControlNode(final Node node) { final boolean isLoop = node instanceof WhileNode; final boolean isBreakable = node instanceof BreakableNode || node instanceof Block; + final FunctionNode function = getFunction(); function.getControlStack().push(node); for (final LabelNode labelNode : function.getLabelStack()) { @@ -530,7 +539,7 @@ loop: */ private void popControlNode() { // Get control stack. - final Stack controlStack = function.getControlStack(); + final Stack controlStack = getFunction().getControlStack(); // Can be empty if missing brace. if (!controlStack.isEmpty()) { @@ -540,7 +549,7 @@ loop: private void popControlNode(final Node node) { // Get control stack. - final Stack controlStack = function.getControlStack(); + final Stack controlStack = getFunction().getControlStack(); // Can be empty if missing brace. if (!controlStack.isEmpty() && controlStack.peek() == node) { @@ -549,7 +558,7 @@ loop: } private boolean isInWithBlock() { - final Stack controlStack = function.getControlStack(); + final Stack controlStack = getFunction().getControlStack(); for (int i = controlStack.size() - 1; i >= 0; i--) { final Node node = controlStack.get(i); @@ -562,7 +571,7 @@ loop: } private T findControl(final Class ctype) { - final Stack controlStack = function.getControlStack(); + final Stack controlStack = getFunction().getControlStack(); for (int i = controlStack.size() - 1; i >= 0; i--) { final Node node = controlStack.get(i); @@ -576,7 +585,7 @@ loop: private List findControls(final Class ctype, final Node to) { final List nodes = new ArrayList<>(); - final Stack controlStack = function.getControlStack(); + final Stack controlStack = getFunction().getControlStack(); for (int i = controlStack.size() - 1; i >= 0; i--) { final Node node = controlStack.get(i); @@ -625,7 +634,10 @@ loop: script.setKind(FunctionNode.Kind.SCRIPT); script.setFirstToken(functionToken); + functionDeclarations = new ArrayList<>(); sourceElements(); + script.prependStatements(functionDeclarations); + functionDeclarations = null; expect(EOF); script.setLastToken(token); script.setFinish(source.getLength() - 1); @@ -704,7 +716,7 @@ loop: // check for directive prologues if (checkDirective) { // skip any debug statement like line number to get actual first line - final Node lastStatement = lastStatement(block.getStatements()); + final Node lastStatement = lastStatement(getBlock().getStatements()); // get directive prologue, if any final String directive = getDirective(lastStatement); @@ -724,6 +736,7 @@ loop: // handle use strict directive if ("use strict".equals(directive)) { isStrictMode = true; + final FunctionNode function = getFunction(); function.setStrictMode(true); // We don't need to check these, if lexical environment is already strict @@ -796,11 +809,11 @@ loop: if (isStrictMode && !topLevel) { error(AbstractParser.message("strict.no.func.here"), token); } - functionExpression(true); + functionExpression(true, topLevel); return; } - block.addStatement(lineNumberNode); + getBlock().addStatement(lineNumberNode); switch (type) { case LBRACE: @@ -886,7 +899,7 @@ loop: // Force block execution. final ExecuteNode executeNode = new ExecuteNode(source, newBlock.getToken(), finish, newBlock); - block.addStatement(executeNode); + getBlock().addStatement(executeNode); } /** @@ -981,13 +994,9 @@ loop: // Allocate var node. final VarNode var = new VarNode(source, varToken, finish, name, init); - if (isStatement) { - function.addDeclaration(var); - } - vars.add(var); // Add to current block. - block.addStatement(var); + getBlock().addStatement(var); if (type != COMMARIGHT) { break; @@ -1000,7 +1009,7 @@ loop: boolean semicolon = type == SEMICOLON; endOfLine(); if (semicolon) { - block.setFinish(finish); + getBlock().setFinish(finish); } } @@ -1017,7 +1026,7 @@ loop: */ private void emptyStatement() { if (env._empty_statements) { - block.addStatement(new EmptyNode(source, token, + getBlock().addStatement(new EmptyNode(source, token, Token.descPosition(token) + Token.descLength(token))); } @@ -1043,7 +1052,7 @@ loop: ExecuteNode executeNode = null; if (expression != null) { executeNode = new ExecuteNode(source, expressionToken, finish, expression); - block.addStatement(executeNode); + getBlock().addStatement(executeNode); } else { expect(null); } @@ -1052,7 +1061,7 @@ loop: if (executeNode != null) { executeNode.setFinish(finish); - block.setFinish(finish); + getBlock().setFinish(finish); } } @@ -1094,7 +1103,7 @@ loop: // Construct and add new if node. final IfNode ifNode = new IfNode(source, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail); - block.addStatement(ifNode); + getBlock().addStatement(ifNode); } /** @@ -1143,13 +1152,13 @@ loop: outer.setFinish(body.getFinish()); // Add for to current block. - block.addStatement(forNode); + getBlock().addStatement(forNode); } finally { - restoreBlock(); + restoreBlock(outer); popControlNode(); } - block.addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); + getBlock().addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); } /** @@ -1283,7 +1292,7 @@ loop: whileNode.setFinish(statements.getFinish()); // Add WHILE node. - block.addStatement(whileNode); + getBlock().addStatement(whileNode); } finally { popControlNode(); } @@ -1330,7 +1339,7 @@ loop: doWhileNode.setFinish(finish); // Add DO node. - block.addStatement(doWhileNode); + getBlock().addStatement(doWhileNode); } finally { popControlNode(); } @@ -1382,7 +1391,7 @@ loop: final ContinueNode continueNode = new ContinueNode(source, continueToken, finish, labelNode, targetNode, findControl(TryNode.class)); continueNode.setScopeNestingLevel(countControls(WithNode.class, targetNode)); - block.addStatement(continueNode); + getBlock().addStatement(continueNode); } /** @@ -1430,7 +1439,7 @@ loop: final BreakNode breakNode = new BreakNode(source, breakToken, finish, labelNode, targetNode, findControl(TryNode.class)); breakNode.setScopeNestingLevel(countControls(WithNode.class, targetNode)); - block.addStatement(breakNode); + getBlock().addStatement(breakNode); } /** @@ -1443,7 +1452,7 @@ loop: */ private void returnStatement() { // check for return outside function - if (function.getKind() == FunctionNode.Kind.SCRIPT) { + if (getFunction().getKind() == FunctionNode.Kind.SCRIPT) { error(AbstractParser.message("invalid.return")); } @@ -1470,7 +1479,7 @@ loop: // Construct and add RETURN node. final ReturnNode returnNode = new ReturnNode(source, returnToken, finish, expression, findControl(TryNode.class)); - block.addStatement(returnNode); + getBlock().addStatement(returnNode); } /** @@ -1505,7 +1514,7 @@ loop: // Construct and add YIELD node. final ReturnNode yieldNode = new ReturnNode(source, yieldToken, finish, expression, findControl(TryNode.class)); - block.addStatement(yieldNode); + getBlock().addStatement(yieldNode); } /** @@ -1529,7 +1538,10 @@ loop: // Get WITH expression. final WithNode withNode = new WithNode(source, withToken, finish, null, null); - function.setHasWith(); + final Iterator it = lexicalContext.getFunctions(); + if(it.hasNext()) { + it.next().setHasWith(it); + } try { pushControlNode(withNode); @@ -1549,7 +1561,7 @@ loop: popControlNode(withNode); } - block.addStatement(withNode); + getBlock().addStatement(withNode); } /** @@ -1649,7 +1661,7 @@ loop: switchNode.setFinish(finish); - block.addStatement(switchNode); + getBlock().addStatement(switchNode); } finally { popControlNode(); } @@ -1684,7 +1696,7 @@ loop: labelNode.setBody(statements); labelNode.setFinish(finish); - block.addStatement(labelNode); + getBlock().addStatement(labelNode); } finally { // Remove label. popLabel(); @@ -1727,7 +1739,7 @@ loop: // Construct and add THROW node. final ThrowNode throwNode = new ThrowNode(source, throwToken, finish, expression, findControl(TryNode.class)); - block.addStatement(throwNode); + getBlock().addStatement(throwNode); } /** @@ -1793,18 +1805,18 @@ loop: expect(RPAREN); + final Block catchBlock = newBlock(); try { - final Block catchBlock = newBlock(); // Get CATCH body. final Block catchBody = getBlock(true); // Create and add catch. final CatchNode catchNode = new CatchNode(source, catchToken, finish, exception, ifExpression, catchBody); - block.addStatement(catchNode); + getBlock().addStatement(catchNode); catchBlocks.add(catchBlock); } finally { - restoreBlock(); + restoreBlock(catchBlock); } // If unconditional catch then should to be the end. @@ -1840,11 +1852,11 @@ loop: outer.addStatement(tryNode); } finally { popControlNode(tryNode); - restoreBlock(); + restoreBlock(outer); popControlNode(outer); } - block.addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); + getBlock().addStatement(new ExecuteNode(source, outer.getToken(), outer.getFinish(), outer)); } /** @@ -1864,7 +1876,7 @@ loop: endOfLine(); final RuntimeNode runtimeNode = new RuntimeNode(source, debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList()); - block.addStatement(runtimeNode); + getBlock().addStatement(runtimeNode); } /** @@ -2244,7 +2256,7 @@ loop: parameters = new ArrayList<>(); functionNode = functionBody(getSetToken, getNameNode, parameters, FunctionNode.Kind.GETTER); propertyNode = new PropertyNode(source, propertyToken, finish, getIdent, null); - propertyNode.setGetter(new ReferenceNode(source, propertyToken, finish, functionNode)); + propertyNode.setGetter(functionNode); return propertyNode; case "set": @@ -2259,7 +2271,7 @@ loop: parameters.add(argIdent); functionNode = functionBody(getSetToken, setNameNode, parameters, FunctionNode.Kind.SETTER); propertyNode = new PropertyNode(source, propertyToken, finish, setIdent, null); - propertyNode.setSetter(new ReferenceNode(source, propertyToken, finish, functionNode)); + propertyNode.setSetter(functionNode); return propertyNode; default: @@ -2440,7 +2452,7 @@ loop: case FUNCTION: // Get function expression. - lhs = functionExpression(false); + lhs = functionExpression(false, false); break; default: @@ -2545,7 +2557,7 @@ loop: * * @return Expression node. */ - private Node functionExpression(final boolean isStatement) { + private Node functionExpression(final boolean isStatement, final boolean topLevel) { final LineNumberNode lineNumber = lineNumber(); final long functionToken = token; @@ -2580,10 +2592,12 @@ loop: final FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL); - if (isStatement && !isInWithBlock()) { - functionNode.setIsStatement(); + if (isStatement) { + if(topLevel) { + functionNode.setIsDeclared(); + } if(ARGUMENTS.tag().equals(name.getName())) { - functionNode.findParentFunction().setDefinesArguments(); + getFunction().setDefinesArguments(); } } @@ -2591,8 +2605,6 @@ loop: functionNode.setIsAnonymous(); } - final ReferenceNode referenceNode = new ReferenceNode(source, functionToken, finish, functionNode); - final int arity = parameters.size(); final boolean strict = functionNode.isStrictMode(); @@ -2628,17 +2640,18 @@ loop: } if (isStatement) { - final VarNode var = new VarNode(source, functionToken, finish, name, referenceNode); - if (isInWithBlock()) { - function.addDeclaration(var); - // Add to current block. - block.addStatement(var); + final VarNode varNode = new VarNode(source, functionToken, finish, name, functionNode, true); + if(topLevel) { + functionDeclarations.add(lineNumber); + functionDeclarations.add(varNode); } else { - functionNode.setFunctionVarNode(var, lineNumber); + final Block block = getBlock(); + block.addStatement(lineNumber); + block.addStatement(varNode); } } - return referenceNode; + return functionNode; } /** @@ -2721,7 +2734,14 @@ loop: expect(LBRACE); // Gather the function elements. - sourceElements(); + final List prevFunctionDecls = functionDeclarations; + functionDeclarations = new ArrayList<>(); + try { + sourceElements(); + functionNode.prependStatements(functionDeclarations); + } finally { + functionDeclarations = prevFunctionDecls; + } functionNode.setLastToken(token); expect(RBRACE); @@ -2729,12 +2749,9 @@ loop: } } finally { - restoreBlock(); + restoreBlock(functionNode); } - // Add the body of the function to the current block. - block.addFunction(functionNode); - return functionNode; } @@ -3069,4 +3086,12 @@ loop: public String toString() { return "[JavaScript Parsing]"; } + + private Block getBlock() { + return lexicalContext.getCurrentBlock(); + } + + private FunctionNode getFunction() { + return lexicalContext.getCurrentFunction(); + } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 0ca2c47a9ec..448df143c24 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -27,9 +27,9 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT; import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; +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.io.File; import java.io.IOException; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 4547e444422..43a7ff62977 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -42,6 +42,8 @@ parser.error.expected.stmt=Expected statement but found {0} parser.error.expected.comma=Expected comma but found {0} parser.error.expected=Expected {0} but found {1} parser.error.invalid.return=Invalid return statement +parser.error.no.func.decl.here=Function declarations can only occur at program or function body level. You should use a function expression here instead. +parser.error.no.func.decl.here.warn=Function declarations should only occur at program or function body level. Function declaration in nested block was converted to a function expression. parser.error.property.redefinition=Property "{0}" already defined parser.error.unexpected.token=Unexpected token: {0} parser.error.many.vars.in.for.in.loop=Only one variable allowed in for..in loop @@ -57,7 +59,7 @@ parser.error.strict.name="{0}" cannot be used as {1} in strict mode parser.error.strict.cant.delete.ident=cannot delete identifier "{0}" in strict mode parser.error.strict.param.redefinition=strict mode function cannot have duplicate parameter name "{0}" parser.error.strict.no.octal=cannot use octal value in strict mode -parser.error.strict.no.func.here=In strict mode, functions can only be declared at top-level or immediately within a function +parser.error.strict.no.func.decl.here=In strict mode, function declarations can only occur at program or function body level. You should use a function expression here instead. type.error.strict.getter.setter.poison=In strict mode, "caller", "callee", and "arguments" properties can not be accessed on functions or the arguments object # not the expected type in a given context diff --git a/nashorn/test/script/basic/JDK-8006755.js b/nashorn/test/script/basic/JDK-8006755.js index 3012a4bed56..092434730b1 100644 --- a/nashorn/test/script/basic/JDK-8006755.js +++ b/nashorn/test/script/basic/JDK-8006755.js @@ -31,7 +31,7 @@ var scope = { x: "hello" }; with (scope) { - function main() { + var main = function() { if (x != "hello") { fail("x != 'hello'"); } diff --git a/nashorn/test/script/basic/NASHORN-837.js b/nashorn/test/script/basic/NASHORN-837.js index 0632fb39a31..ef9ec64d193 100644 --- a/nashorn/test/script/basic/NASHORN-837.js +++ b/nashorn/test/script/basic/NASHORN-837.js @@ -28,23 +28,13 @@ * @run */ -var failed = false; - try { - try { - throw new TypeError('error'); - } catch (iox) { - function f() { - print(iox.message); - } + throw new TypeError('error'); +} catch (iox) { + var f = function() { + if(iox.message != 'error') { + print("Failure! iox did not throw correct exception"); + } } - f(); -} catch (e) { - failed = (e instanceof ReferenceError); - //iox not defined should be thrown } - -if (!failed) { - print("Failure! iox did not throw correct exception"); -} - +f(); diff --git a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java index adf361f4944..3cbe1ed4152 100644 --- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java @@ -44,6 +44,7 @@ public class CompilerTest { private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("compilertest.verbose")); private static final boolean TEST262 = Boolean.valueOf(System.getProperty("compilertest.test262")); private static final String TEST_BASIC_DIR = System.getProperty("test.basic.dir"); + private static final String TEST_NODE_DIR = System.getProperty("test.node.dir"); private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); interface TestFilter { @@ -81,21 +82,22 @@ public class CompilerTest { @Test public void compileAllTests() { if (TEST262) { - compileTestSet(TEST262_SUITE_DIR, new TestFilter() { + compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() { @Override public boolean exclude(final File file, final String content) { return content.indexOf("@negative") != -1; } }); } - compileTestSet(TEST_BASIC_DIR, null); + compileTestSet(new File(TEST_BASIC_DIR), null); + compileTestSet(new File(TEST_NODE_DIR, "node"), null); + compileTestSet(new File(TEST_NODE_DIR, "src"), null); } - private void compileTestSet(final String testSet, final TestFilter filter) { + private void compileTestSet(final File testSetDir, final TestFilter filter) { passed = 0; failed = 0; skipped = 0; - final File testSetDir = new File(testSet); if (! testSetDir.isDirectory()) { log("WARNING: " + testSetDir + " not found or not a directory"); return; @@ -103,7 +105,7 @@ public class CompilerTest { log(testSetDir.getAbsolutePath()); compileJSDirectory(testSetDir, filter); - log(testSet + " compile done!"); + log(testSetDir + " compile done!"); log("compile ok: " + passed); log("compile failed: " + failed); log("compile skipped: " + skipped); From 87b698f39432d8d4550b39356eca77248b58682e Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 23 Mar 2013 11:49:28 +0800 Subject: [PATCH 102/137] 8009970: Several LoginModule classes need extra permission to load AuthResources Reviewed-by: mullan --- .../security/auth/module/JndiLoginModule.java | 13 +++++++-- .../auth/module/KeyStoreLoginModule.java | 27 ++++++++----------- .../security/auth/module/Krb5LoginModule.java | 12 +++++++-- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java index cb68cfc2a3f..b6b8660a2e4 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/JndiLoginModule.java @@ -32,8 +32,11 @@ import javax.security.auth.spi.*; import javax.naming.*; import javax.naming.directory.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Map; import java.util.LinkedList; +import java.util.ResourceBundle; import com.sun.security.auth.UnixPrincipal; import com.sun.security.auth.UnixNumericUserPrincipal; @@ -150,8 +153,14 @@ import com.sun.security.auth.UnixNumericGroupPrincipal; */ public class JndiLoginModule implements LoginModule { - static final java.util.ResourceBundle rb = - java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); + private static final ResourceBundle rb = AccessController.doPrivileged( + new PrivilegedAction() { + public ResourceBundle run() { + return ResourceBundle.getBundle( + "sun.security.util.AuthResources"); + } + } + ); /** JNDI Provider */ public final String USER_PROVIDER = "user.provider.url"; diff --git a/jdk/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java index e5d88cf8e1f..70f74d65a22 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/KeyStoreLoginModule.java @@ -30,22 +30,11 @@ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.security.AuthProvider; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.Provider; -import java.security.UnrecoverableKeyException; +import java.security.*; import java.security.cert.*; +import java.security.cert.Certificate; import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; import javax.security.auth.Destroyable; import javax.security.auth.DestroyFailedException; import javax.security.auth.Subject; @@ -123,8 +112,14 @@ import sun.security.util.Password; */ public class KeyStoreLoginModule implements LoginModule { - static final java.util.ResourceBundle rb = - java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); + private static final ResourceBundle rb = AccessController.doPrivileged( + new PrivilegedAction() { + public ResourceBundle run() { + return ResourceBundle.getBundle( + "sun.security.util.AuthResources"); + } + } + ); /* -- Fields -- */ diff --git a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java index 719aeee76d4..cd60c6ac790 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java @@ -27,6 +27,8 @@ package com.sun.security.auth.module; import java.io.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.text.MessageFormat; import java.util.*; @@ -429,8 +431,14 @@ public class Krb5LoginModule implements LoginModule { private static final String NAME = "javax.security.auth.login.name"; private static final String PWD = "javax.security.auth.login.password"; - static final java.util.ResourceBundle rb = - java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); + private static final ResourceBundle rb = AccessController.doPrivileged( + new PrivilegedAction() { + public ResourceBundle run() { + return ResourceBundle.getBundle( + "sun.security.util.AuthResources"); + } + } + ); /** * Initialize this LoginModule. From 5f089665158696578781622f4b0febc89c0a0f90 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 23 Mar 2013 11:49:39 +0800 Subject: [PATCH 103/137] 8009875: Provide a default udp_preference_limit for krb5.conf Reviewed-by: valeriep --- .../classes/sun/security/krb5/KdcComm.java | 13 +++- .../sun/security/krb5/internal/Krb5.java | 2 + jdk/test/sun/security/krb5/auto/KDC.java | 10 +-- .../sun/security/krb5/config/DefUdpLimit.java | 67 +++++++++++++++++++ 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 jdk/test/sun/security/krb5/config/DefUdpLimit.java diff --git a/jdk/src/share/classes/sun/security/krb5/KdcComm.java b/jdk/src/share/classes/sun/security/krb5/KdcComm.java index 6a40bacc3b4..80c0af48e00 100644 --- a/jdk/src/share/classes/sun/security/krb5/KdcComm.java +++ b/jdk/src/share/classes/sun/security/krb5/KdcComm.java @@ -138,7 +138,7 @@ public final class KdcComm { int timeout = -1; int max_retries = -1; - int udf_pref_limit = -1; + int udp_pref_limit = -1; try { Config cfg = Config.getInstance(); @@ -147,7 +147,7 @@ public final class KdcComm { temp = cfg.get("libdefaults", "max_retries"); max_retries = parsePositiveIntString(temp); temp = cfg.get("libdefaults", "udp_preference_limit"); - udf_pref_limit = parsePositiveIntString(temp); + udp_pref_limit = parsePositiveIntString(temp); } catch (Exception exc) { // ignore any exceptions; use default values if (DEBUG) { @@ -159,7 +159,14 @@ public final class KdcComm { defaultKdcTimeout = timeout > 0 ? timeout : 30*1000; // 30 seconds defaultKdcRetryLimit = max_retries > 0 ? max_retries : Krb5.KDC_RETRY_LIMIT; - defaultUdpPrefLimit = udf_pref_limit; + + if (udp_pref_limit < 0) { + defaultUdpPrefLimit = Krb5.KDC_DEFAULT_UDP_PREF_LIMIT; + } else if (udp_pref_limit > Krb5.KDC_HARD_UDP_LIMIT) { + defaultUdpPrefLimit = Krb5.KDC_HARD_UDP_LIMIT; + } else { + defaultUdpPrefLimit = udp_pref_limit; + } KdcAccessibility.reset(); } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java b/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java index 1d3bb644aca..1861c395f0e 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/Krb5.java @@ -130,6 +130,8 @@ public class Krb5 { // number of retries before giving up public static final int KDC_RETRY_LIMIT = 3; + public static final int KDC_DEFAULT_UDP_PREF_LIMIT = 1465; + public static final int KDC_HARD_UDP_LIMIT = 32700; //OSI authentication mechanism OID diff --git a/jdk/test/sun/security/krb5/auto/KDC.java b/jdk/test/sun/security/krb5/auto/KDC.java index 83cafe73f8f..44330dfc723 100644 --- a/jdk/test/sun/security/krb5/auto/KDC.java +++ b/jdk/test/sun/security/krb5/auto/KDC.java @@ -923,29 +923,29 @@ public class KDC { pas2 = new DerValue[] { new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()), - new DerValue(new ETypeInfo2(1, OneKDC.REALM, new byte[]{1}).asn1Encode()), + new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()), }; pas = new DerValue[] { new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()), - new DerValue(new ETypeInfo(1, OneKDC.REALM).asn1Encode()), + new DerValue(new ETypeInfo(1, realm).asn1Encode()), }; break; case 2: // we still reject non-null s2kparams and prefer E2 over E pas2 = new DerValue[] { - new DerValue(new ETypeInfo2(1, OneKDC.REALM, new byte[]{1}).asn1Encode()), + new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()), new DerValue(new ETypeInfo2(1, null, null).asn1Encode()), new DerValue(new ETypeInfo2(1, "", null).asn1Encode()), }; pas = new DerValue[] { - new DerValue(new ETypeInfo(1, OneKDC.REALM).asn1Encode()), + new DerValue(new ETypeInfo(1, realm).asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()), }; break; case 3: // but only E is wrong pas = new DerValue[] { - new DerValue(new ETypeInfo(1, OneKDC.REALM).asn1Encode()), + new DerValue(new ETypeInfo(1, realm).asn1Encode()), new DerValue(new ETypeInfo(1, null).asn1Encode()), new DerValue(new ETypeInfo(1, "").asn1Encode()), }; diff --git a/jdk/test/sun/security/krb5/config/DefUdpLimit.java b/jdk/test/sun/security/krb5/config/DefUdpLimit.java new file mode 100644 index 00000000000..ae1712d0b1a --- /dev/null +++ b/jdk/test/sun/security/krb5/config/DefUdpLimit.java @@ -0,0 +1,67 @@ +/* + * 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 8009875 + * @summary Provide a default udp_preference_limit for krb5.conf + * @compile -XDignore.symbol.file DefUdpLimit.java + * @run main/othervm DefUdpLimit -1 1465 + * @run main/othervm DefUdpLimit 0 0 + * @run main/othervm DefUdpLimit 1234 1234 + * @run main/othervm DefUdpLimit 12345 12345 + * @run main/othervm DefUdpLimit 123456 32700 + * + */ + +import sun.security.krb5.KdcComm; + +import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class DefUdpLimit { + + public static void main(String[] args) throws Exception { + int set = Integer.valueOf(args[0]); + int expected = Integer.valueOf(args[1]); + Field f = KdcComm.class.getDeclaredField("defaultUdpPrefLimit"); + f.setAccessible(true); + writeConf(set); + int actual = (Integer)f.get(null); + if (actual != expected) { + throw new Exception("Expected: " + expected + ", get " + actual); + } + } + + static void writeConf(int i) throws Exception { + String file = "krb5.conf." + i; + String content = "[libdefaults]\n"; + if (i >= 0) { + content += "udp_preference_limit = " + i; + } + Files.write(Paths.get(file), content.getBytes()); + System.setProperty("java.security.krb5.conf", file); + } +} + From 9afb5dba836600b84897c68bafb930af185de545 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Sat, 23 Mar 2013 01:47:25 -0700 Subject: [PATCH 104/137] Added tag hs25-b24 for changeset 5f89974cce81 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 486a2cdf23e..bfb3baa2ed0 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -325,3 +325,4 @@ dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22 65b797426a3bec6e91b64085a0cfb94adadb634a jdk8-b81 0631ebcc45f05c73b09a56c2586685af1f781c1d hs25-b23 3db4ab0e12f437fe374817de346b2b0c6b4a5b31 jdk8-b82 +e3a41fc0234895eba4f272b984f7dacff495f8eb hs25-b24 From 196cd6601b3631808f0a3c81914346262e3ab866 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Sat, 23 Mar 2013 10:06:34 -0700 Subject: [PATCH 105/137] 8010498: new hotspot build - hs25-b25 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 69b8ad849df..c6bad83dffd 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=24 +HS_BUILD_NUMBER=25 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From c458eb3fd6400ddf6988e21dbf9b5eb93f95328f Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Sun, 24 Mar 2013 09:11:55 +0100 Subject: [PATCH 106/137] 8008454: test/runtime/NMT/PrintNMTStatistics is broken Added @run tag so that it actually runs the test, also fixed broken command line and incorrect parsing. Also reviewed by gerard.ziemski@oracle.com Reviewed-by: mgerdin, zgu --- hotspot/test/runtime/NMT/PrintNMTStatistics.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hotspot/test/runtime/NMT/PrintNMTStatistics.java b/hotspot/test/runtime/NMT/PrintNMTStatistics.java index 084a81512d5..96bc2f3267f 100644 --- a/hotspot/test/runtime/NMT/PrintNMTStatistics.java +++ b/hotspot/test/runtime/NMT/PrintNMTStatistics.java @@ -27,7 +27,9 @@ * @bug 8005936 * @summary Make sure PrintNMTStatistics works on normal JVM exit * @library /testlibrary /testlibrary/whitebox - * @run compile PrintNMTStatistics.java + * @build PrintNMTStatistics + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main PrintNMTStatistics */ import com.oracle.java.testlibrary.*; @@ -52,13 +54,15 @@ public class PrintNMTStatistics { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", + "-Xbootclasspath/a:.", + "-XX:+WhiteBoxAPI", "-XX:NativeMemoryTracking=summary", - "+XX:+PrintNMTStatistics", + "-XX:+PrintNMTStatistics", "PrintNMTStatistics", "test"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Java Heap (reserved="); + output.shouldContain("Java Heap (reserved="); output.shouldNotContain("error"); output.shouldNotContain("warning"); output.shouldHaveExitValue(0); From 897aab045e7fef1438a523340501f2fe31826792 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Mon, 25 Mar 2013 12:01:06 +0100 Subject: [PATCH 107/137] 8017010: index evaluation to a temporary location for index operator much change temporaries to slots, but never scoped vars Reviewed-by: hannesw, sundar --- .../jdk/nashorn/internal/codegen/Attr.java | 9 ++- .../runtime/regexp/joni/ByteCodeMachine.java | 2 +- .../regexp/joni/encoding/AsciiTables.java | 2 +- nashorn/test/script/basic/JDK-8017010.js | 68 +++++++++++++++++++ .../test/script/basic/JDK-8017010.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-258.js | 12 ++++ .../test/script/basic/NASHORN-258.js.EXPECTED | 1 + 7 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8017010.js create mode 100644 nashorn/test/script/basic/JDK-8017010.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 938055984cd..9ecf7c89a9c 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -577,7 +577,7 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveIndexNode(final IndexNode indexNode) { - newTemporary(Type.OBJECT, indexNode); //TORO + newTemporary(Type.OBJECT, indexNode); //TODO return indexNode; } @@ -1470,8 +1470,13 @@ final class Attr extends NodeOperatorVisitor { assignmentDest.accept(new NodeVisitor() { @Override public Node leaveIndexNode(final IndexNode indexNode) { + assert indexNode.getSymbol().isTemp(); final Node index = indexNode.getIndex(); - index.getSymbol().setNeedsSlot(!index.getSymbol().isConstant()); + //only temps can be set as needing slots. the others will self resolve + //it is illegal to take a scope var and force it to be a slot, that breaks + if (index.getSymbol().isTemp() && !index.getSymbol().isConstant()) { + index.getSymbol().setNeedsSlot(true); + } return indexNode; } }); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java index 8aaabe2deca..43cc5188477 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java @@ -1459,4 +1459,4 @@ class ByteCodeMachine extends StackMachine { private int finish() { return bestLen; } -} \ No newline at end of file +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java index 77eba2deb86..3dec4ba2547 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java @@ -154,4 +154,4 @@ public class AsciiTables { {0x59, 0x79}, {0x5a, 0x7a} }; -} \ No newline at end of file +} diff --git a/nashorn/test/script/basic/JDK-8017010.js b/nashorn/test/script/basic/JDK-8017010.js new file mode 100644 index 00000000000..aa6e61a9328 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8017010.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-8010710 - slot/scope problem with temporary expressions + * as array index in self modifying assigns + * + * @test + * @run + */ +function zero() { + return 0; +} + +//try complex self modifying assignment and force slots to temporary value index operators +var a = [1, 2, 3, 4, 5]; +var b = [a, a]; +print(b[zero() + 1][2 + a[0]] += 10); + +//repro for NASHORN-258 that never made it +function AddRoundKey() { + var r=0; + state[r][1] &= 17; +} + +var srcFiles = []; +for(i=0;i<100;i++) { + srcFiles.push('dummy'); +} +var added = ''; + +//this broke the javafx build system. verify it works +function bouncingBall() { + for (j=0; j<100; j++) { + added += srcFiles[j]; + } +} +bouncingBall(); +print(added); + +//this is how they should have done it for speed, that works always, verify this too +function bouncingBall2() { + for (var k=0; k<100; k++) { + added += srcFiles[k]; + } +} +bouncingBall2(); +print(added); diff --git a/nashorn/test/script/basic/JDK-8017010.js.EXPECTED b/nashorn/test/script/basic/JDK-8017010.js.EXPECTED new file mode 100644 index 00000000000..296c81e57c4 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8017010.js.EXPECTED @@ -0,0 +1,3 @@ +14 +dummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummy +dummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummydummy diff --git a/nashorn/test/script/basic/NASHORN-258.js b/nashorn/test/script/basic/NASHORN-258.js index 0f4f674b6be..6d71266a3ad 100644 --- a/nashorn/test/script/basic/NASHORN-258.js +++ b/nashorn/test/script/basic/NASHORN-258.js @@ -29,6 +29,16 @@ */ function test3(a) { + for (i = 0; i < a.length ; i++) { + for (j = 0; j < a[i].length ; j++) { + for (k = 0; k < a[i][j].length ; k++) { + a[i][j][k] *= 8; + } + } + } +} + +function test3local(a) { for (var i = 0; i < a.length ; i++) { for (var j = 0; j < a[i].length ; j++) { for (var k = 0; k < a[i][j].length ; k++) { @@ -45,6 +55,8 @@ var array = [ [[1,1,1],[1,1,1],[1,1,1]], test3(array); print(array); +test3local(array); +print(array); function outer() { diff --git a/nashorn/test/script/basic/NASHORN-258.js.EXPECTED b/nashorn/test/script/basic/NASHORN-258.js.EXPECTED index 8c95c914b48..5986c471cd4 100644 --- a/nashorn/test/script/basic/NASHORN-258.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-258.js.EXPECTED @@ -1,2 +1,3 @@ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64 1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8,1,1,8 From 41f0004e4ffc4c43ddaf45ea38c8008d837e0202 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 25 Mar 2013 08:37:28 -0400 Subject: [PATCH 108/137] 8010667: Non-zero padding is not allowed in splitverifier for tableswitch/lookupswitch instructions Don't check the padding bits if class file version is >= 51. Reviewed-by: kvn, dholmes, coleenp --- hotspot/src/share/vm/classfile/verifier.cpp | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 071c835279e..4ff142a9200 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -61,8 +61,9 @@ # include "bytes_ppc.hpp" #endif -#define NOFAILOVER_MAJOR_VERSION 51 -#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52 +#define NOFAILOVER_MAJOR_VERSION 51 +#define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION 51 +#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52 // Access to external entry for VerifyClassCodes - old byte code verifier @@ -2027,16 +2028,19 @@ void ClassVerifier::verify_switch( address bcp = bcs->bcp(); address aligned_bcp = (address) round_to((intptr_t)(bcp + 1), jintSize); - // 4639449 & 4647081: padding bytes must be 0 - u2 padding_offset = 1; - while ((bcp + padding_offset) < aligned_bcp) { - if(*(bcp + padding_offset) != 0) { - verify_error(ErrorContext::bad_code(bci), - "Nonzero padding byte in lookswitch or tableswitch"); - return; + if (_klass->major_version() < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) { + // 4639449 & 4647081: padding bytes must be 0 + u2 padding_offset = 1; + while ((bcp + padding_offset) < aligned_bcp) { + if(*(bcp + padding_offset) != 0) { + verify_error(ErrorContext::bad_code(bci), + "Nonzero padding byte in lookswitch or tableswitch"); + return; + } + padding_offset++; } - padding_offset++; } + int default_offset = (int) Bytes::get_Java_u4(aligned_bcp); int keys, delta; current_frame->pop_stack( From a9423b7ebf4e22b42c4382cbfd946ed5a2034386 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 25 Mar 2013 18:20:16 +0530 Subject: [PATCH 109/137] 8010709: org on the top level doesn't resolve Reviewed-by: lagergren, hannesw --- .../jdk/nashorn/internal/objects/Global.java | 30 +++++++++++- nashorn/test/script/basic/JDK-8010709.js | 46 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8010709.js diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index e0bb9ecefd2..e079248b577 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -259,13 +259,29 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE) public volatile Object packages; + /** Nashorn extension: Java access - global.com */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public volatile Object com; + + /** Nashorn extension: Java access - global.edu */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public volatile Object edu; + /** Nashorn extension: Java access - global.java */ @Property(attributes = Attribute.NOT_ENUMERABLE) public volatile Object java; + /** Nashorn extension: Java access - global.javafx */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public volatile Object javafx; + /** Nashorn extension: Java access - global.javax */ @Property(attributes = Attribute.NOT_ENUMERABLE) - public Object javax; + public volatile Object javax; + + /** Nashorn extension: Java access - global.org */ + @Property(attributes = Attribute.NOT_ENUMERABLE) + public volatile Object org; /** Nashorn extension: Java access - global.javaImporter */ @Property(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE) @@ -320,8 +336,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { private ScriptFunction builtinTypeError; private ScriptFunction builtinURIError; private ScriptObject builtinPackages; + private ScriptObject builtinCom; + private ScriptObject builtinEdu; private ScriptObject builtinJava; + private ScriptObject builtinJavafx; private ScriptObject builtinJavax; + private ScriptObject builtinOrg; private ScriptObject builtinJavaImporter; private ScriptObject builtinJavaApi; private ScriptObject builtinArrayBuffer; @@ -1482,8 +1502,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { private void initJavaAccess() { final ScriptObject objectProto = getObjectPrototype(); this.builtinPackages = new NativeJavaPackage("", objectProto); + this.builtinCom = new NativeJavaPackage("com", objectProto); + this.builtinEdu = new NativeJavaPackage("edu", objectProto); this.builtinJava = new NativeJavaPackage("java", objectProto); + this.builtinJavafx = new NativeJavaPackage("javafx", objectProto); this.builtinJavax = new NativeJavaPackage("javax", objectProto); + this.builtinOrg = new NativeJavaPackage("org", objectProto); this.builtinJavaImporter = initConstructor("JavaImporter"); this.builtinJavaApi = initConstructor("Java"); } @@ -1566,8 +1590,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { this.function = this.builtinFunction; this.jsadapter = this.builtinJSAdapter; this.json = this.builtinJSON; + this.com = this.builtinCom; + this.edu = this.builtinEdu; this.java = this.builtinJava; + this.javafx = this.builtinJavafx; this.javax = this.builtinJavax; + this.org = this.builtinOrg; this.javaImporter = this.builtinJavaImporter; this.javaApi = this.builtinJavaApi; this.math = this.builtinMath; diff --git a/nashorn/test/script/basic/JDK-8010709.js b/nashorn/test/script/basic/JDK-8010709.js new file mode 100644 index 00000000000..d2ec87aeb7d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8010709.js @@ -0,0 +1,46 @@ +/* + * 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-8010709 org on the top level doesn't resolve + * + * @test + * @run + */ + +function check(pkgName) { + if (typeof this[pkgName] != 'object') { + fail(pkgName + " not defined"); + } + + if (String(this[pkgName]) != '[JavaPackage ' + pkgName + ']') { + fail(pkgName + " is not a JavaPackage"); + } +} + +check("com"); +check("edu"); +check("java"); +check("javafx"); +check("javax"); +check("org"); From 61c8affcc1323e16b6eeb6476b6870082a58dc17 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 25 Mar 2013 19:25:01 +0530 Subject: [PATCH 110/137] 8010704: The test closed/java/lang/SecurityManager/CheckPackageDefinition.java failed after fix for 8009869 Reviewed-by: lagergren, hannesw --- jdk/src/share/lib/security/java.security-linux | 2 +- jdk/src/share/lib/security/java.security-solaris | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/lib/security/java.security-linux b/jdk/src/share/lib/security/java.security-linux index 1abac9d2aa8..ba0f305ffad 100644 --- a/jdk/src/share/lib/security/java.security-linux +++ b/jdk/src/share/lib/security/java.security-linux @@ -185,7 +185,7 @@ package.definition=sun.,\ com.sun.org.glassfish.gmbal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools + jdk.nashorn.tools. # # Determines whether this properties file can be appended to diff --git a/jdk/src/share/lib/security/java.security-solaris b/jdk/src/share/lib/security/java.security-solaris index a24634e61b9..e51581e8c3a 100644 --- a/jdk/src/share/lib/security/java.security-solaris +++ b/jdk/src/share/lib/security/java.security-solaris @@ -187,7 +187,7 @@ package.definition=sun.,\ com.sun.org.glassfish.gmbal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools + jdk.nashorn.tools. # # Determines whether this properties file can be appended to From c3647bf3a612c652ef0001d1bab744b0f296efe2 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Mon, 25 Mar 2013 14:29:13 +0000 Subject: [PATCH 111/137] 8010668: builtin JNI libraries should not be unloaded Reviewed-by: chegar, alanb --- jdk/src/share/native/java/lang/ClassLoader.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/native/java/lang/ClassLoader.c b/jdk/src/share/native/java/lang/ClassLoader.c index 47c41b2bd84..776b2dd24e7 100644 --- a/jdk/src/share/native/java/lang/ClassLoader.c +++ b/jdk/src/share/native/java/lang/ClassLoader.c @@ -398,7 +398,9 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load if (cause) { (*env)->ExceptionClear(env); (*env)->Throw(env, cause); - JVM_UnloadLibrary(handle); + if (!isBuiltin) { + JVM_UnloadLibrary(handle); + } goto done; } @@ -409,7 +411,9 @@ Java_java_lang_ClassLoader_00024NativeLibrary_load "unsupported JNI version 0x%08X required by %s", jniVersion, cname); JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg); - JVM_UnloadLibrary(handle); + if (!isBuiltin) { + JVM_UnloadLibrary(handle); + } goto done; } (*env)->SetIntField(env, this, jniVersionID, jniVersion); @@ -458,7 +462,9 @@ Java_java_lang_ClassLoader_00024NativeLibrary_unload (*env)->GetJavaVM(env, &jvm); (*JNI_OnUnload)(jvm, NULL); } - JVM_UnloadLibrary(handle); + if (!isBuiltin) { + JVM_UnloadLibrary(handle); + } JNU_ReleaseStringPlatformChars(env, name, cname); } From 0e9d409036892e67fb0d3928e7845692cd58459a Mon Sep 17 00:00:00 2001 From: Bharadwaj Yadavalli Date: Mon, 25 Mar 2013 09:36:15 -0700 Subject: [PATCH 112/137] 8009552: test/vm/verifier/TestStaticIF.java failing with hs25.0-b Remove support for verification of class files with version 52 and above from type inference verifier. Reviewed-by: acorn, hseigel --- hotspot/src/share/vm/classfile/verifier.cpp | 6 --- .../test/runtime/8007736/TestStaticIF.java | 44 ------------------- 2 files changed, 50 deletions(-) delete mode 100644 hotspot/test/runtime/8007736/TestStaticIF.java diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 4ff142a9200..96912df1971 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -63,7 +63,6 @@ #define NOFAILOVER_MAJOR_VERSION 51 #define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION 51 -#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52 // Access to external entry for VerifyClassCodes - old byte code verifier @@ -2322,11 +2321,6 @@ void ClassVerifier::verify_invoke_instructions( types = (1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref); break; - case Bytecodes::_invokestatic: - types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ? - (1 << JVM_CONSTANT_Methodref) : - ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)); - break; default: types = 1 << JVM_CONSTANT_Methodref; } diff --git a/hotspot/test/runtime/8007736/TestStaticIF.java b/hotspot/test/runtime/8007736/TestStaticIF.java deleted file mode 100644 index d3c3239e816..00000000000 --- a/hotspot/test/runtime/8007736/TestStaticIF.java +++ /dev/null @@ -1,44 +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 8007736 - * @summary Test static interface method. - * @run main/othervm -Xverify:all TestStaticIF - */ - -public class TestStaticIF implements StaticMethodInInterface { - - public static void main(String[] args) { - System.out.printf("main: %s%n", StaticMethodInInterface.get()); - } -} - -interface StaticMethodInInterface { - - public static String get() { - return "Hello from StaticMethodInInterface.get()"; - } -} From 9309aac6971c4ab58f370e5513e15a2e1f1bd4ad Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Mon, 25 Mar 2013 16:53:02 -0700 Subject: [PATCH 113/137] 8010521: jdk8 l10n resource file translation update 2 Reviewed-by: naoto, yhuang --- .../se/impl/orbutil/resources/sunorb_de.properties | 2 +- .../se/impl/orbutil/resources/sunorb_es.properties | 2 +- .../se/impl/orbutil/resources/sunorb_fr.properties | 2 +- .../se/impl/orbutil/resources/sunorb_it.properties | 10 +++++----- .../se/impl/orbutil/resources/sunorb_ja.properties | 10 +++++----- .../se/impl/orbutil/resources/sunorb_ko.properties | 2 +- .../se/impl/orbutil/resources/sunorb_pt_BR.properties | 2 +- .../se/impl/orbutil/resources/sunorb_sv.properties | 2 +- .../se/impl/orbutil/resources/sunorb_zh_CN.properties | 2 +- .../se/impl/orbutil/resources/sunorb_zh_TW.properties | 2 +- .../classes/com/sun/tools/corba/se/idl/idl_ja.prp | 8 ++++---- .../classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp | 2 +- .../corba/se/idl/toJavaPortable/toJavaPortable_ja.prp | 4 ++-- .../se/idl/toJavaPortable/toJavaPortable_zh_CN.prp | 2 +- 14 files changed, 26 insertions(+), 26 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_de.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_de.properties index 3343f1fb225..b33670ea62f 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_de.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_de.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_es.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_es.properties index 96707e40f75..12562891caa 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_es.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_es.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_fr.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_fr.properties index b46f46cd619..b1b64f1f9f3 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_fr.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_fr.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_it.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_it.properties index 7d39881dddf..908f7a4e2cb 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_it.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_it.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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,9 +23,9 @@ # questions. # -orbd.usage=Utilizzo: {0} \n\ndove include:\n -port Porta di attivazione da cui avviare ORBD, valore predefinito 1049 (opzionale)\n -defaultdb Directory per i file ORBD, valore predefinito "./orb.db" (opzionale)\n -serverid ID server per ORBD, valore predefinito 1 (opzionale)\n -ORBInitialPort Porta iniziale (richiesta)\n -ORBInitialHost HostName iniziale (richiesto)\n +orbd.usage=Uso: {0} \n\ndove include:\n -port Porta di attivazione da cui avviare ORBD, valore predefinito 1049 (opzionale)\n -defaultdb Directory per i file ORBD, valore predefinito "./orb.db" (opzionale)\n -serverid ID server per ORBD, valore predefinito 1 (opzionale)\n -ORBInitialPort Porta iniziale (richiesta)\n -ORBInitialHost HostName iniziale (richiesto)\n -servertool.usage=Utilizzo: {0} \n\ndove include:\n -ORBInitialPort Porta iniziale (richiesta)\n -ORBInitialHost HostName iniziale (richiesto)\n +servertool.usage=Uso: {0} \n\ndove include:\n -ORBInitialPort Porta iniziale (richiesta)\n -ORBInitialHost HostName iniziale (richiesto)\n servertool.banner=\n\nBenvenuti in Java IDL Server Tool \nimmettere i comandi quando richiesto \n servertool.shorthelp=\n\n\tComandi disponibili:\n\t-------------------- \n servertool.baddef=Definizione server errata: {0} @@ -82,13 +82,13 @@ servertool.quit1=esci dall'applicazione corrente servertool.help=\thelp\n\tOR\n\thelp \n servertool.help1=Guida -servertool.orbidmap=\tUtilizzo: orblist [ -serverid | -applicationName ]\n +servertool.orbidmap=\tUso: orblist [ -serverid | -applicationName ]\n servertool.orbidmap1=lista nomi orb e relativa mappatura servertool.orbidmap2=\n\tId ORB\t\tNome ORB\n\t------\t\t--------\n pnameserv.success=NameServer persistente avviato correttamente -bootstrap.usage=Utilizzo: {0} \n\ndove include:\n -ORBInitialPort Porta iniziale (richiesta)\n -InitialServicesFile File contenente la lista dei servizi iniziali (richiesto)\n +bootstrap.usage=Uso: {0} \n\ndove include:\n -ORBInitialPort Porta iniziale (richiesta)\n -InitialServicesFile File contenente la lista dei servizi iniziali (richiesto)\n bootstrap.success=impostazione porta su {0} e lettura servizi da {1} in corso bootstrap.filenotreadable=il file {0} non \u00E8 leggibile bootstrap.filenotfound=impossibile trovare il file {0} diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ja.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ja.properties index 8911bd177f1..f067fd9de63 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ja.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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,12 +60,12 @@ servertool.getserverid=\n\tgetserverid [ -applicationName ]\n servertool.getserverid1=applicationName\u306E\u30B5\u30FC\u30D0\u30FCID\u3092\u8FD4\u3057\u307E\u3059 servertool.getserverid2=\tapplicationName {0}\u306E\u30B5\u30FC\u30D0\u30FCID\u306F{1}\u3067\u3059 -servertool.list=\n\t\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\n +servertool.list=\n\tlist\n servertool.list1=\u767B\u9332\u3055\u308C\u305F\u3059\u3079\u3066\u306E\u30B5\u30FC\u30D0\u30FC\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059 servertool.list2=\n\t\u30B5\u30FC\u30D0\u30FCID\t\u30B5\u30FC\u30D0\u30FC\u306E\u30AF\u30E9\u30B9\u540D\t\t\u30B5\u30FC\u30D0\u30FC\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\n\t---------\t----------------\t\t----------------------\n -servertool.listactive=\n\t\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30B5\u30FC\u30D0\u30FC\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059 +servertool.listactive=\n\tlistactive servertool.listactive1=\u73FE\u5728\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30B5\u30FC\u30D0\u30FC\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059 -servertool.listappnames=\tapplicationNames\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059\n +servertool.listappnames=\tlistappnames\n servertool.listappnames1=\u73FE\u5728\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308BapplicationNames\u306E\u30EA\u30B9\u30C8\u3092\u8868\u793A\u3057\u307E\u3059 servertool.listappnames2=\u73FE\u5728\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u308B\u30B5\u30FC\u30D0\u30FCapplicationNames: @@ -76,7 +76,7 @@ servertool.startserver=\n\tstartup [ -serverid | -applicationName \n diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ko.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ko.properties index 7d58921d36f..7be6158a9f5 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ko.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_ko.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_pt_BR.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_pt_BR.properties index 1c5dbce8243..81ca99db3d8 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_pt_BR.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_pt_BR.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_sv.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_sv.properties index eaf5b45f79a..c11488e9f48 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_sv.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_sv.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_CN.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_CN.properties index e03e66b400f..6dce9e6e827 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_CN.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_TW.properties b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_TW.properties index 075fa02a2ba..db797522663 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_TW.properties +++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_TW.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2005, 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 diff --git a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp index ab409ba6fa5..80fbd04f9d8 100644 --- a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp +++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp @@ -68,7 +68,7 @@ Compile.parsing=%0\u306E\u89E3\u6790\u4E2D Compile.parseDone=\u5B8C\u4E86 - %0 Compile.generating=%0\u306E\u751F\u6210\u4E2D Compile.genDone=\u5B8C\u4E86 - %0 -Deprecated.keyword=\u8B66\u544A: \u30AD\u30FC\u30EF\u30FC\u30C9`%0'\u306F\u63A8\u5968\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 +Deprecated.keyword=\u8B66\u544A: \u30AD\u30FC\u30EF\u30FC\u30C9`%0'\u306F\u975E\u63A8\u5968\u3067\u3059\u3002 EvaluationException.1=%0\u6F14\u7B97\u5B50\u306E\u30AA\u30DA\u30E9\u30F3\u30C9\u306B\u4E00\u8CAB\u6027\u304C\u3042\u308A\u307E\u305B\u3093: %1\u304A\u3088\u3073%2\u3002 EvaluationException.2=%0\u6F14\u7B97\u5B50\u306E\u30AA\u30DA\u30E9\u30F3\u30C9\u306F\u3001%1\u3067\u306F\u306A\u304F\u6570\u5024\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 EvaluationException.or=\u30D3\u30C3\u30C8\u5358\u4F4D\u306EOR\u6F14\u7B97 @@ -114,7 +114,7 @@ ParseException.badRepIDPrefix=%0 (\u884C%1): \u30A4\u30F3\u30BF\u30D5\u30A7\u30F ParseException.badState=%0 (\u884C%1): %2\u306F\u30B9\u30C6\u30FC\u30C8\u30D5\u30EB\u30FB\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306B\u3067\u304D\u307E\u305B\u3093\u3002\u8907\u6570\u306E\u30B9\u30C6\u30FC\u30C8\u30D5\u30EB\u89AA\u304C\u3042\u308A\u307E\u3059\u3002\n%3\n%4 ParseException.branchLabel=%0 (\u884C%1): case %2\u306F\u3059\u3067\u306B\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u3059\u3002\n%3\n%4 ParseException.branchName=%0 (\u884C%1): %2\u3068\u3044\u3046\u540D\u524D\u306E\u5206\u5C90\u306F\u3059\u3067\u306B\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u3059\u3002\n%3\n%4 -ParseException.duplicateInit=%0 (\u884C%1): \u521D\u671F\u5316\u5B50\u306B\u306F\u524D\u306E\u521D\u671F\u5316\u5B50\u3068\u540C\u3058\u7F72\u540D\u304C\u3042\u308A\u307E\u3059\u3002\n%2\n%3 +ParseException.duplicateInit=%0 (\u884C%1): \u521D\u671F\u5316\u5B50\u306B\u306F\u524D\u306E\u521D\u671F\u5316\u5B50\u3068\u540C\u3058\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u3042\u308A\u307E\u3059\u3002\n%2\n%3 ParseException.duplicateState=%0 (\u884C%1): \u30C7\u30FC\u30BF\u30FB\u30E1\u30F3\u30D0\u30FC%2\u306E\u540D\u524D\u304C\u524D\u306E\u30C7\u30FC\u30BF\u30FB\u30E1\u30F3\u30D0\u30FC\u3068\u540C\u3058\u3067\u3059\u3002\n%3\n%4 ParseException.elseNoIf=%0 (\u884C%1): \u4E00\u81F4\u3059\u308B#if\u304C\u306A\u3044#else\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\n%2\n%3 ParseException.endNoIf=%0 (\u884C%1): \u4E00\u81F4\u3059\u308B#if\u304C\u306A\u3044#endif\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\n%2\n%3 @@ -146,7 +146,7 @@ ParseException.selfInherit=%0 (\u884C%1): %2\u3092\u305D\u308C\u81EA\u4F53\u304B ParseException.stringTooLong=%0 (\u884C%1): "%2"\u306F%3\u6587\u5B57\u4EE5\u5185\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n%4\n%5 ParseException.syntax1=%0 (\u884C%1): `%2'\u304C\u5FC5\u8981\u3067\u3059\u304C\u3001`%3'\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\n%4\n%5 ParseException.syntax2=%0 (\u884C%1): %2\u306E1\u3064\u304C\u5FC5\u8981\u3067\u3059\u304C\u3001`%3'\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F\u3002\n%4\n%5 -ParseException.unclosed=%0: \u30B3\u30E1\u30F3\u30C8\u3067\u4E88\u671F\u3057\u306A\u3044EOF\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002 +ParseException.unclosed=%0: \u30B3\u30E1\u30F3\u30C8\u3067\u4E88\u671F\u3057\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002 ParseException.undeclaredType=%0 (\u884C%1): %2\u306F\u5BA3\u8A00\u3055\u308C\u3066\u3044\u306A\u3044\u578B\u3067\u3059\u3002\n%3\n%4 ParseException.warning=%0 (\u884C%1): %2\n%3\n%4 ParseException.constExprType=%0 (\u884C%1): \u5B9A\u6570\u5F0F\u306E\u578B\u306F%2\u3067\u3059\u304C\u3001%3\u306B\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n%4\n%5 @@ -173,5 +173,5 @@ default=\u30A8\u30E9\u30FC\u3002\u5B58\u5728\u3057\u306A\u3044\u30E1\u30C3\u30BB # -i, -d, -keep, -emitAll, -noWarn, -v, -verbose, -version, #define # Do not translate the string "java com.sun.tools.corba.se.idl.Compile" -usage=\u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u4F7F\u7528\u65B9\u6CD5:\n\ java com.sun.tools.corba.se.idl.Compile [options] \n\u306FIDL\u5B9A\u7FA9\u3092\u542B\u3080\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3067\u3001\n[options]\u306F\u6B21\u306B\u30EA\u30B9\u30C8\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u5408\u305B\u3067\u3059\u3002\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n\u7701\u7565\u53EF\u80FD\u3067\u3001\u4EFB\u610F\u306E\u9806\u5E8F\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u306F\u5FC5\u9808\u3067\u3001\n\u6700\u5F8C\u306B\u8868\u793A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\ \n\u30AA\u30D7\u30B7\u30E7\u30F3:\n-d IDL\u30D5\u30A1\u30A4\u30EB\u306E\u6B21\u306E\u884C\u3068\n\ \u540C\u3058\u3067\u3059: #define \n-emitAll #included\u30D5\u30A1\u30A4\u30EB\u3067\u898B\u3064\u304B\u3063\u305F\u30BF\u30A4\u30D7\u3092\u542B\u3080\u3001\u3059\u3079\u3066\u306E\u30BF\u30A4\u30D7\u3092\n\ \u767A\u884C\u3057\u307E\u3059\u3002\n-i \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u304C\n\ \u30B9\u30AD\u30E3\u30F3\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5225\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002\n-keep \u751F\u6210\u3055\u308C\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3059\u3067\u306B\u5B58\u5728\u3059\u308B\u5834\u5408\u306F\u3001\u4E0A\u66F8\u304D\n\ \u3057\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u4E0A\u66F8\u304D\u3055\u308C\u307E\u3059\u3002\n-noWarn \u8B66\u544A\u3092\u51FA\u3055\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002\n-v, -verbose \u8A73\u7D30\u30E2\u30FC\u30C9\u3002\n-version \u30D0\u30FC\u30B8\u30E7\u30F3\u756A\u53F7\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n +usage=\u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u4F7F\u7528\u65B9\u6CD5:\n java com.sun.tools.corba.se.idl.Compile [options] \n\u306FIDL\u5B9A\u7FA9\u3092\u542B\u3080\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3067\u3001\n[options]\u306F\u6B21\u306B\u30EA\u30B9\u30C8\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u5408\u305B\u3067\u3059\u3002\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n\u7701\u7565\u53EF\u80FD\u3067\u3001\u4EFB\u610F\u306E\u9806\u5E8F\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u306F\u5FC5\u9808\u3067\u3001\n\u6700\u5F8C\u306B\u8868\u793A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n \n\u30AA\u30D7\u30B7\u30E7\u30F3:\n-d IDL\u30D5\u30A1\u30A4\u30EB\u306E\u6B21\u306E\u884C\u3068\n \u540C\u3058\u3067\u3059: #define \n-emitAll #included\u30D5\u30A1\u30A4\u30EB\u3067\u898B\u3064\u304B\u3063\u305F\u30BF\u30A4\u30D7\u3092\u542B\u3080\u3001\u3059\u3079\u3066\u306E\u30BF\u30A4\u30D7\u3092\n \u767A\u884C\u3057\u307E\u3059\u3002\n-i \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u304C\n \u30B9\u30AD\u30E3\u30F3\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5225\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002\n-keep \u751F\u6210\u3055\u308C\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3059\u3067\u306B\u5B58\u5728\u3059\u308B\u5834\u5408\u306F\u3001\u4E0A\u66F8\u304D\n \u3057\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u4E0A\u66F8\u304D\u3055\u308C\u307E\u3059\u3002\n-noWarn \u8B66\u544A\u3092\u51FA\u3055\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002\n-v, -verbose \u8A73\u7D30\u30E2\u30FC\u30C9\u3002\n-version \u30D0\u30FC\u30B8\u30E7\u30F3\u756A\u53F7\u3092\u8868\u793A\u3057\u307E\u3059\u3002\n diff --git a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp index ed66b727a78..630b55d0d7f 100644 --- a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp +++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp @@ -173,5 +173,5 @@ default=\u9519\u8BEF! \u8BF7\u6C42\u4E86\u4E0D\u5B58\u5728\u7684\u6D88\u606F\u30 # -i, -d, -keep, -emitAll, -noWarn, -v, -verbose, -version, #define # Do not translate the string "java com.sun.tools.corba.se.idl.Compile" -usage=\u7F16\u8BD1\u5668\u7528\u6CD5:\n\ java com.sun.tools.corba.se.idl.Compile [\u9009\u9879] \n\u5176\u4E2D, \u662F\u5305\u542B IDL \u5B9A\u4E49\u7684\u6587\u4EF6\u7684\u540D\u79F0, \u800C\n[\u9009\u9879] \u662F\u4E0B\u5217\u9009\u9879\u7684\u4EFB\u610F\u7EC4\u5408\u3002\u8FD9\u4E9B\u9009\u9879\n\u662F\u53EF\u9009\u7684, \u5E76\u4E14\u663E\u793A\u987A\u5E8F\u5E76\u4E0D\u56FA\u5B9A; \u662F\u5FC5\u9700\u7684\n\u5E76\u4E14\u5FC5\u987B\u663E\u793A\u5728\u6700\u540E\u3002\n\ \n\u9009\u9879:\n-d <\u7B26\u53F7> \u8FD9\u7B49\u540C\u4E8E IDL \u6587\u4EF6\u4E2D\u7684\n\ \u4E0B\u9762\u4E00\u884C: #define <\u7B26\u53F7>\n-emitAll \u53D1\u51FA\u6240\u6709\u7C7B\u578B, \u5305\u62EC\u5728 #included\n\ \u6587\u4EF6\u4E2D\u627E\u5230\u7684\u7C7B\u578B\u3002\n-i <\u5305\u542B\u8DEF\u5F84> \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u4E2D\u626B\u63CF\n\ \u5305\u542B\u7684\u6587\u4EF6\u3002\u6B64\u9009\u9879\u5C06\u6DFB\u52A0\u53E6\u4E00\u4E2A\u76EE\u5F55\u3002\n-keep \u5982\u679C\u8981\u751F\u6210\u7684\u6587\u4EF6\u5DF2\u5B58\u5728, \u8BF7\u4E0D\u8981\n\ \u8986\u76D6\u5B83\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F1A\u8986\u76D6\u5B83\u3002\n-noWarn \u9690\u85CF\u8B66\u544A\u3002\n-v, -verbose \u8BE6\u7EC6\u6A21\u5F0F\u3002\n-version \u663E\u793A\u7248\u672C\u53F7\u3002\n +usage=\u7F16\u8BD1\u5668\u7528\u6CD5:\n java com.sun.tools.corba.se.idl.Compile [\u9009\u9879] \n\u5176\u4E2D, \u662F\u5305\u542B IDL \u5B9A\u4E49\u7684\u6587\u4EF6\u7684\u540D\u79F0, \u800C\n[\u9009\u9879] \u662F\u4E0B\u5217\u9009\u9879\u7684\u4EFB\u610F\u7EC4\u5408\u3002\u8FD9\u4E9B\u9009\u9879\n\u662F\u53EF\u9009\u7684, \u5E76\u4E14\u663E\u793A\u987A\u5E8F\u5E76\u4E0D\u56FA\u5B9A; \u662F\u5FC5\u9700\u7684\n\u5E76\u4E14\u5FC5\u987B\u663E\u793A\u5728\u6700\u540E\u3002\n \n\u9009\u9879:\n-d <\u7B26\u53F7> \u8FD9\u7B49\u540C\u4E8E IDL \u6587\u4EF6\u4E2D\u7684\n \u4E0B\u9762\u4E00\u884C: #define <\u7B26\u53F7>\n-emitAll \u53D1\u51FA\u6240\u6709\u7C7B\u578B, \u5305\u62EC\u5728 #included\n \u6587\u4EF6\u4E2D\u627E\u5230\u7684\u7C7B\u578B\u3002\n-i <\u5305\u542B\u8DEF\u5F84> \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u4E2D\u626B\u63CF\n \u5305\u542B\u7684\u6587\u4EF6\u3002\u6B64\u9009\u9879\u5C06\u6DFB\u52A0\u53E6\u4E00\u4E2A\u76EE\u5F55\u3002\n-keep \u5982\u679C\u8981\u751F\u6210\u7684\u6587\u4EF6\u5DF2\u5B58\u5728, \u8BF7\u4E0D\u8981\n \u8986\u76D6\u5B83\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F1A\u8986\u76D6\u5B83\u3002\n-noWarn \u9690\u85CF\u8B66\u544A\u3002\n-v, -verbose \u8BE6\u7EC6\u6A21\u5F0F\u3002\n-version \u663E\u793A\u7248\u672C\u53F7\u3002\n diff --git a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp index 1171c88b7f2..35cee81cd2d 100644 --- a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp +++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp @@ -53,7 +53,7 @@ # toJavaProlog1=%0\u306B\u3088\u3063\u3066\u751F\u6210\u3055\u308C\u307E\u3057\u305F toJavaProlog2=%0\u304B\u3089 -PreEmit.indeterminateTypeInfo=%0\u306E\u30BF\u30A4\u30D7\u60C5\u5831\u3092\u5224\u65AD\u3067\u304D\u307E\u305B\u3093\u3002 +PreEmit.indeterminateTypeInfo=%0\u306E\u30BF\u30A4\u30D7\u60C5\u5831\u3092\u5224\u5225\u3067\u304D\u307E\u305B\u3093\u3002 InterfaceGen.noImpl=%0\u306E\u30ED\u30FC\u30AB\u30EB\u5B9F\u88C5\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002 Version.product=IDL-to-Java\u30B3\u30F3\u30D1\u30A4\u30E9(\u30DD\u30FC\u30BF\u30D6\u30EB)\u3001\u30D0\u30FC\u30B8\u30E7\u30F3"%0" Version.number=3.2 @@ -65,4 +65,4 @@ NameModifier.InvalidChar=\u30D1\u30BF\u30FC\u30F3\u306B\u7121\u52B9\u306A\u6587\ # -d, -emitAll, -f, -i, -keep, -m, -sep, -pkgPrefix, -td, -v, -verbose, -version, -implbase # Do not translate the string "java com.sun.tools.corba.se.idl.toJavaPortable.Compile" # -usage=\u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u4F7F\u7528\u65B9\u6CD5:\n\n\ java com.sun.tools.corba.se.idl.toJavaPortable.Compile [options] \n\n\u306FIDL\u5B9A\u7FA9\u3092\u542B\u3080\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3067\u3001\n[options]\u306F\u6B21\u306B\u30EA\u30B9\u30C8\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u5408\u305B\u3067\u3059\u3002\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n\u7701\u7565\u53EF\u80FD\u3067\u3001\u4EFB\u610F\u306E\u9806\u5E8F\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u306F\u5FC5\u9808\u3067\u3001\n\u6700\u5F8C\u306B\u8868\u793A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\ \n\u30AA\u30D7\u30B7\u30E7\u30F3:\n-d IDL\u30D5\u30A1\u30A4\u30EB\u306E\u6B21\u306E\u884C\u3068\n\ \u540C\u3058\u3067\u3059: #define \n-emitAll #included\u30D5\u30A1\u30A4\u30EB\u3067\u898B\u3064\u304B\u3063\u305F\u30BF\u30A4\u30D7\u3092\u542B\u3080\u3001\u3059\u3079\u3066\u306E\u30BF\u30A4\u30D7\u3092\u767A\u884C\u3057\u307E\u3059\u3002\n-f \u767A\u884C\u3059\u308B\u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002\u306Fclient\u3001\n\ server\u3001all\u3001serverTIE\u3001allTIE\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002serverTIE\u3068allTIE\u306F\n\ \u59D4\u4EFB\u30E2\u30C7\u30EB\u30FB\u30B9\u30B1\u30EB\u30C8\u30F3\u3092\u767A\u884C\u3057\u307E\u3059\u3002\u3053\u306E\u30D5\u30E9\u30B0\u3092\n\ \u4F7F\u7528\u3057\u306A\u3044\u5834\u5408\u306F\u3001-fclient\u3068\u307F\u306A\u3055\u308C\u307E\u3059\u3002\n-i \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u304C\n\ \u30B9\u30AD\u30E3\u30F3\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5225\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002\n-keep \u751F\u6210\u3055\u308C\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3059\u3067\u306B\u5B58\u5728\u3059\u308B\u5834\u5408\u306F\u3001\u4E0A\u66F8\u304D\n\ \u3057\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u4E0A\u66F8\u304D\u3055\u308C\u307E\u3059\u3002\n-noWarn \u8B66\u544A\u3092\u51FA\u3055\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002\n-oldImplBase \u53E4\u3044(1.4\u4EE5\u524D) JDK ORB\u3068\u4E92\u63DB\u6027\u306E\u3042\u308B\u30B9\u30B1\u30EB\u30C8\u30F3\u3092\u751F\u6210\u3057\u307E\u3059\u3002\n-pkgPrefix \u30D5\u30A1\u30A4\u30EB\u30FB\u30B9\u30B3\u30FC\u30D7\u3067\u30BF\u30A4\u30D7\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u304C\u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\n\ \u306B\u5BFE\u3057\u3066\u751F\u6210\u3055\u308C\u305F\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u306EJava\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u3092\n\ \u3067\u59CB\u3081\u307E\u3059\u3002\n-pkgTranslate \u30BF\u30A4\u30D7\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u304C\u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\n\ \u751F\u6210\u3055\u308C\u305FJava\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u3067\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002pkgPrefix\u306E\n\ \u5909\u66F4\u304C\u5148\u306B\u884C\u308F\u308C\u308B\u3053\u3068\u306B\u6CE8\u610F\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n\ \u6B63\u5F0F\u540D\u3068\u5B8C\u5168\u306B\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u307E\u305F\u3001\u3092\n\ org\u3001org.omg\u307E\u305F\u306Forg.omg\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\n-skeletonName \u30D1\u30BF\u30FC\u30F3\u306B\u5F93\u3063\u3066\u30B9\u30B1\u30EB\u30C8\u30F3\u306B\u540D\u524D\u3092\u4ED8\u3051\u307E\u3059\u3002\n\ \u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\ POA\u30D9\u30FC\u30B9\u30FB\u30AF\u30E9\u30B9\u306E\u5834\u5408\u306F%POA (-fserver\u307E\u305F\u306F-fall) \n\ oldImplBase\u30D9\u30FC\u30B9\u30FB\u30AF\u30E9\u30B9\u306E\u5834\u5408\u306F_%ImplBase\n\ (-oldImplBase\u304A\u3088\u3073(-fserver\u307E\u305F\u306F-fall))\u3002\n-td
\u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u304B\u308F\u308A\u306B\u3092\n\ \u4F7F\u7528\u3057\u307E\u3059\u3002\n-tieName \u30D1\u30BF\u30FC\u30F3\u306B\u5F93\u3063\u3066tie\u306B\u540D\u524D\u3092\u4ED8\u3051\u307E\u3059\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n\ POA tie\u306E\u5834\u5408\u306F%POATie (-fserverTie\u307E\u305F\u306F-fallTie) \n\ oldImplBase tie\u306E\u5834\u5408\u306F%_Tie\n\ (-oldImplBase\u304A\u3088\u3073(-fserverTie\u307E\u305F\u306F-fallTie))\u3002\n-v, -verbose \u8A73\u7D30\u30E2\u30FC\u30C9\u3002\n-version \u30D0\u30FC\u30B8\u30E7\u30F3\u756A\u53F7\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3057\u307E\u3059\u3002\n +usage=\u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u4F7F\u7528\u65B9\u6CD5:\n\n java com.sun.tools.corba.se.idl.toJavaPortable.Compile [options] \n\n\u306FIDL\u5B9A\u7FA9\u3092\u542B\u3080\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3067\u3001\n[options]\u306F\u6B21\u306B\u30EA\u30B9\u30C8\u3059\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u5408\u305B\u3067\u3059\u3002\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n\u7701\u7565\u53EF\u80FD\u3067\u3001\u4EFB\u610F\u306E\u9806\u5E8F\u3067\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u306F\u5FC5\u9808\u3067\u3001\n\u6700\u5F8C\u306B\u8868\u793A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n \n\u30AA\u30D7\u30B7\u30E7\u30F3:\n-d IDL\u30D5\u30A1\u30A4\u30EB\u306E\u6B21\u306E\u884C\u3068\n \u540C\u3058\u3067\u3059: #define \n-emitAll #included\u30D5\u30A1\u30A4\u30EB\u3067\u898B\u3064\u304B\u3063\u305F\u30BF\u30A4\u30D7\u3092\u542B\u3080\u3001\u3059\u3079\u3066\u306E\u30BF\u30A4\u30D7\u3092\u767A\u884C\u3057\u307E\u3059\u3002\n-f \u767A\u884C\u3059\u308B\u30D0\u30A4\u30F3\u30C7\u30A3\u30F3\u30B0\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002\u306Fclient\u3001\n server\u3001all\u3001serverTIE\u3001allTIE\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002serverTIE\u3068allTIE\u306F\n \u59D4\u4EFB\u30E2\u30C7\u30EB\u30FB\u30B9\u30B1\u30EB\u30C8\u30F3\u3092\u767A\u884C\u3057\u307E\u3059\u3002\u3053\u306E\u30D5\u30E9\u30B0\u3092\n \u4F7F\u7528\u3057\u306A\u3044\u5834\u5408\u306F\u3001-fclient\u3068\u307F\u306A\u3055\u308C\u307E\u3059\u3002\n-i \u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u30A4\u30F3\u30AF\u30EB\u30FC\u30C9\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u304C\n \u30B9\u30AD\u30E3\u30F3\u3055\u308C\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u5225\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002\n-keep \u751F\u6210\u3055\u308C\u308B\u30D5\u30A1\u30A4\u30EB\u304C\u3059\u3067\u306B\u5B58\u5728\u3059\u308B\u5834\u5408\u306F\u3001\u4E0A\u66F8\u304D\n \u3057\u307E\u305B\u3093\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u4E0A\u66F8\u304D\u3055\u308C\u307E\u3059\u3002\n-noWarn \u8B66\u544A\u3092\u51FA\u3055\u306A\u3044\u3088\u3046\u306B\u3057\u307E\u3059\u3002\n-oldImplBase \u53E4\u3044(1.4\u4EE5\u524D) JDK ORB\u3068\u4E92\u63DB\u6027\u306E\u3042\u308B\u30B9\u30B1\u30EB\u30C8\u30F3\u3092\u751F\u6210\u3057\u307E\u3059\u3002\n-pkgPrefix \u30D5\u30A1\u30A4\u30EB\u30FB\u30B9\u30B3\u30FC\u30D7\u3067\u30BF\u30A4\u30D7\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u304C\u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\n \u306B\u5BFE\u3057\u3066\u751F\u6210\u3055\u308C\u305F\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u306EJava\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u3092\n \u3067\u59CB\u3081\u307E\u3059\u3002\n-pkgTranslate \u30BF\u30A4\u30D7\u307E\u305F\u306F\u30E2\u30B8\u30E5\u30FC\u30EB\u540D\u304C\u691C\u51FA\u3055\u308C\u305F\u5834\u5408\u3001\n \u751F\u6210\u3055\u308C\u305FJava\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u3067\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002pkgPrefix\u306E\n \u5909\u66F4\u304C\u5148\u306B\u884C\u308F\u308C\u308B\u3053\u3068\u306B\u6CE8\u610F\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\n \u6B63\u5F0F\u540D\u3068\u5B8C\u5168\u306B\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u307E\u305F\u3001\u3092\n org\u3001org.omg\u307E\u305F\u306Forg.omg\u306E\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u306B\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002\n-skeletonName \u30D1\u30BF\u30FC\u30F3\u306B\u5F93\u3063\u3066\u30B9\u30B1\u30EB\u30C8\u30F3\u306B\u540D\u524D\u3092\u4ED8\u3051\u307E\u3059\u3002\n \u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n POA\u30D9\u30FC\u30B9\u30FB\u30AF\u30E9\u30B9\u306E\u5834\u5408\u306F%POA (-fserver\u307E\u305F\u306F-fall) \n oldImplBase\u30D9\u30FC\u30B9\u30FB\u30AF\u30E9\u30B9\u306E\u5834\u5408\u306F_%ImplBase\n (-oldImplBase\u304A\u3088\u3073(-fserver\u307E\u305F\u306F-fall))\u3002\n-td \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u306F\u3001\u73FE\u5728\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u304B\u308F\u308A\u306B\u3092\n \u4F7F\u7528\u3057\u307E\u3059\u3002\n-tieName \u30D1\u30BF\u30FC\u30F3\u306B\u5F93\u3063\u3066tie\u306B\u540D\u524D\u3092\u4ED8\u3051\u307E\u3059\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:\n POA tie\u306E\u5834\u5408\u306F%POATie (-fserverTie\u307E\u305F\u306F-fallTie) \n oldImplBase tie\u306E\u5834\u5408\u306F%_Tie\n (-oldImplBase\u304A\u3088\u3073(-fserverTie\u307E\u305F\u306F-fallTie))\u3002\n-v, -verbose \u8A73\u7D30\u30E2\u30FC\u30C9\u3002\n-version \u30D0\u30FC\u30B8\u30E7\u30F3\u756A\u53F7\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3057\u307E\u3059\u3002\n diff --git a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp index dd385beab8f..ee77a65bb3c 100644 --- a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp +++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp @@ -65,4 +65,4 @@ NameModifier.InvalidChar=\u6A21\u5F0F\u4E2D\u5305\u542B\u65E0\u6548\u5B57\u7B26 # -d, -emitAll, -f, -i, -keep, -m, -sep, -pkgPrefix, -td, -v, -verbose, -version, -implbase # Do not translate the string "java com.sun.tools.corba.se.idl.toJavaPortable.Compile" # -usage=\u7F16\u8BD1\u5668\u7528\u6CD5:\n\n\ java com.sun.tools.corba.se.idl.toJavaPortable.Compile [\u9009\u9879] \n\n\u5176\u4E2D, \u662F\u5305\u542B IDL \u5B9A\u4E49\u7684\u6587\u4EF6\u7684\u540D\u79F0, \u800C\n[\u9009\u9879] \u662F\u4E0B\u5217\u9009\u9879\u7684\u4EFB\u610F\u7EC4\u5408\u3002\u9009\u9879\n\u662F\u53EF\u9009\u7684, \u5E76\u4E14\u663E\u793A\u987A\u5E8F\u5E76\u4E0D\u56FA\u5B9A; \u662F\u5FC5\u9700\u7684,\n\u5E76\u4E14\u5FC5\u987B\u663E\u793A\u5728\u6700\u540E\u3002\n\ \n\u9009\u9879:\n-d <\u7B26\u53F7> \u8FD9\u7B49\u540C\u4E8E IDL \u6587\u4EF6\u4E2D\u7684\n\ \u4E0B\u9762\u4E00\u884C: #define <\u7B26\u53F7>\n-emitAll \u53D1\u51FA\u6240\u6709\u7C7B\u578B, \u5305\u62EC\u5728 #included \u6587\u4EF6\u4E2D\u627E\u5230\u7684\u7C7B\u578B\u3002\n-f \u5B9A\u4E49\u8981\u53D1\u51FA\u54EA\u4E9B\u7ED1\u5B9A\u3002 \u662F client,\n\ server, all, serverTIE, allTIE \u4E4B\u4E00\u3002serverTIE \u548C allTIE\n\ \u5BFC\u81F4\u53D1\u51FA\u59D4\u6D3E\u6A21\u578B\u9AA8\u67B6\u3002\u5982\u679C\u672A\u4F7F\u7528\n\ \u6B64\u6807\u8BB0, \u5C06\u5047\u5B9A\u4E3A -fclient\u3002\n-i <\u5305\u542B\u8DEF\u5F84> \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u4E2D\u626B\u63CF\n\ \u5305\u542B\u7684\u6587\u4EF6\u3002\u6B64\u9009\u9879\u5C06\u6DFB\u52A0\u53E6\u4E00\u4E2A\u76EE\u5F55\u3002\n-keep \u5982\u679C\u8981\u751F\u6210\u7684\u6587\u4EF6\u5DF2\u5B58\u5728, \u8BF7\u4E0D\u8981\n\ \u8986\u76D6\u5B83\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F1A\u8986\u76D6\u5B83\u3002\n-noWarn \u9690\u85CF\u8B66\u544A\u3002\n-oldImplBase \u751F\u6210\u4E0E\u65E7\u7248 (1.4 \u7248\u4E4B\u524D) JDK ORB \u517C\u5BB9\u7684\u9AA8\u67B6\u3002\n-pkgPrefix <\u524D\u7F00> \u5F53\u5728\u6587\u4EF6\u8303\u56F4\u5185\u9047\u5230\u7C7B\u578B\u6216\u6A21\u5757\u540D \u65F6,\n\ \u5728\u4E3A \u751F\u6210\u7684\u6240\u6709\u6587\u4EF6\u7684 Java \u7A0B\u5E8F\u5305\u540D\u524D\n\ \u6DFB\u52A0 <\u524D\u7F00>\u3002\n-pkgTranslate \u5F53\u9047\u5230\u7C7B\u578B\u6216\u6A21\u5757\u540D \u65F6, \u5728\n\ \u751F\u6210\u7684 Java \u7A0B\u5E8F\u5305\u4E2D\u5C06\u5176\u66FF\u6362\u4E3A \u3002\u8BF7\u6CE8\u610F, \n\ \u5C06\u9996\u5148\u8FDB\u884C pkgPrefix \u66F4\u6539\u3002 \u5FC5\u987B\u4E0E\n\ \u5B8C\u6574\u7A0B\u5E8F\u5305\u540D\u5B8C\u5168\u5339\u914D\u3002\u53E6\u5916, \u4E0D\u80FD\u4E3A\n\ org, org.omg \u6216 org.omg \u7684\u4EFB\u4F55\u5B50\u7A0B\u5E8F\u5305\u3002\n-skeletonName \u6839\u636E\u6A21\u5F0F\u547D\u540D\u9AA8\u67B6\u3002\n\ \u9ED8\u8BA4\u503C\u4E3A:\n\ %POA \u8868\u793A POA \u57FA\u7C7B (-fserver \u6216 -fall) \n\ _%ImplBase \u8868\u793A oldImplBase \u57FA\u7C7B\n\ (-oldImplBase \u548C (-fserver \u6216 -fall))\u3002\n-td \u4F7F\u7528 \u8868\u793A\u8F93\u51FA\u76EE\u5F55\u4EE5\u4EE3\u66FF\n\ \u5F53\u524D\u76EE\u5F55\u3002\n-tieName \u6839\u636E\u6A21\u5F0F\u547D\u540D tie\u3002\u9ED8\u8BA4\u503C\u4E3A:\n\ %POATie \u8868\u793A POA tie (-fserverTie \u6216 -fallTie) \n\ %_Tie \u8868\u793A oldImplBase tie\n\ (-oldImplBase \u548C (-fserverTie \u6216 -fallTie))\u3002\n-v, -verbose \u8BE6\u7EC6\u6A21\u5F0F\u3002\n-version \u663E\u793A\u7248\u672C\u53F7\u5E76\u9000\u51FA\u3002\n +usage=\u7F16\u8BD1\u5668\u7528\u6CD5:\n\n java com.sun.tools.corba.se.idl.toJavaPortable.Compile [\u9009\u9879] \n\n\u5176\u4E2D, \u662F\u5305\u542B IDL \u5B9A\u4E49\u7684\u6587\u4EF6\u7684\u540D\u79F0, \u800C\n[\u9009\u9879] \u662F\u4E0B\u5217\u9009\u9879\u7684\u4EFB\u610F\u7EC4\u5408\u3002\u9009\u9879\n\u662F\u53EF\u9009\u7684, \u5E76\u4E14\u663E\u793A\u987A\u5E8F\u5E76\u4E0D\u56FA\u5B9A; \u662F\u5FC5\u9700\u7684,\n\u5E76\u4E14\u5FC5\u987B\u663E\u793A\u5728\u6700\u540E\u3002\n \n\u9009\u9879:\n-d <\u7B26\u53F7> \u8FD9\u7B49\u540C\u4E8E IDL \u6587\u4EF6\u4E2D\u7684\n \u4E0B\u9762\u4E00\u884C: #define <\u7B26\u53F7>\n-emitAll \u53D1\u51FA\u6240\u6709\u7C7B\u578B, \u5305\u62EC\u5728 #included \u6587\u4EF6\u4E2D\u627E\u5230\u7684\u7C7B\u578B\u3002\n-f \u5B9A\u4E49\u8981\u53D1\u51FA\u54EA\u4E9B\u7ED1\u5B9A\u3002 \u662F client,\n server, all, serverTIE, allTIE \u4E4B\u4E00\u3002serverTIE \u548C allTIE\n \u5BFC\u81F4\u53D1\u51FA\u59D4\u6D3E\u6A21\u578B\u9AA8\u67B6\u3002\u5982\u679C\u672A\u4F7F\u7528\n \u6B64\u6807\u8BB0, \u5C06\u5047\u5B9A\u4E3A -fclient\u3002\n-i <\u5305\u542B\u8DEF\u5F84> \u9ED8\u8BA4\u60C5\u51B5\u4E0B, \u5C06\u5728\u5F53\u524D\u76EE\u5F55\u4E2D\u626B\u63CF\n \u5305\u542B\u7684\u6587\u4EF6\u3002\u6B64\u9009\u9879\u5C06\u6DFB\u52A0\u53E6\u4E00\u4E2A\u76EE\u5F55\u3002\n-keep \u5982\u679C\u8981\u751F\u6210\u7684\u6587\u4EF6\u5DF2\u5B58\u5728, \u8BF7\u4E0D\u8981\n \u8986\u76D6\u5B83\u3002\u9ED8\u8BA4\u60C5\u51B5\u4E0B\u4F1A\u8986\u76D6\u5B83\u3002\n-noWarn \u9690\u85CF\u8B66\u544A\u3002\n-oldImplBase \u751F\u6210\u4E0E\u65E7\u7248 (1.4 \u7248\u4E4B\u524D) JDK ORB \u517C\u5BB9\u7684\u9AA8\u67B6\u3002\n-pkgPrefix <\u524D\u7F00> \u5F53\u5728\u6587\u4EF6\u8303\u56F4\u5185\u9047\u5230\u7C7B\u578B\u6216\u6A21\u5757\u540D \u65F6,\n \u5728\u4E3A \u751F\u6210\u7684\u6240\u6709\u6587\u4EF6\u7684 Java \u7A0B\u5E8F\u5305\u540D\u524D\n \u6DFB\u52A0 <\u524D\u7F00>\u3002\n-pkgTranslate \u5F53\u9047\u5230\u7C7B\u578B\u6216\u6A21\u5757\u540D \u65F6, \u5728\n \u751F\u6210\u7684 Java \u7A0B\u5E8F\u5305\u4E2D\u5C06\u5176\u66FF\u6362\u4E3A \u3002\u8BF7\u6CE8\u610F, \n \u5C06\u9996\u5148\u8FDB\u884C pkgPrefix \u66F4\u6539\u3002 \u5FC5\u987B\u4E0E\n \u5B8C\u6574\u7A0B\u5E8F\u5305\u540D\u5B8C\u5168\u5339\u914D\u3002\u53E6\u5916, \u4E0D\u80FD\u4E3A\n org, org.omg \u6216 org.omg \u7684\u4EFB\u4F55\u5B50\u7A0B\u5E8F\u5305\u3002\n-skeletonName \u6839\u636E\u6A21\u5F0F\u547D\u540D\u9AA8\u67B6\u3002\n \u9ED8\u8BA4\u503C\u4E3A:\n %POA \u8868\u793A POA \u57FA\u7C7B (-fserver \u6216 -fall) \n _%ImplBase \u8868\u793A oldImplBase \u57FA\u7C7B\n (-oldImplBase \u548C (-fserver \u6216 -fall))\u3002\n-td \u4F7F\u7528 \u8868\u793A\u8F93\u51FA\u76EE\u5F55\u4EE5\u4EE3\u66FF\n \u5F53\u524D\u76EE\u5F55\u3002\n-tieName \u6839\u636E\u6A21\u5F0F\u547D\u540D tie\u3002\u9ED8\u8BA4\u503C\u4E3A:\n %POATie \u8868\u793A POA tie (-fserverTie \u6216 -fallTie) \n %_Tie \u8868\u793A oldImplBase tie\n (-oldImplBase \u548C (-fserverTie \u6216 -fallTie))\u3002\n-v, -verbose \u8BE6\u7EC6\u6A21\u5F0F\u3002\n-version \u663E\u793A\u7248\u672C\u53F7\u5E76\u9000\u51FA\u3002\n From d414a7e8320879083a593d41ae4339ccaf606436 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 25 Mar 2013 17:19:16 -0700 Subject: [PATCH 114/137] 8007703: Remove com.sun.servicetag API Reviewed-by: dholmes, alanb, erikj --- jdk/make/com/sun/Makefile | 2 +- jdk/make/common/Release.gmk | 3 +-- jdk/makefiles/CopyFiles.gmk | 11 ----------- jdk/makefiles/CopyIntoClasses.gmk | 9 --------- jdk/makefiles/CreateJars.gmk | 3 +-- jdk/makefiles/GensrcProperties.gmk | 1 - jdk/makefiles/profile-includes.txt | 1 - jdk/makefiles/profile-rtjar-includes.txt | 1 - jdk/test/Makefile | 1 - 9 files changed, 3 insertions(+), 29 deletions(-) diff --git a/jdk/make/com/sun/Makefile b/jdk/make/com/sun/Makefile index 8b9d9dbe25b..052cd541032 100644 --- a/jdk/make/com/sun/Makefile +++ b/jdk/make/com/sun/Makefile @@ -45,7 +45,7 @@ SUBDIRS_management = jmx SUBDIRS_desktop = image SUBDIRS_enterprise = crypto/provider jndi \ org rowset net/httpserver -SUBDIRS_misc = $(SCRIPT_SUBDIR) tracing servicetag nio demo +SUBDIRS_misc = $(SCRIPT_SUBDIR) tracing nio demo SUBDIRS_tools = tools diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk index 5371d044b91..2cdfc0ef6ba 100644 --- a/jdk/make/common/Release.gmk +++ b/jdk/make/common/Release.gmk @@ -59,8 +59,7 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \ # This is an interim solution until the ct.sym is replaced # with a new module system (being discussed for JDK 8). # -EXPORTED_PRIVATE_PKGS = com.sun.servicetag \ - com.oracle.net \ +EXPORTED_PRIVATE_PKGS = com.oracle.net \ com.oracle.nio # 64-bit solaris has a few special cases. We define the variable diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk index 9c4dc0d7dec..0b4bbfd68ce 100644 --- a/jdk/makefiles/CopyFiles.gmk +++ b/jdk/makefiles/CopyFiles.gmk @@ -81,17 +81,6 @@ endif ########################################################################################## LIBDIR = $(JDK_OUTPUTDIR)/lib -SERVICETAG_LIBDIR = $(LIBDIR)/servicetag - -$(SERVICETAG_LIBDIR)/jdk_header.png: $(JDK_TOPDIR)/src/share/classes/com/sun/servicetag/resources/jdk_header.png - $(MKDIR) -p $(@D) - $(RM) $@ - $(CP) $< $@ - $(CHMOD) 444 $@ - -COPY_FILES += $(SERVICETAG_LIBDIR)/jdk_header.png - -########################################################################################## MGMT_LIBDIR = $(LIBDIR)/management MGMT_LIB_SRC = $(JDK_TOPDIR)/src/share/lib/management diff --git a/jdk/makefiles/CopyIntoClasses.gmk b/jdk/makefiles/CopyIntoClasses.gmk index d5ec8573110..549a58efd68 100644 --- a/jdk/makefiles/CopyIntoClasses.gmk +++ b/jdk/makefiles/CopyIntoClasses.gmk @@ -59,15 +59,6 @@ COPY_FILES += \ COPY_FILES += \ $(JDK_TOPDIR)/src/share/classes/sun/jvmstat/perfdata/resources/aliasmap -# Servicetag resources -SERVICETAG_RESOURCES_DIR = $(JDK_TOPDIR)/src/share/classes/com/sun/servicetag/resources -COPY_FILES += \ - $(SERVICETAG_RESOURCES_DIR)/product_registration.xsd \ - $(SERVICETAG_RESOURCES_DIR)/register.html \ - $(SERVICETAG_RESOURCES_DIR)/register_ja.html \ - $(SERVICETAG_RESOURCES_DIR)/register_zh_CN.html \ - $(wildcard $(SERVICETAG_RESOURCES_DIR)/javase_*.properties) - # JConsole resources JCONSOLE_RESOURCES_DIR = $(JDK_TOPDIR)/src/share/classes/sun/tools/jconsole/resources COPY_FILES += \ diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 61edcfa783d..523af3dc90f 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -866,8 +866,7 @@ EXCLUDE_PROPWARN_PKGS = com.sun.java.swing.plaf.windows \ # This is an interim solution until the ct.sym is replaced # with a new module system (being discussed for JDK 8). # -EXPORTED_PRIVATE_PKGS = com.sun.servicetag \ - com.oracle.net \ +EXPORTED_PRIVATE_PKGS = com.oracle.net \ com.oracle.nio $(IMAGES_OUTPUTDIR)/symbols/_the.symbols: $(IMAGES_OUTPUTDIR)/lib/rt.jar diff --git a/jdk/makefiles/GensrcProperties.gmk b/jdk/makefiles/GensrcProperties.gmk index 00598f4e94c..3ef3a538475 100644 --- a/jdk/makefiles/GensrcProperties.gmk +++ b/jdk/makefiles/GensrcProperties.gmk @@ -194,7 +194,6 @@ $(eval $(call add_properties_to_clean,COM_SUN_ROWSET_HK,\ $(call CacheFind,$(JDK_TOPDIR)/src/share/classes/com/sun/rowset)),\ %zh_TW,%zh_HK)) -#com/sun/servicetag/resources #com/sun/swing/internal/plaf/basic/resources $(eval $(call add_properties_to_compile,COM_SUN_SWING_PLAF_BASIC,\ $(filter %.properties,\ diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index b4eb6f83fb3..17e554f4223 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -222,7 +222,6 @@ FULL_JRE_LIB_FILES := \ oblique-fonts/fonts.dir \ psfont.properties.ja \ psfontj2d.properties \ - servicetag/jdk_header.png \ sound.properties FULL_JRE_OTHER_FILES := \ diff --git a/jdk/makefiles/profile-rtjar-includes.txt b/jdk/makefiles/profile-rtjar-includes.txt index f7251d94147..a90af142db1 100644 --- a/jdk/makefiles/profile-rtjar-includes.txt +++ b/jdk/makefiles/profile-rtjar-includes.txt @@ -186,7 +186,6 @@ FULL_JRE_RTJAR_INCLUDE_PACKAGES := \ com/sun/media/sound \ com/sun/org/glassfish \ com/sun/org/omg \ - com/sun/servicetag \ com/sun/swing \ com/sun/xml/internal/bind \ com/sun/xml/internal/fastinfoset \ diff --git a/jdk/test/Makefile b/jdk/test/Makefile index 69d5dac3d57..2b4bfa14594 100644 --- a/jdk/test/Makefile +++ b/jdk/test/Makefile @@ -518,7 +518,6 @@ jdk_other: $(call TestDirs, \ jdk/asm \ com/sun/org/apache/xerces \ com/sun/corba \ - com/sun/servicetag \ com/sun/tracing \ sun/usagetracker) $(call RunAgentvmBatch) From d79b11782a0a7743ba496cd224ea0683362441fe Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Mon, 25 Mar 2013 18:14:52 -0700 Subject: [PATCH 115/137] 8010787: changeset for 8007703 is missing the deleted files Reviewed-by: dholmes, alanb, erikj --- jdk/make/com/sun/servicetag/Makefile | 80 -- .../com/sun/servicetag/BrowserSupport.java | 176 ---- .../classes/com/sun/servicetag/Installer.java | 937 ------------------ .../servicetag/LinuxSystemEnvironment.java | 193 ---- .../com/sun/servicetag/RegistrationData.java | 475 --------- .../sun/servicetag/RegistrationDocument.java | 358 ------- .../classes/com/sun/servicetag/Registry.java | 556 ----------- .../com/sun/servicetag/ServiceTag.java | 634 ------------ .../com/sun/servicetag/SolarisServiceTag.java | 62 -- .../servicetag/SolarisSystemEnvironment.java | 159 --- .../com/sun/servicetag/SunConnection.java | 297 ------ .../com/sun/servicetag/SystemEnvironment.java | 338 ------- .../UnauthorizedAccessException.java | 53 - .../classes/com/sun/servicetag/Util.java | 339 ------- .../servicetag/WindowsSystemEnvironment.java | 150 --- .../classes/com/sun/servicetag/package.html | 71 -- .../servicetag/resources/Putback-Notes.txt | 25 - .../resources/javase_5_swordfish.properties | 29 - .../resources/javase_6_swordfish.properties | 29 - .../resources/javase_7_swordfish.properties | 29 - .../resources/javase_servicetag.properties | 29 - .../sun/servicetag/resources/jdk_header.png | Bin 8705 -> 0 bytes .../resources/product_registration.xsd | 301 ------ .../sun/servicetag/resources/register.html | 105 -- .../sun/servicetag/resources/register_ja.html | 91 -- .../servicetag/resources/register_zh_CN.html | 92 -- .../com/sun/servicetag/DeleteServiceTag.java | 129 --- .../com/sun/servicetag/DuplicateNotFound.java | 97 -- .../com/sun/servicetag/FindServiceTags.java | 141 --- .../com/sun/servicetag/InstanceUrnCheck.java | 76 -- .../servicetag/InvalidRegistrationData.java | 65 -- .../com/sun/servicetag/InvalidServiceTag.java | 96 -- .../sun/servicetag/JavaServiceTagTest.java | 191 ---- .../sun/servicetag/JavaServiceTagTest1.java | 265 ----- .../sun/servicetag/NewRegistrationData.java | 105 -- jdk/test/com/sun/servicetag/SvcTagClient.java | 200 ---- .../sun/servicetag/SystemRegistryTest.java | 139 --- .../com/sun/servicetag/TestLoadFromXML.java | 69 -- .../sun/servicetag/UpdateServiceTagTest.java | 109 -- jdk/test/com/sun/servicetag/Util.java | 265 ----- .../sun/servicetag/ValidRegistrationData.java | 112 --- .../com/sun/servicetag/environ.properties | 9 - .../sun/servicetag/missing-environ-field.xml | 45 - .../sun/servicetag/newer-registry-version.xml | 32 - jdk/test/com/sun/servicetag/registration.xml | 61 -- .../com/sun/servicetag/servicetag1.properties | 13 - .../com/sun/servicetag/servicetag2.properties | 13 - .../com/sun/servicetag/servicetag3.properties | 13 - .../com/sun/servicetag/servicetag4.properties | 13 - .../com/sun/servicetag/servicetag5.properties | 13 - 50 files changed, 7879 deletions(-) delete mode 100644 jdk/make/com/sun/servicetag/Makefile delete mode 100644 jdk/src/share/classes/com/sun/servicetag/BrowserSupport.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/Installer.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/LinuxSystemEnvironment.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/RegistrationData.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/RegistrationDocument.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/Registry.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/ServiceTag.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/SolarisServiceTag.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/SunConnection.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/SystemEnvironment.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/UnauthorizedAccessException.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/Util.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/WindowsSystemEnvironment.java delete mode 100644 jdk/src/share/classes/com/sun/servicetag/package.html delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/javase_servicetag.properties delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/register.html delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html delete mode 100644 jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html delete mode 100644 jdk/test/com/sun/servicetag/DeleteServiceTag.java delete mode 100644 jdk/test/com/sun/servicetag/DuplicateNotFound.java delete mode 100644 jdk/test/com/sun/servicetag/FindServiceTags.java delete mode 100644 jdk/test/com/sun/servicetag/InstanceUrnCheck.java delete mode 100644 jdk/test/com/sun/servicetag/InvalidRegistrationData.java delete mode 100644 jdk/test/com/sun/servicetag/InvalidServiceTag.java delete mode 100644 jdk/test/com/sun/servicetag/JavaServiceTagTest.java delete mode 100644 jdk/test/com/sun/servicetag/JavaServiceTagTest1.java delete mode 100644 jdk/test/com/sun/servicetag/NewRegistrationData.java delete mode 100644 jdk/test/com/sun/servicetag/SvcTagClient.java delete mode 100644 jdk/test/com/sun/servicetag/SystemRegistryTest.java delete mode 100644 jdk/test/com/sun/servicetag/TestLoadFromXML.java delete mode 100644 jdk/test/com/sun/servicetag/UpdateServiceTagTest.java delete mode 100644 jdk/test/com/sun/servicetag/Util.java delete mode 100644 jdk/test/com/sun/servicetag/ValidRegistrationData.java delete mode 100644 jdk/test/com/sun/servicetag/environ.properties delete mode 100644 jdk/test/com/sun/servicetag/missing-environ-field.xml delete mode 100644 jdk/test/com/sun/servicetag/newer-registry-version.xml delete mode 100644 jdk/test/com/sun/servicetag/registration.xml delete mode 100644 jdk/test/com/sun/servicetag/servicetag1.properties delete mode 100644 jdk/test/com/sun/servicetag/servicetag2.properties delete mode 100644 jdk/test/com/sun/servicetag/servicetag3.properties delete mode 100644 jdk/test/com/sun/servicetag/servicetag4.properties delete mode 100644 jdk/test/com/sun/servicetag/servicetag5.properties diff --git a/jdk/make/com/sun/servicetag/Makefile b/jdk/make/com/sun/servicetag/Makefile deleted file mode 100644 index a31b9aed177..00000000000 --- a/jdk/make/com/sun/servicetag/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2008, 2011, 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. - -BUILDDIR = ../../.. -PACKAGE = com.sun.servicetag -PRODUCT = sun -include $(BUILDDIR)/common/Defs.gmk - -# -# Files to compile -# -AUTO_FILES_JAVA_DIRS = com/sun/servicetag - -# -# Rules -# -include $(BUILDDIR)/common/Classes.gmk - -SERVICETAG_LIBDIR = $(LIBDIR)/servicetag -SERVICETAG_RESOURCES_DIR = $(CLASSDESTDIR)/com/sun/servicetag/resources -FILES_copy = $(SERVICETAG_RESOURCES_DIR)/product_registration.xsd \ - $(SERVICETAG_RESOURCES_DIR)/register.html \ - $(SERVICETAG_RESOURCES_DIR)/register_ja.html \ - $(SERVICETAG_RESOURCES_DIR)/register_zh_CN.html \ - $(SERVICETAG_LIBDIR)/jdk_header.png - -# Add all properties files to the FILES_copy list -SWORDFISH_properties := $(shell \ - $(CD) $(SHARE_SRC)/classes/com/sun/servicetag/resources; \ - $(FIND) . -name 'javase_*.properties' -print ; \ - ) -FILES_copy += $(shell \ - for f in $(SWORDFISH_properties) ; do \ - echo $(SERVICETAG_RESOURCES_DIR)/$$f ; \ - done \ -) - - -# -#OTHER_JAVACFLAGS += -Xlint:unchecked - -build: install-servicetag-lib copy-files - -copy-files: $(FILES_copy) - -$(CLASSBINDIR)/%: $(SHARE_SRC)/classes/% - $(install-file) - -$(SERVICETAG_LIBDIR)/jdk_header.png: $(SHARE_SRC)/classes/com/sun/servicetag/resources/jdk_header.png - $(install-file) - $(call chmod-file, 444) - -install-servicetag-lib: - @$(RM) -rf $(SERVICETAG_LIBDIR) - $(MKDIR) $(SERVICETAG_LIBDIR) - -clean clobber:: - @$(RM) $(FILES_copy) - -.PHONY: copy-files diff --git a/jdk/src/share/classes/com/sun/servicetag/BrowserSupport.java b/jdk/src/share/classes/com/sun/servicetag/BrowserSupport.java deleted file mode 100644 index cfbc832a32d..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/BrowserSupport.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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.servicetag; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.io.IOException; -import java.net.URI; - -/** - * BrowserSupport class. - * - * The implementation of the com.sun.servicetag API needs to be - * compiled with JDK 5 as well since the consumer of this API - * may require to support JDK 5 (e.g. NetBeans). - * - * The Desktop.browse() method can be backported in this class - * if needed. The current implementation only supports JDK 6. - */ -class BrowserSupport { - private static boolean isBrowseSupported = false; - private static Method browseMethod = null; - private static Object desktop = null; - private static volatile Boolean result = false; - - - private static void initX() { - if (desktop != null) { - return; - } - boolean supported = false; - Method browseM = null; - Object desktopObj = null; - try { - // Determine if java.awt.Desktop is supported - Class desktopCls = Class.forName("java.awt.Desktop", true, null); - Method getDesktopM = desktopCls.getMethod("getDesktop"); - browseM = desktopCls.getMethod("browse", URI.class); - - Class actionCls = Class.forName("java.awt.Desktop$Action", true, null); - final Method isDesktopSupportedMethod = desktopCls.getMethod("isDesktopSupported"); - Method isSupportedMethod = desktopCls.getMethod("isSupported", actionCls); - Field browseField = actionCls.getField("BROWSE"); - // isDesktopSupported calls getDefaultToolkit which can block - // infinitely, see 6636099 for details, to workaround we call - // in a thread and time it out, noting that the issue is specific - // to X11, it does not hurt for Windows. - Thread xthread = new Thread() { - public void run() { - try { - // support only if Desktop.isDesktopSupported() and - // Desktop.isSupported(Desktop.Action.BROWSE) return true. - result = (Boolean) isDesktopSupportedMethod.invoke(null); - } catch (IllegalAccessException e) { - // should never reach here - throw new InternalError("Desktop.getDesktop() method not found", e); - } catch (InvocationTargetException e) { - // browser not supported - if (Util.isVerbose()) { - e.printStackTrace(); - } - } - } - }; - // set it to daemon, so that the vm will exit. - xthread.setDaemon(true); - xthread.start(); - try { - xthread.join(5 * 1000); - } catch (InterruptedException ie) { - // ignore the exception - } - if (result.booleanValue()) { - desktopObj = getDesktopM.invoke(null); - result = (Boolean) isSupportedMethod.invoke(desktopObj, browseField.get(null)); - supported = result.booleanValue(); - } - } catch (IllegalAccessException e) { - // should never reach here - throw new InternalError("Desktop.getDesktop() method not found", e); - } catch (ReflectiveOperationException e) { - // browser not supported - if (Util.isVerbose()) { - e.printStackTrace(); - } - } - isBrowseSupported = supported; - browseMethod = browseM; - desktop = desktopObj; - } - - static boolean isSupported() { - initX(); - return isBrowseSupported; - } - - /** - * Launches the default browser to display a {@code URI}. - * If the default browser is not able to handle the specified - * {@code URI}, the application registered for handling - * {@code URIs} of the specified type is invoked. The application - * is determined from the protocol and path of the {@code URI}, as - * defined by the {@code URI} class. - *

- * This method calls the Desktop.getDesktop().browse() method. - *

- * @param uri the URI to be displayed in the user default browser - * - * @throws NullPointerException if {@code uri} is {@code null} - * @throws UnsupportedOperationException if the current platform - * does not support the {@link Desktop.Action#BROWSE} action - * @throws IOException if the user default browser is not found, - * or it fails to be launched, or the default handler application - * failed to be launched - * @throws IllegalArgumentException if the necessary permissions - * are not available and the URI can not be converted to a {@code URL} - */ - static void browse(URI uri) throws IOException { - if (uri == null) { - throw new NullPointerException("null uri"); - } - if (!isSupported()) { - throw new UnsupportedOperationException("Browse operation is not supported"); - } - - // Call Desktop.browse() method - try { - if (Util.isVerbose()) { - System.out.println("desktop: " + desktop + ":browsing..." + uri); - } - browseMethod.invoke(desktop, uri); - } catch (IllegalAccessException e) { - // should never reach here - throw new InternalError("Desktop.getDesktop() method not found", e); - } catch (InvocationTargetException e) { - Throwable x = e.getCause(); - if (x != null) { - if (x instanceof UnsupportedOperationException) { - throw (UnsupportedOperationException) x; - } else if (x instanceof IllegalArgumentException) { - throw (IllegalArgumentException) x; - } else if (x instanceof IOException) { - throw (IOException) x; - } else if (x instanceof SecurityException) { - throw (SecurityException) x; - } else { - // ignore - } - } - } - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/Installer.java b/jdk/src/share/classes/com/sun/servicetag/Installer.java deleted file mode 100644 index 35395abe9fd..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/Installer.java +++ /dev/null @@ -1,937 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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.servicetag; - -import java.io.*; -import java.util.HashSet; -import java.util.Locale; -import java.util.Properties; -import java.util.Set; -import java.util.List; -import java.util.ArrayList; -import static com.sun.servicetag.Util.*; - -/** - * Service Tag Installer for Java SE. - */ -public class Installer { - // System properties for testing - private static String SVCTAG_DIR_PATH = - "servicetag.dir.path"; - private static String SVCTAG_ENABLE_REGISTRATION = - "servicetag.registration.enabled"; - private final static String ORACLE = "Oracle"; - private final static String SUN = "Sun Microsystems"; - private final static String REGISTRATION_XML = "registration.xml"; - private final static String SERVICE_TAG_FILE = "servicetag"; - private final static String REGISTRATION_HTML_NAME = "register"; - - private final static Locale[] knownSupportedLocales = - new Locale[] { Locale.ENGLISH, - Locale.JAPANESE, - Locale.SIMPLIFIED_CHINESE}; - - private final static String javaHome = System.getProperty("java.home"); - private static File svcTagDir; - private static File serviceTagFile; - private static File regXmlFile; - private static RegistrationData registration; - private static boolean supportRegistration; - private static String registerHtmlParent; - private static Set supportedLocales = new HashSet<>(); - private static Properties svcTagProps = null; - private static String[] jreArchs = null; - static { - String dir = System.getProperty(SVCTAG_DIR_PATH); - if (dir == null) { - svcTagDir = new File(getJrePath(), "lib" + File.separator + SERVICE_TAG_FILE); - } else { - svcTagDir = new File(dir); - } - serviceTagFile = new File(svcTagDir, SERVICE_TAG_FILE); - regXmlFile = new File(svcTagDir, REGISTRATION_XML); - if (System.getProperty(SVCTAG_ENABLE_REGISTRATION) == null) { - supportRegistration = isJdk(); - } else { - supportRegistration = true; - } - } - - private Installer() { - } - - // Implementation of ServiceTag.getJavaServiceTag(String) method - static ServiceTag getJavaServiceTag(String source) throws IOException { - String vendor = System.getProperty("java.vendor", ""); - if (!vendor.startsWith(SUN) && !vendor.startsWith(ORACLE)) { - // Products bundling this implementation may run on - // Mac OS which is not a Sun/Oracle JDK - return null; - } - boolean cleanup = false; - try { - // Check if we have the swordfish entries for this JRE version - if (loadServiceTagProps() == null) { - return null; - } - - ServiceTag st = getJavaServiceTag(); - // Check if the service tag created by this bundle owner - if (st != null && st.getSource().equals(source)) { - // Install the system service tag if supported - // stclient may be installed after the service tag creation - if (Registry.isSupported()) { - installSystemServiceTag(); - } - return st; - } - - // in case any exception thrown during the cleanup - cleanup = true; - - // re-create a new one for this bundle owner - // first delete the registration data - deleteRegistrationData(); - cleanup = false; - - // create service tag and generate new register.html pages - return createServiceTag(source); - } finally { - if (cleanup) { - if (regXmlFile.exists()) { - regXmlFile.delete(); - } - if (serviceTagFile.exists()) { - serviceTagFile.delete(); - } - } - } - } - - /** - * Returns the Java SE registration data located in - * the /lib/servicetag/registration.xml by default. - * - * @throws IllegalArgumentException if the registration data - * is of invalid format. - */ - private static synchronized RegistrationData getRegistrationData() - throws IOException { - if (registration != null) { - return registration; - } - if (regXmlFile.exists()) { - try (BufferedInputStream in = - new BufferedInputStream(new FileInputStream(regXmlFile))) - { - registration = RegistrationData.loadFromXML(in); - } catch (IllegalArgumentException ex) { - System.err.println("Error: Bad registration data \"" + - regXmlFile + "\":" + ex.getMessage()); - throw ex; - } - } else { - registration = new RegistrationData(); - } - return registration; - } - - /** - * Write the registration data to the registration.xml file. - * - * The offline registration page has to be regenerated with - * the new registration data. - * - * @throws java.io.IOException - */ - private static synchronized void writeRegistrationXml() - throws IOException { - if (!svcTagDir.exists()) { - // This check is for NetBeans or other products that - // bundles this com.sun.servicetag implementation for - // pre-6u5 release. - if (!svcTagDir.mkdir()) { - throw new IOException("Failed to create directory: " + svcTagDir); - } - } - - // regenerate the new offline registration page - deleteRegistrationHtmlPage(); - getRegistrationHtmlPage(); - - try (BufferedOutputStream out = - new BufferedOutputStream(new FileOutputStream(regXmlFile))) - { - getRegistrationData().storeToXML(out); - } catch (IllegalArgumentException ex) { - System.err.println("Error: Bad registration data \"" + - regXmlFile + "\":" + ex.getMessage()); - throw ex; - } - } - - /** - * Returns the instance urn(s) stored in the servicetag file - * or empty set if file not exists. - */ - private static Set getInstalledURNs() throws IOException { - Set urnSet = new HashSet<>(); - if (serviceTagFile.exists()) { - try (BufferedReader in = new BufferedReader(new FileReader(serviceTagFile))) { - String urn; - while ((urn = in.readLine()) != null) { - urn = urn.trim(); - if (urn.length() > 0) { - urnSet.add(urn); - } - } - } - } - return urnSet; - } - - /** - * Return the Java SE service tag(s) if it exists. - * Typically only one Java SE service tag but it could have two for - * Solaris 32-bit and 64-bit on the same install directory. - * - * @return the service tag(s) for Java SE - */ - private static ServiceTag[] getJavaServiceTagArray() throws IOException { - RegistrationData regData = getRegistrationData(); - Set svcTags = regData.getServiceTags(); - Set result = new HashSet<>(); - - Properties props = loadServiceTagProps(); - String jdkUrn = props.getProperty("servicetag.jdk.urn"); - String jreUrn = props.getProperty("servicetag.jre.urn"); - for (ServiceTag st : svcTags) { - if (st.getProductURN().equals(jdkUrn) || - st.getProductURN().equals(jreUrn)) { - result.add(st); - } - } - return result.toArray(new ServiceTag[0]); - } - - /** - * Returns the Java SE service tag for this running platform; - * or null if not exist. - * This method will return the 64-bit service tag if the JDK - * supports both 32-bit and 64-bit if already created. - */ - private static ServiceTag getJavaServiceTag() throws IOException { - String definedId = getProductDefinedId(); - for (ServiceTag st : getJavaServiceTagArray()) { - if (st.getProductDefinedInstanceID().equals(definedId)) { - return st; - } - } - return null; - } - - /** - * Create a service tag for Java SE and install in the system - * service tag registry if supported. - * - * A registration data /lib/servicetag/registration.xml - * will be created to storeToXML the XML entry for Java SE service tag. - * If the system supports service tags, this method will install - * the Java SE service tag in the system service tag registry and - * its instance_urn will be stored to /lib/servicetag/servicetag. - * - * If /lib/servicetag/registration.xml exists but is not installed - * in the system service tag registry (i.e. servicetag doesn't exist), - * this method will install it as described above. - * - * If the system supports service tag, stclient will be used - * to create the Java SE service tag. - * - * A Solaris 32-bit and 64-bit JDK will be installed in the same - * directory but the registration.xml will have 2 service tags. - * The servicetag file will also contain 2 instance_urns for that case. - */ - private static ServiceTag createServiceTag(String svcTagSource) - throws IOException { - // determine if a new service tag is needed to be created - ServiceTag newSvcTag = null; - if (getJavaServiceTag() == null) { - newSvcTag = newServiceTag(svcTagSource); - } - - // Add the new service tag in the registration data - if (newSvcTag != null) { - RegistrationData regData = getRegistrationData(); - - // Add the service tag to the registration data in JDK/JRE - newSvcTag = regData.addServiceTag(newSvcTag); - - // add if there is a service tag for the OS - ServiceTag osTag = SolarisServiceTag.getServiceTag(); - if (osTag != null && regData.getServiceTag(osTag.getInstanceURN()) == null) { - regData.addServiceTag(osTag); - } - // write to the registration.xml - writeRegistrationXml(); - } - - // Install the system service tag if supported - if (Registry.isSupported()) { - installSystemServiceTag(); - } - return newSvcTag; - } - - private static void installSystemServiceTag() throws IOException { - // only install the service tag in the registry if - // it has permission to write the servicetag file. - if ((!serviceTagFile.exists() && !svcTagDir.canWrite()) || - (serviceTagFile.exists() && !serviceTagFile.canWrite())) { - return; - } - - Set urns = getInstalledURNs(); - ServiceTag[] javaSvcTags = getJavaServiceTagArray(); - if (urns.size() < javaSvcTags.length) { - for (ServiceTag st : javaSvcTags) { - // Add the service tag in the system service tag registry - // if not installed - String instanceURN = st.getInstanceURN(); - if (!urns.contains(instanceURN)) { - Registry.getSystemRegistry().addServiceTag(st); - } - } - } - writeInstalledUrns(); - } - - private static ServiceTag newServiceTag(String svcTagSource) throws IOException { - Properties props = loadServiceTagProps(); - - // Determine the product URN and name - String productURN; - String productName; - - if (isJdk()) { - // /jre exists which implies it's a JDK - productURN = props.getProperty("servicetag.jdk.urn"); - productName = props.getProperty("servicetag.jdk.name"); - } else { - // Otherwise, it's a JRE - productURN = props.getProperty("servicetag.jre.urn"); - productName = props.getProperty("servicetag.jre.name"); - } - - return ServiceTag.newInstance(ServiceTag.generateInstanceURN(), - productName, - System.getProperty("java.version"), - productURN, - props.getProperty("servicetag.parent.name"), - props.getProperty("servicetag.parent.urn"), - getProductDefinedId(), - System.getProperty("java.vendor"), - System.getProperty("os.arch"), - getZoneName(), - svcTagSource); - } - - /** - * Delete the registration data, the offline registration pages and - * the service tags in the system service tag registry if installed. - * - * The registration.xml and servicetag file will be removed. - */ - private static synchronized void deleteRegistrationData() - throws IOException { - try { - // delete the offline registration page - deleteRegistrationHtmlPage(); - - // Remove the service tag from the system ST registry if exists - Set urns = getInstalledURNs(); - if (urns.size() > 0 && Registry.isSupported()) { - for (String u : urns) { - Registry.getSystemRegistry().removeServiceTag(u); - } - } - registration = null; - } finally { - // Delete the registration.xml and servicetag files if exists - if (regXmlFile.exists()) { - if (!regXmlFile.delete()) { - throw new IOException("Failed to delete " + regXmlFile); - } - } - if (serviceTagFile.exists()) { - if (!serviceTagFile.delete()) { - throw new IOException("Failed to delete " + serviceTagFile); - } - } - } - } - - /** - * Updates the registration data to contain one single service tag - * for the running Java runtime. - */ - private static synchronized void updateRegistrationData(String svcTagSource) - throws IOException { - RegistrationData regData = getRegistrationData(); - ServiceTag curSvcTag = newServiceTag(svcTagSource); - - ServiceTag[] javaSvcTags = getJavaServiceTagArray(); - Set urns = getInstalledURNs(); - for (ServiceTag st : javaSvcTags) { - if (!st.getProductDefinedInstanceID().equals(curSvcTag.getProductDefinedInstanceID())) { - String instanceURN = st.getInstanceURN(); - regData.removeServiceTag(instanceURN); - - // remove it from the system service tag registry if exists - if (urns.contains(instanceURN) && Registry.isSupported()) { - Registry.getSystemRegistry().removeServiceTag(instanceURN); - } - } - } - writeRegistrationXml(); - writeInstalledUrns(); - } - - private static void writeInstalledUrns() throws IOException { - // if the Registry is not supported, - // remove the servicetag file - if (!Registry.isSupported() && serviceTagFile.exists()) { - serviceTagFile.delete(); - return; - } - - try (PrintWriter out = new PrintWriter(serviceTagFile)) { - ServiceTag[] javaSvcTags = getJavaServiceTagArray(); - for (ServiceTag st : javaSvcTags) { - // Write the instance_run to the servicetag file - String instanceURN = st.getInstanceURN(); - out.println(instanceURN); - } - } - } - - /** - * Load the properties for generating Java SE service tags. - * - * @param version Version of Java SE - */ - private static synchronized Properties loadServiceTagProps() throws IOException { - if (svcTagProps != null) { - return svcTagProps; - } - - // For Java SE 8 and later releases, JDK and JRE both use - // the same product number. The sworRDFish metadata were - // for legacy Sun part number. - String filename = "/com/sun/servicetag/resources/javase_servicetag.properties"; - try (InputStream in = Installer.class.getResourceAsStream(filename)) { - svcTagProps = new Properties(); - svcTagProps.load(in); - } - return svcTagProps; - } - - /** - * Returns the product defined instance ID for Java SE. - * It is a list of comma-separated name/value pairs: - * "id= []*" - * "dir=" - * - * where is the full version string of the JRE, - * is the architecture that the runtime supports - * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list)) - * - * For Solaris, it can be dual mode that can support both - * 32-bit and 64-bit. the "id" will be set to - * "1.6.0_03-b02 sparc sparcv9" - * - * The "dir" property is included in the service tag to enable - * the Service Tag software to determine if a service tag for - * Java SE is invalid and perform appropriate service tag - * cleanup if necessary. See RFE# 6574781 Service Tags Enhancement. - * - */ - private static String getProductDefinedId() { - StringBuilder definedId = new StringBuilder(); - definedId.append("id="); - definedId.append(System.getProperty("java.runtime.version")); - - String[] archs = getJreArchs(); - for (String name : archs) { - definedId.append(" " + name); - } - - String location = ",dir=" + javaHome; - if ((definedId.length() + location.length()) < 256) { - definedId.append(",dir="); - definedId.append(javaHome); - } else { - // if it exceeds the limit, we will not include the location - if (isVerbose()) { - System.err.println("Warning: Product defined instance ID exceeds the field limit:"); - } - } - - return definedId.toString(); - } - - /** - * Returns the architectures that the runtime supports - * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list)) - * The directory name where libjava.so is located. - * - * On Windows, returns the "os.arch" system property value. - */ - private synchronized static String[] getJreArchs() { - if (jreArchs != null) { - return jreArchs; - } - - Set archs = new HashSet<>(); - - String os = System.getProperty("os.name"); - if (os.equals("SunOS") || os.equals("Linux")) { - // Traverse the directories under /lib. - // If /lib//libjava.so exists, add - // to the product defined ID - File dir = new File(getJrePath() + File.separator + "lib"); - if (dir.isDirectory()) { - String[] children = dir.list(); - for (String name : children) { - File f = new File(dir, name + File.separator + "libjava.so"); - if (f.exists()) { - archs.add(name); - } - } - } - } else { - // Windows - append the os.arch - archs.add(System.getProperty("os.arch")); - } - jreArchs = archs.toArray(new String[0]); - return jreArchs; - } - - /** - * Return the zonename if zone is supported; otherwise, return - * "global". - */ - private static String getZoneName() throws IOException { - String zonename = "global"; - - String command = "/usr/bin/zonename"; - File f = new File(command); - // com.sun.servicetag package has to be compiled with JDK 5 as well - // JDK 5 doesn't support the File.canExecute() method. - // Risk not checking isExecute() for the zonename command is very low. - if (f.exists()) { - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - if (p.exitValue() == 0) { - zonename = output.trim(); - } - - } - return zonename; - } - - private synchronized static String getRegisterHtmlParent() throws IOException { - if (registerHtmlParent == null) { - File htmlDir; // register.html is put under the JDK directory - if (getJrePath().endsWith(File.separator + "jre")) { - htmlDir = new File(getJrePath(), ".."); - } else { - // j2se non-image build - htmlDir = new File(getJrePath()); - } - - // initialize the supported locales - initSupportedLocales(htmlDir); - - // Determine the location of the offline registration page - String path = System.getProperty(SVCTAG_DIR_PATH); - if (path == null) { - // Default is /register.html - registerHtmlParent = htmlDir.getCanonicalPath(); - } else { - File f = new File(path); - registerHtmlParent = f.getCanonicalPath(); - if (!f.isDirectory()) { - throw new InternalError("Path " + path + " set in \"" + - SVCTAG_DIR_PATH + "\" property is not a directory"); - } - } - } - return registerHtmlParent; - } - - /** - * Returns the File object of the offline registration page localized - * for the default locale in the JDK directory. - */ - static synchronized File getRegistrationHtmlPage() throws IOException { - if (!supportRegistration) { - // No register.html page generated if JRE - return null; - } - - String parent = getRegisterHtmlParent(); - - // check if the offline registration page is already generated - File f = new File(parent, REGISTRATION_HTML_NAME + ".html"); - if (!f.exists()) { - // Generate the localized version of the offline registration Page - generateRegisterHtml(parent); - } - - String name = REGISTRATION_HTML_NAME; - Locale locale = getDefaultLocale(); - if (!locale.equals(Locale.ENGLISH) && supportedLocales.contains(locale)) { - // if the locale is not English and is supported by JDK - // set to the appropriate offline registration page; - // otherwise,set to register.html. - name = REGISTRATION_HTML_NAME + "_" + locale.toString(); - } - File htmlFile = new File(parent, name + ".html"); - if (isVerbose()) { - System.out.print("Offline registration page: " + htmlFile); - System.out.println((htmlFile.exists() ? - "" : " not exist. Use register.html")); - } - if (htmlFile.exists()) { - return htmlFile; - } else { - return new File(parent, - REGISTRATION_HTML_NAME + ".html"); - } - } - - private static Locale getDefaultLocale() { - List candidateLocales = getCandidateLocales(Locale.getDefault()); - for (Locale l : candidateLocales) { - if (supportedLocales.contains(l)) { - return l; - } - } - return Locale.getDefault(); - } - - private static List getCandidateLocales(Locale locale) { - String language = locale.getLanguage(); - String country = locale.getCountry(); - String variant = locale.getVariant(); - - List locales = new ArrayList<>(3); - if (variant.length() > 0) { - locales.add(locale); - } - if (country.length() > 0) { - locales.add((locales.isEmpty()) ? - locale : new Locale(language, country, "")); - } - if (language.length() > 0) { - locales.add((locales.isEmpty()) ? - locale : new Locale(language, "", "")); - } - return locales; - } - - // Remove the offline registration pages - private static void deleteRegistrationHtmlPage() throws IOException { - String parent = getRegisterHtmlParent(); - if (parent == null) { - return; - } - - for (Locale locale : supportedLocales) { - String name = REGISTRATION_HTML_NAME; - if (!locale.equals(Locale.ENGLISH)) { - name += "_" + locale.toString(); - } - File f = new File(parent, name + ".html"); - if (f.exists()) { - if (!f.delete()) { - throw new IOException("Failed to delete " + f); - } - } - } - } - - private static void initSupportedLocales(File jdkDir) { - if (supportedLocales.isEmpty()) { - // initialize with the known supported locales - for (Locale l : knownSupportedLocales) { - supportedLocales.add(l); - } - } - - // Determine unknown supported locales if any - // by finding the localized version of README.html - // This prepares if a new locale in JDK is supported in - // e.g. in the OpenSource world - FilenameFilter ff = new FilenameFilter() { - public boolean accept(File dir, String name) { - String fname = name.toLowerCase(); - if (fname.startsWith("readme") && fname.endsWith(".html")) { - return true; - } - return false; - } - }; - - String[] readmes = jdkDir.list(ff); - for (String name : readmes) { - String basename = name.substring(0, name.length() - ".html".length()); - String[] ss = basename.split("_"); - switch (ss.length) { - case 1: - // English version - break; - case 2: - supportedLocales.add(new Locale(ss[1])); - break; - case 3: - supportedLocales.add(new Locale(ss[1], ss[2])); - break; - default: - // ignore - break; - } - } - if (isVerbose()) { - System.out.println("Supported locales: "); - for (Locale l : supportedLocales) { - System.out.println(l); - } - } - } - - private static final String JDK_HEADER_PNG_KEY = "@@JDK_HEADER_PNG@@"; - private static final String JDK_VERSION_KEY = "@@JDK_VERSION@@"; - private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@"; - private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@"; - - @SuppressWarnings("unchecked") - private static void generateRegisterHtml(String parent) throws IOException { - int version = Util.getJdkVersion(); - int update = Util.getUpdateVersion(); - String jdkVersion = "Version " + version; - if (update > 0) { - // product name is not translated - jdkVersion += " Update " + update; - } - RegistrationData regData = getRegistrationData(); - // Make sure it uses the canonical path before getting the URI. - File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png"); - String headerImageSrc = img.toURI().toString(); - - // Format the registration data in one single line - StringBuilder payload = new StringBuilder(); - String xml = regData.toString().replaceAll("\"", "%22"); - try (BufferedReader reader = new BufferedReader(new StringReader(xml))) { - String line = null; - while ((line = reader.readLine()) != null) { - payload.append(line.trim()); - } - } - - String resourceFilename = "/com/sun/servicetag/resources/register"; - for (Locale locale : supportedLocales) { - String name = REGISTRATION_HTML_NAME; - String resource = resourceFilename; - if (!locale.equals(Locale.ENGLISH)) { - name += "_" + locale.toString(); - resource += "_" + locale.toString(); - } - File f = new File(parent, name + ".html"); - InputStream in = null; - BufferedReader br = null; - PrintWriter pw = null; - String registerURL = SunConnection. - getRegistrationURL(regData.getRegistrationURN(), - locale, - String.valueOf(version)).toString(); - try { - in = Installer.class.getResourceAsStream(resource + ".html"); - if (in == null) { - // if the resource file is missing - if (isVerbose()) { - System.out.println("Missing resouce file: " + resource + ".html"); - } - continue; - } - if (isVerbose()) { - System.out.println("Generating " + f + " from " + resource + ".html"); - } - - try { - br = new BufferedReader(new InputStreamReader(in, "UTF-8")); - pw = new PrintWriter(f, "UTF-8"); - String line = null; - while ((line = br.readLine()) != null) { - String output = line; - if (line.contains(JDK_VERSION_KEY)) { - output = line.replace(JDK_VERSION_KEY, jdkVersion); - } else if (line.contains(JDK_HEADER_PNG_KEY)) { - output = line.replace(JDK_HEADER_PNG_KEY, headerImageSrc); - } else if (line.contains(REGISTRATION_URL_KEY)) { - output = line.replace(REGISTRATION_URL_KEY, registerURL); - } else if (line.contains(REGISTRATION_PAYLOAD_KEY)) { - output = line.replace(REGISTRATION_PAYLOAD_KEY, payload.toString()); - } - pw.println(output); - } - f.setReadOnly(); - pw.flush(); - } finally { - // It's safe for this finally block to have two close statements - // consecutively as PrintWriter.close doesn't throw IOException. - if (pw != null) { - pw.close(); - } - if (br!= null) { - br.close(); - } - } - } finally { - if (in != null) { - in.close(); - } - } - } - } - - private static final int MAX_SOURCE_LEN = 63; - - /** - * A utility class to create a service tag for Java SE. - *

- * Usage:
- *

- * <JAVA_HOME>/bin/java com.sun.servicetag.Installer - *
- *

- */ - public static void main(String[] args) { - String source = "Manual "; - String runtimeName = System.getProperty("java.runtime.name"); - if (runtimeName.startsWith("OpenJDK")) { - source = "OpenJDK "; - } - source += System.getProperty("java.runtime.version"); - if (source.length() > MAX_SOURCE_LEN) { - source = source.substring(0, MAX_SOURCE_LEN); - } - - // Parse the options (arguments starting with "-" ) - boolean delete = false; - boolean update = false; - boolean register = false; - int count = 0; - while (count < args.length) { - String arg = args[count]; - if (arg.trim().length() == 0) { - // skip empty arguments - count++; - continue; - } - - if (arg.equals("-source")) { - source = args[++count]; - } else if (arg.equals("-delete")) { - delete = true; - } else if (arg.equals("-register")) { - register = true; - } else { - usage(); - return; - } - count++; - } - try { - if (delete) { - deleteRegistrationData(); - } else { - ServiceTag[] javaSvcTags = getJavaServiceTagArray(); - String[] archs = getJreArchs(); - if (javaSvcTags.length > archs.length) { - // 64-bit has been uninstalled - // so remove the service tag - updateRegistrationData(source); - } else { - // create the service tag - createServiceTag(source); - } - } - - if (register) { - // Registration is only supported by JDK - // For testing purpose, override with a "servicetag.enable.registration" property - - RegistrationData regData = getRegistrationData(); - if (supportRegistration && !regData.getServiceTags().isEmpty()) { - SunConnection.register(regData, - getDefaultLocale(), - String.valueOf(Util.getJdkVersion())); - } - } - System.exit(0); - } catch (IOException e) { - System.err.println("I/O Error: " + e.getMessage()); - if (isVerbose()) { - e.printStackTrace(); - } - } catch (IllegalArgumentException ex) { - if (isVerbose()) { - ex.printStackTrace(); - } - } catch (Exception e) { - System.err.println("Error: " + e.getMessage()); - if (isVerbose()) { - e.printStackTrace(); - } - } - System.exit(1); - } - - private static void usage() { - System.out.println("Usage:"); - System.out.print(" " + Installer.class.getName()); - System.out.println(" [-delete|-source |-register]"); - System.out.println(" to create a service tag for the Java platform"); - System.out.println(""); - System.out.println("Internal Options:"); - System.out.println(" -source: to specify the source of the service tag to be created"); - System.out.println(" -delete: to delete the service tag "); - System.out.println(" -register: to register the JDK"); - System.out.println(" -help: to print this help message"); - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/LinuxSystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/LinuxSystemEnvironment.java deleted file mode 100644 index 0d5a70720f4..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/LinuxSystemEnvironment.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -// This class is a copy of the com.sun.scn.servicetags.LinuxSystemEnvironment -// class from the Sun Connection source. -// -// The Service Tags team maintains the latest version of the implementation -// for system environment data collection. JDK will include a copy of -// the most recent released version for a JDK release. We rename -// the package to com.sun.servicetag so that the Sun Connection -// product always uses the latest version from the com.sun.scn.servicetags -// package. JDK and users of the com.sun.servicetag API -// (e.g. NetBeans and SunStudio) will use the version in JDK. -// -// So we keep this class in src/share/classes instead of src//classes. - -import java.io.*; - -/** - * Linux implementation of the SystemEnvironment class. - */ -class LinuxSystemEnvironment extends SystemEnvironment { - LinuxSystemEnvironment() { - setHostId(getLinuxHostId()); - setSystemModel(getCommandOutput("/bin/uname", "-i")); - setSystemManufacturer(getLinuxSystemManufacturer()); - setCpuManufacturer(getLinuxCpuManufacturer()); - setSerialNumber(getLinuxSN()); - } - private String dmiInfo = null; - - private static final int SN = 1; - private static final int SYS = 2; - private static final int CPU = 3; - - private String getLinuxHostId() { - String output = getCommandOutput("/usr/bin/hostid"); - // trim off the leading 0x - if (output.startsWith("0x")) { - output = output.substring(2); - } - return output; - } - - /** - * Tries to obtain and return the cpu manufacturer. - * @return The cpu manufacturer (an empty string if not found or an error occurred) - */ - private String getLinuxCpuManufacturer() { - String tmp = getLinuxPSNInfo(CPU); - if (tmp.length() > 0) { - return tmp; - } - - String contents = getFileContent("/proc/cpuinfo"); - for (String line : contents.split("\n")) { - if (line.contains("vendor_id")) { - String[] ss = line.split(":", 2); - if (ss.length > 1) { - return ss[1].trim(); - } - } - } - - // returns an empty string if it can't be found or an error happened - return getLinuxDMIInfo("dmi type 4", "manufacturer"); - } - - - /** - * Tries to obtain and return the system manufacturer. - * @return The system manufacturer (an empty string if not found or an error occurred) - */ - private String getLinuxSystemManufacturer() { - String tmp = getLinuxPSNInfo(SYS); - if (tmp.length() > 0) { - return tmp; - } - - // returns an empty string if it can't be found or an error happened - return getLinuxDMIInfo("dmi type 1", "manufacturer"); - } - - /** - * Tries to obtain and return the serial number of the system. - * @return The serial number (an empty string if not found or an error occurred) - */ - private String getLinuxSN() { - String tmp = getLinuxPSNInfo(SN); - if (tmp.length() > 0) { - return tmp; - } - - // returns an empty string if it can't be found or an error happened - return getLinuxDMIInfo("dmi type 1", "serial number"); - } - - private String getLinuxPSNInfo(int target) { - // try to read from the psn file if it exists - String contents = getFileContent("/var/run/psn"); - String[] ss = contents.split("\n"); - if (target <= ss.length) { - return ss[target-1]; - } - - // default case is to return "" - return ""; - } - - // reads from dmidecode with the given type and target - // returns an empty string if nothing was found or an error occurred - // - // Sample output segment: - // Handle 0x0001 - // DMI type 1, 25 bytes. - // System Information - // Manufacturer: System manufacturer - // Product Name: System Product Name - // Version: System Version - // Serial Number: System Serial Number - // UUID: 3091D719-B25B-D911-959D-6D1B12C7686E - // Wake-up Type: Power Switch - - private synchronized String getLinuxDMIInfo(String dmiType, String target) { - // only try to get dmidecode information once, after that, we can - // reuse the output - if (dmiInfo == null) { - Thread dmidecodeThread = new Thread() { - public void run() { - dmiInfo = getCommandOutput("/usr/sbin/dmidecode"); - } - }; - dmidecodeThread.start(); - - try { - dmidecodeThread.join(2000); - if (dmidecodeThread.isAlive()) { - dmidecodeThread.interrupt(); - dmiInfo = ""; - } - } catch (InterruptedException ie) { - dmidecodeThread.interrupt(); - } - } - - if (dmiInfo.length() == 0) { - return ""; - } - boolean dmiFlag = false; - for (String s : dmiInfo.split("\n")) { - String line = s.toLowerCase(); - if (dmiFlag) { - if (line.contains(target)) { - String key = target + ":"; - int indx = line.indexOf(key) + key.length(); - if (line.contains(key) && indx < line.length()) { - return line.substring(indx).trim(); - } - String[] ss = line.split(":"); - return ss[ss.length-1]; - } - } else if (line.contains(dmiType)) { - dmiFlag = true; - } - } - return ""; - } - -} diff --git a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java b/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java deleted file mode 100644 index 1c203f4126c..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/RegistrationData.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -import java.io.*; -import java.net.UnknownHostException; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import static com.sun.servicetag.RegistrationDocument.*; - -/** - * A {@code RegistrationData} object is a container of one or more - * {@link #getServiceTags service tags} that identify the - * components for product registration. - * Each {@code RegistrationData} object has a {@link #getRegistrationURN - * uniform resource name} (URN) as its identifier. - * - * It also has an environment map with - * the following elements: - *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
hostnameHostname of the systeme.g. woody
hostIdHost ID of the systeme.g. 83abc1ab
osNameOperating system name e.g. SunOS
osVersionOperating system version e.g. 5.10
osArchitectureOperating system architecture e.g. sparc
systemModelSystem model e.g. SUNW,Sun-Fire-V440
systemManufacturerSystem manufacturer e.g. Oracle Corporation
cpuManufacturerCPU manufacturer e.g. Oracle Corporation
serialNumberSystem serial number e.g. BEL078932
- *
- * The hostname and osName element must have a non-empty value. - * If an element is not available on a system and their value will be - * empty. - *

- * - * Registration XML Schema - *

- * A {@code RegistrationData} object can be {@link #loadFromXML loaded} from - * and {@link #storeToXML stored} into an XML file in the format described - * by the - * - * registration data schema. The registration data schema is defined by the - * Service Tags Technology. - *

- * Typically the registration data is constructed at installation time - * and stored in an XML file for later service tag lookup or registration. - * - *

- * Example Usage - *

- * The examples below show how the {@code RegistrationData} can be - * used for product registration. - * Exception handling is not shown in these examples for clarity. - *

    - *
  1. This example shows how the JDK creates a JDK service tag, installs it - * in the system service tag registry and adds it to the registration data. - *
    - *
    - *   // create a service tag object with an instance_urn
    - *   ServiceTag st = ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
    - *                                          ....);
    - *   // Adds to the system service tag registry if supported
    - *   if (Registry.isSupported()) {
    - *       Registry.getSystemRegistry().addServiceTag(st);
    - *   }
    - *
    - *   // add to the registration data
    - *   RegistrationData registration  = new RegistrationData();
    - *   registration.addServiceTag(st);
    - * 
    - *
  2. - *
  3. At this point, the registration data is ready to - * send to Sun Connection for registration. This example shows how to register - * the JDK via the Registration Relay Service. - *

    - * There are several registration services for Sun Connection. For example, - * the - * Registration Relay Service is a web application interface that - * processes the registration data payload sent via HTTP post - * and hosts the registration user interface for a specified - * registration URL. Refer to the - * Registration Relay Service Specification for details. - *

    - *

    - *   // Open the connection to the URL of the registration service
    - *   HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
    - *   con.setDoInput(true);
    - *   con.setDoOutput(true);
    - *   con.setUseCaches(false);
    - *   con.setAllowUserInteraction(false);
    - *   con.setRequestMethod("POST");
    - *   con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
    - *   con.connect();
    - *
    - *   // send the registration data to the registration service
    - *   OutputStream out = con.getOutputStream();
    - *   registration.storeToXML(out);
    - *   out.close();
    - * 
    - *
  4. - *
  5. This example shows how to store the registration data in an XML file. - * for later service tag lookup or registration. - *
    - *
    - *   BufferedOutputStream out = new BufferedOutputStream(
    - *       new FileOutputStream(""<JAVA_HOME>/lib/servicetag/registration.xml"));
    - *   registration.storeToXML(out);
    - *   out.close();
    - * 
    - *
  6. - *
  7. This example shows how to install service tags that are in the - * registration data in the system service tag registry when determined - * to be available. The system service tag registry might not have existed - * when the registration data was constructed. - *
    - *
    - *   if (Registry.isSupported()) {
    - *       Set<ServiceTag> svctags = registration.getServiceTags();
    - *       for (ServiceTag st : svctags) {
    - *           Registry.getSystemRegistry().addServiceTag(st);
    - *       }
    - *   }
    - * 
    - *
  8. - *
- * - * @see Sun Connection Inventory Channel - */ -public class RegistrationData { - private final Map environment = initEnvironment(); - private final Map svcTagMap = - new LinkedHashMap(); - private final String urn; - - /** - * Creates a {@code RegistrationData} object with a generated - * {@link #getRegistrationURN registration URN}. - * The following keys in the {@link #getEnvironmentMap environment map} - * will be initialized for the configuration of the - * running system: - *
- * hostname, osName, osVersion and - * osArchitecture - *
- * and the value of other keys may be empty. - */ - public RegistrationData() { - this(Util.generateURN()); - SystemEnvironment sysEnv = SystemEnvironment.getSystemEnvironment(); - setEnvironment(ST_NODE_HOSTNAME, sysEnv.getHostname()); - setEnvironment(ST_NODE_HOST_ID, sysEnv.getHostId()); - setEnvironment(ST_NODE_OS_NAME, sysEnv.getOsName()); - setEnvironment(ST_NODE_OS_VERSION, sysEnv.getOsVersion()); - setEnvironment(ST_NODE_OS_ARCH, sysEnv.getOsArchitecture()); - setEnvironment(ST_NODE_SYSTEM_MODEL, sysEnv.getSystemModel()); - setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, sysEnv.getSystemManufacturer()); - setEnvironment(ST_NODE_CPU_MANUFACTURER, sysEnv.getCpuManufacturer()); - setEnvironment(ST_NODE_SERIAL_NUMBER, sysEnv.getSerialNumber()); - } - - // package private - RegistrationData(String urn) { - this.urn = urn; - } - - private Map initEnvironment() { - Map map = new LinkedHashMap(); - map.put(ST_NODE_HOSTNAME, ""); - map.put(ST_NODE_HOST_ID, ""); - map.put(ST_NODE_OS_NAME, ""); - map.put(ST_NODE_OS_VERSION, ""); - map.put(ST_NODE_OS_ARCH, ""); - map.put(ST_NODE_SYSTEM_MODEL, ""); - map.put(ST_NODE_SYSTEM_MANUFACTURER, ""); - map.put(ST_NODE_CPU_MANUFACTURER, ""); - map.put(ST_NODE_SERIAL_NUMBER, ""); - return map; - } - - /** - * Returns the uniform resource name of this registration data - * in this format: - * urn:st:<32-char {@link java.util.UUID uuid}> - * - * @return the URN of this registration data. - */ - public String getRegistrationURN() { - return urn; - } - - /** - * Returns a map containing the environment information for this - * registration data. See the set of keys - * in the environment map. Subsequent update to the environment - * map via the {@link #setEnvironment setEnvironment} method will not be reflected - * in the returned map. - * - * @return an environment map for this registration data. - */ - public Map getEnvironmentMap() { - return new LinkedHashMap(environment); - } - - /** - * Sets an element of the specified {@code name} in the environment map - * with the given {@code value}. - * - * @throws IllegalArgumentException if {@code name} is not a valid key - * in the environment map, or {@code value} is not valid. - */ - public void setEnvironment(String name, String value) { - if (name == null) { - throw new NullPointerException("name is null"); - } - if (value == null) { - throw new NullPointerException("value is null"); - } - if (environment.containsKey(name)) { - if (name.equals(ST_NODE_HOSTNAME) || name.equals(ST_NODE_OS_NAME)) { - if (value.length() == 0) { - throw new IllegalArgumentException("\"" + - name + "\" requires non-empty value."); - } - } - environment.put(name, value); - } else { - throw new IllegalArgumentException("\"" + - name + "\" is not an environment element."); - } - } - - /** - * Returns all service tags in this registration data. - * - * @return a {@link Set Set} of the service tags - * in this registration data. - */ - public Set getServiceTags() { - return new HashSet(svcTagMap.values()); - } - - /** - * Adds a service tag to this registration data. - * If the given service tag has an empty instance_urn, - * this method will generate a URN and place it in the copy - * of the service tag in this registration data. - * This method will return the {@code ServiceTag} object - * added to this registration data. - * - * @param st {@code ServiceTag} object to be added. - * @return a {@code ServiceTag} object added to this registration data. - * - * @throws IllegalArgumentException if - * a service tag of the same {@link ServiceTag#getInstanceURN - * instance_urn} already exists in the registry. - */ - public synchronized ServiceTag addServiceTag(ServiceTag st) { - ServiceTag svcTag = ServiceTag.newInstanceWithUrnTimestamp(st); - - String instanceURN = svcTag.getInstanceURN(); - if (svcTagMap.containsKey(instanceURN)) { - throw new IllegalArgumentException("Instance_urn = " + instanceURN + - " already exists in the registration data."); - } else { - svcTagMap.put(instanceURN, svcTag); - } - return svcTag; - } - - /** - * Returns a service tag of the given instance_urn in this registration - * data. - * - * @param instanceURN the instance_urn of the service tag - * @return the {@code ServiceTag} object of the given instance_urn - * if exists; otherwise return {@code null}. - */ - public synchronized ServiceTag getServiceTag(String instanceURN) { - if (instanceURN == null) { - throw new NullPointerException("instanceURN is null"); - } - return svcTagMap.get(instanceURN); - } - - /** - * Removes a service tag of the given instance_urn from this - * registration data. - * - * @param instanceURN the instance_urn of - * the service tag to be removed. - * - * @return the removed {@code ServiceTag} object; - * or {@code null} if the service tag does not exist in this - * registration data. - */ - public synchronized ServiceTag removeServiceTag(String instanceURN) { - if (instanceURN == null) { - throw new NullPointerException("instanceURN is null"); - } - - ServiceTag svcTag = null; - if (svcTagMap.containsKey(instanceURN)) { - svcTag = svcTagMap.remove(instanceURN); - } - return svcTag; - } - - /** - * Updates the product_defined_instance_id in the service tag - * of the given instance_urn in this registration data. - * - * @param instanceURN the instance_urn of the service tag to be updated. - * @param productDefinedInstanceID the value of the - * product_defined_instance_id to be set. - * - * @return the updated {@code ServiceTag} object; - * or {@code null} if the service tag does not exist in this - * registration data. - */ - public synchronized ServiceTag updateServiceTag(String instanceURN, - String productDefinedInstanceID) { - ServiceTag svcTag = getServiceTag(instanceURN); - if (svcTag == null) { - return null; - } - - svcTag = ServiceTag.newInstanceWithUrnTimestamp(svcTag); - // update the product defined instance ID field - svcTag.setProductDefinedInstanceID(productDefinedInstanceID); - svcTagMap.put(instanceURN, svcTag); - return svcTag; - } - - /** - * Reads the registration data from the XML document on the - * specified input stream. The XML document must be - * in the format described by the - * registration data schema. - * The specified stream is closed after this method returns. - * - * @param in the input stream from which to read the XML document. - * @return a {@code RegistrationData} object read from the input - * stream. - * - * @throws IllegalArgumentException if the input stream - * contains an invalid registration data. - * - * @throws IOException if an error occurred when reading from the input stream. - */ - public static RegistrationData loadFromXML(InputStream in) throws IOException { - try { - return RegistrationDocument.load(in); - } finally { - in.close(); - } - } - - /** - * Writes the registration data to the specified output stream - * in the format described by the - * registration data schema with "UTF-8" encoding. - * The specified stream remains open after this method returns. - * - * @param os the output stream on which to write the XML document. - * - * @throws IOException if an error occurred when writing to the output stream. - */ - public void storeToXML(OutputStream os) throws IOException { - RegistrationDocument.store(os, this); - os.flush(); - } - - /** - * Returns a newly allocated byte array containing the registration - * data in XML format. - * - * @return a newly allocated byte array containing the registration - * data in XML format. - */ - public byte[] toXML() { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - storeToXML(out); - return out.toByteArray(); - } catch (IOException e) { - // should not reach here - return new byte[0]; - } - } - - /** - * Returns a string representation of this registration data in XML - * format. - * - * @return a string representation of this registration data in XML - * format. - */ - @Override - public String toString() { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - storeToXML(out); - return out.toString("UTF-8"); - } catch (IOException e) { - // should not reach here - return "Error creating the return string."; - } - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/RegistrationDocument.java b/jdk/src/share/classes/com/sun/servicetag/RegistrationDocument.java deleted file mode 100644 index d6d55203ba4..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/RegistrationDocument.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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.servicetag; - -import java.io.*; -import java.net.URL; -import java.util.Collection; -import java.util.Map; -import java.util.Set; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; -import org.xml.sax.InputSource; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -// For write operation -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -/** - * XML Support Class for Product Registration. - */ -class RegistrationDocument { - - private static final String REGISTRATION_DATA_SCHEMA = - "/com/sun/servicetag/resources/product_registration.xsd"; - private static final String REGISTRATION_DATA_VERSION = "1.0"; - private static final String SERVICE_TAG_VERSION = "1.0"; - final static String ST_NODE_REGISTRATION_DATA = "registration_data"; - final static String ST_ATTR_REGISTRATION_VERSION = "version"; - final static String ST_NODE_ENVIRONMENT = "environment"; - final static String ST_NODE_HOSTNAME = "hostname"; - final static String ST_NODE_HOST_ID = "hostId"; - final static String ST_NODE_OS_NAME = "osName"; - final static String ST_NODE_OS_VERSION = "osVersion"; - final static String ST_NODE_OS_ARCH = "osArchitecture"; - final static String ST_NODE_SYSTEM_MODEL = "systemModel"; - final static String ST_NODE_SYSTEM_MANUFACTURER = "systemManufacturer"; - final static String ST_NODE_CPU_MANUFACTURER = "cpuManufacturer"; - final static String ST_NODE_SERIAL_NUMBER = "serialNumber"; - final static String ST_NODE_REGISTRY = "registry"; - final static String ST_ATTR_REGISTRY_URN = "urn"; - final static String ST_ATTR_REGISTRY_VERSION = "version"; - final static String ST_NODE_SERVICE_TAG = "service_tag"; - final static String ST_NODE_INSTANCE_URN = "instance_urn"; - final static String ST_NODE_PRODUCT_NAME = "product_name"; - final static String ST_NODE_PRODUCT_VERSION = "product_version"; - final static String ST_NODE_PRODUCT_URN = "product_urn"; - final static String ST_NODE_PRODUCT_PARENT_URN = "product_parent_urn"; - final static String ST_NODE_PRODUCT_PARENT = "product_parent"; - final static String ST_NODE_PRODUCT_DEFINED_INST_ID = "product_defined_inst_id"; - final static String ST_NODE_PRODUCT_VENDOR = "product_vendor"; - final static String ST_NODE_PLATFORM_ARCH = "platform_arch"; - final static String ST_NODE_TIMESTAMP = "timestamp"; - final static String ST_NODE_CONTAINER = "container"; - final static String ST_NODE_SOURCE = "source"; - final static String ST_NODE_INSTALLER_UID = "installer_uid"; - - static RegistrationData load(InputStream in) throws IOException { - Document document = initializeDocument(in); - - // Gets the registration URN - Element root = getRegistrationDataRoot(document); - Element registryRoot = - getSingletonElementFromRoot(root, ST_NODE_REGISTRY); - String urn = registryRoot.getAttribute(ST_ATTR_REGISTRY_URN); - - // Construct a new RegistrationData object from the DOM tree - // Initialize the environment map and service tags - RegistrationData regData = new RegistrationData(urn); - addServiceTags(registryRoot, regData); - - Element envRoot = getSingletonElementFromRoot(root, ST_NODE_ENVIRONMENT); - buildEnvironmentMap(envRoot, regData); - return regData; - } - - static void store(OutputStream os, RegistrationData registration) - throws IOException { - // create a new document with the root node - Document document = initializeDocument(); - - // create the nodes for the environment map and the service tags - // in the registration data - addEnvironmentNodes(document, - registration.getEnvironmentMap()); - addServiceTagRegistry(document, - registration.getRegistrationURN(), - registration.getServiceTags()); - transform(document, os); - } - - // initialize a document from an input stream - private static Document initializeDocument(InputStream in) throws IOException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - try { - // XML schema for validation - SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - URL xsdUrl = RegistrationDocument.class.getResource(REGISTRATION_DATA_SCHEMA); - Schema schema = sf.newSchema(xsdUrl); - Validator validator = schema.newValidator(); - - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(new InputSource(in)); - validator.validate(new DOMSource(doc)); - return doc; - } catch (SAXException sxe) { - IllegalArgumentException e = new IllegalArgumentException("Error generated in parsing"); - e.initCause(sxe); - throw e; - } catch (ParserConfigurationException pce) { - // Parser with specific options can't be built - // should not reach here - throw new InternalError("Error in creating the new document", pce); - } - } - - // initialize a new document for the registration data - private static Document initializeDocument() throws IOException { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - try { - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.newDocument(); - - // initialize the document with the registration_data root - Element root = doc.createElement(ST_NODE_REGISTRATION_DATA); - doc.appendChild(root); - root.setAttribute(ST_ATTR_REGISTRATION_VERSION, REGISTRATION_DATA_VERSION); - - return doc; - } catch (ParserConfigurationException pce) { - // Parser with specified options can't be built - // should not reach here - throw new InternalError("Error in creating the new document", pce); - } - } - - // Transform the current DOM tree with the given output stream. - private static void transform(Document document, OutputStream os) { - try { - // Use a Transformer for output - TransformerFactory tFactory = TransformerFactory.newInstance(); - tFactory.setAttribute("indent-number", new Integer(3)); - - Transformer transformer = tFactory.newTransformer(); - - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.METHOD, "xml"); - transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); - transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); - transformer.transform(new DOMSource(document), - new StreamResult(new BufferedWriter(new OutputStreamWriter(os, "UTF-8")))); - } catch (UnsupportedEncodingException ue) { - // Should not reach here - throw new InternalError("Error generated during transformation", ue); - } catch (TransformerConfigurationException tce) { - // Error generated by the parser - // Should not reach here - throw new InternalError("Error in creating the new document", tce); - } catch (TransformerException te) { - // Error generated by the transformer - throw new InternalError("Error generated during transformation", te); - } - } - - private static void addServiceTagRegistry(Document document, - String registryURN, - Set svcTags) { - // add service tag registry node and its attributes - Element reg = document.createElement(ST_NODE_REGISTRY); - reg.setAttribute(ST_ATTR_REGISTRY_URN, registryURN); - reg.setAttribute(ST_ATTR_REGISTRY_VERSION, SERVICE_TAG_VERSION); - - Element root = getRegistrationDataRoot(document); - root.appendChild(reg); - - // adds the elements for the service tags - for (ServiceTag st : svcTags) { - addServiceTagElement(document, reg, st); - } - } - - private static void addServiceTagElement(Document document, - Element registryRoot, - ServiceTag st) { - Element svcTag = document.createElement(ST_NODE_SERVICE_TAG); - registryRoot.appendChild(svcTag); - addChildElement(document, svcTag, - ST_NODE_INSTANCE_URN, st.getInstanceURN()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_NAME, st.getProductName()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_VERSION, st.getProductVersion()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_URN, st.getProductURN()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_PARENT_URN, st.getProductParentURN()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_PARENT, st.getProductParent()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_DEFINED_INST_ID, - st.getProductDefinedInstanceID()); - addChildElement(document, svcTag, - ST_NODE_PRODUCT_VENDOR, st.getProductVendor()); - addChildElement(document, svcTag, - ST_NODE_PLATFORM_ARCH, st.getPlatformArch()); - addChildElement(document, svcTag, - ST_NODE_TIMESTAMP, Util.formatTimestamp(st.getTimestamp())); - addChildElement(document, svcTag, - ST_NODE_CONTAINER, st.getContainer()); - addChildElement(document, svcTag, - ST_NODE_SOURCE, st.getSource()); - addChildElement(document, svcTag, - ST_NODE_INSTALLER_UID, - String.valueOf(st.getInstallerUID())); - } - - private static void addChildElement(Document document, Element root, - String element, String text) { - Element node = document.createElement(element); - node.appendChild(document.createTextNode(text)); - root.appendChild(node); - } - - // Constructs service tags from the document - private static void addServiceTags(Element registryRoot, - RegistrationData registration) { - NodeList children = registryRoot.getElementsByTagName(ST_NODE_SERVICE_TAG); - int length = (children == null ? 0 : children.getLength()); - for (int i = 0; i < length; i++) { - Element svcTagElement = (Element) children.item(i); - ServiceTag st = getServiceTag(svcTagElement); - registration.addServiceTag(st); - } - } - - // build environment map from the document - private static void buildEnvironmentMap(Element envRoot, - RegistrationData registration) { - registration.setEnvironment(ST_NODE_HOSTNAME, getTextValue(envRoot, ST_NODE_HOSTNAME)); - registration.setEnvironment(ST_NODE_HOST_ID, getTextValue(envRoot, ST_NODE_HOST_ID)); - registration.setEnvironment(ST_NODE_OS_NAME, getTextValue(envRoot, ST_NODE_OS_NAME)); - registration.setEnvironment(ST_NODE_OS_VERSION, getTextValue(envRoot, ST_NODE_OS_VERSION)); - registration.setEnvironment(ST_NODE_OS_ARCH, getTextValue(envRoot, ST_NODE_OS_ARCH)); - registration.setEnvironment(ST_NODE_SYSTEM_MODEL, getTextValue(envRoot, ST_NODE_SYSTEM_MODEL)); - registration.setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, getTextValue(envRoot, ST_NODE_SYSTEM_MANUFACTURER)); - registration.setEnvironment(ST_NODE_CPU_MANUFACTURER, getTextValue(envRoot, ST_NODE_CPU_MANUFACTURER)); - registration.setEnvironment(ST_NODE_SERIAL_NUMBER, getTextValue(envRoot, ST_NODE_SERIAL_NUMBER)); - } - - // add the nodes representing the environment map in the document - private static void addEnvironmentNodes(Document document, - Map envMap) { - Element root = getRegistrationDataRoot(document); - Element env = document.createElement(ST_NODE_ENVIRONMENT); - root.appendChild(env); - Set> keys = envMap.entrySet(); - for (Map.Entry entry : keys) { - addChildElement(document, env, entry.getKey(), entry.getValue()); - } - } - - private static Element getRegistrationDataRoot(Document doc) { - Element root = doc.getDocumentElement(); - if (!root.getNodeName().equals(ST_NODE_REGISTRATION_DATA)) { - throw new IllegalArgumentException("Not a " + - ST_NODE_REGISTRATION_DATA + - " node \"" + root.getNodeName() + "\""); - } - return root; - } - - private static Element getSingletonElementFromRoot(Element root, String name) { - NodeList children = root.getElementsByTagName(name); - int length = (children == null ? 0 : children.getLength()); - if (length != 1) { - throw new IllegalArgumentException("Invalid number of " + name + - " nodes = " + length); - } - Element e = (Element) children.item(0); - if (!e.getNodeName().equals(name)) { - throw new IllegalArgumentException("Not a " + name + - " node \"" + e.getNodeName() + "\""); - } - return e; - } - - // Constructs one ServiceTag instance from a service tag element root - private static ServiceTag getServiceTag(Element svcTagElement) { - return new ServiceTag( - getTextValue(svcTagElement, ST_NODE_INSTANCE_URN), - getTextValue(svcTagElement, ST_NODE_PRODUCT_NAME), - getTextValue(svcTagElement, ST_NODE_PRODUCT_VERSION), - getTextValue(svcTagElement, ST_NODE_PRODUCT_URN), - getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT), - getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT_URN), - getTextValue(svcTagElement, ST_NODE_PRODUCT_DEFINED_INST_ID), - getTextValue(svcTagElement, ST_NODE_PRODUCT_VENDOR), - getTextValue(svcTagElement, ST_NODE_PLATFORM_ARCH), - getTextValue(svcTagElement, ST_NODE_CONTAINER), - getTextValue(svcTagElement, ST_NODE_SOURCE), - Util.getIntValue(getTextValue(svcTagElement, ST_NODE_INSTALLER_UID)), - Util.parseTimestamp(getTextValue(svcTagElement, ST_NODE_TIMESTAMP)) - ); - } - - private static String getTextValue(Element e, String tagName) { - String value = ""; - NodeList nl = e.getElementsByTagName(tagName); - if (nl != null && nl.getLength() > 0) { - Element el = (Element) nl.item(0); - Node node = el.getFirstChild(); - if (node != null) { - value = node.getNodeValue(); - } - } - return value; - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/Registry.java b/jdk/src/share/classes/com/sun/servicetag/Registry.java deleted file mode 100644 index a9f3c8d4486..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/Registry.java +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (c) 2008, 2010, 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.servicetag; - -import java.io.*; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import static com.sun.servicetag.Util.*; -import static com.sun.servicetag.RegistrationDocument.*; - -/** - * A service tag registry is a XML-based registry containing - * the list of {@link ServiceTag service tags} installed in the system. - * The {@code Registry} class provides interfaces - * to add, remove, update, and get a service tag from a service tag - * registry. - * This {@code Registry} class may not be supported - * on all systems. The {@link #isSupported} method - * can be called to determine if it is supported. - *

- * A registry may implement restrictions to only allow certain users - * to {@link #updateServiceTag update} and - * to {@link #removeServiceTag remove} a service tag record. Typically, - * only the owner of the service tag, the owner of the registry - * and superuser are authorized to update or remove a service tag in - * the registry. - * - * @see - * Service Tag User Guide - */ -public class Registry { - - private static final String STCLIENT_SOLARIS = "/usr/bin/stclient"; - private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient"; - // stclient exit value (see sthelper.h) - private static final int ST_ERR_NOT_AUTH = 245; - private static final int ST_ERR_REC_NOT_FOUND = 225; - - // The stclient output has to be an exported interface - private static final String INSTANCE_URN_DESC = "Product instance URN="; - private static boolean initialized = false; - private static File stclient = null; - private static String stclientPath = null; - private static Registry registry = new Registry(); - - // System properties for testing - private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd"; - private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported"; - - private Registry() { - } - - private synchronized static String getSTclient() { - if (!initialized) { - // Initialization to determine the platform's stclient pathname - String os = System.getProperty("os.name"); - if (os.equals("SunOS")) { - stclient = new File(STCLIENT_SOLARIS); - } else if (os.equals("Linux")) { - stclient = new File(STCLIENT_LINUX); - } else if (os.startsWith("Windows")) { - stclient = getWindowsStClientFile(); - } else { - if (isVerbose()) { - System.out.println("Running on unsupported platform"); - } - } - initialized = true; - } - - boolean supportsHelperClass = true; // default - if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) { - // the system property always overrides the default setting - supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED); - } - - if (!supportsHelperClass) { - // disable system registry - return null; - } - - // This is only used for testing - String path = System.getProperty(SVCTAG_STCLIENT_CMD); - if (path != null) { - return path; - } - - // com.sun.servicetag package has to be compiled with JDK 5 as well - // JDK 5 doesn't support the File.canExecute() method. - // Risk not checking isExecute() for the stclient command is very low. - if (stclientPath == null && stclient != null && stclient.exists()) { - stclientPath = stclient.getAbsolutePath(); - } - return stclientPath; - } - - /** - * Returns the system service tag registry. The {@code Registry} class - * may not be supported on some platforms; use the {@link #isSupported} - * method to determine if it is supported. - * - * @return the {@code Registry} object for the system service tag registry. - * - * @throws UnsupportedOperationException if the {@code Registry} class is - * not supported. - */ - public static Registry getSystemRegistry() { - if (isSupported()) { - return registry; - } else { - throw new UnsupportedOperationException("Registry class is not supported"); - } - } - - /** - * Returns {@code true} if the {@code Registry} class is supported on this system. - * - * @return {@code true} if the {@code Registry} class is supported; - * otherwise, return {@code false}. - */ - public static synchronized boolean isSupported() { - return getSTclient() != null; - } - - private static List getCommandList() { - // Set up the arguments to call stclient - List command = new ArrayList(); - if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) { - // This is for jtreg testing use. This will be set to something - // like: - // $JAVA_HOME/bin/java -cp $TEST_DIR \ - // -Dstclient.registry.path=$TEST_DIR/registry.xml \ - // SvcTagClient - // - // On Windows, the JAVA_HOME and TEST_DIR path could contain - // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java. - // The SVCTAG_STCLIENT_CMD must be set with a list of - // space-separated parameters. If a parameter contains spaces, - // it must be quoted with '"'. - - String cmd = getSTclient(); - int len = cmd.length(); - int i = 0; - while (i < len) { - char separator = ' '; - if (cmd.charAt(i) == '"') { - separator = '"'; - i++; - } - // look for the separator or matched the closing '"' - int j; - for (j = i+1; j < len; j++) { - if (cmd.charAt(j) == separator) { - break; - } - } - - if (i == j-1) { - // add an empty parameter - command.add("\"\""); - } else { - // double quotes and space are not included - command.add(cmd.substring(i,j)); - } - - // skip spaces - for (i = j+1; i < len; i++) { - if (!Character.isSpaceChar(cmd.charAt(i))) { - break; - } - } - } - if (isVerbose()) { - System.out.println("Command list:"); - for (String s : command) { - System.out.println(s); - } - } - } else { - command.add(getSTclient()); - } - return command; - } - - // Returns null if the service tag record not found; - // or throw UnauthorizedAccessException or IOException - // based on the exitValue. - private static ServiceTag checkReturnError(int exitValue, - String output, - ServiceTag st) throws IOException { - switch (exitValue) { - case ST_ERR_REC_NOT_FOUND: - return null; - case ST_ERR_NOT_AUTH: - if (st != null) { - throw new UnauthorizedAccessException( - "Not authorized to access " + st.getInstanceURN() + - " installer_uid=" + st.getInstallerUID()); - } else { - throw new UnauthorizedAccessException( - "Not authorized:" + output); - } - default: - throw new IOException("stclient exits with error" + - " (" + exitValue + ")\n" + output); - } - } - - /** - * Adds a service tag to this registry. - * If the given service tag has an empty instance_urn, - * this helper class will generate a URN and place it in the - * copy of the service tag in this registry. - * This method will return the {@code ServiceTag} representing - * the service tag entry to this registry. - * - * @param st {@code ServiceTag} object - * @return a {@code ServiceTag} object representing the service tag - * entry to this registry. - * - * @throws IllegalArgumentException if a service tag of the same - * instance_urn already exists in this registry. - * - * @throws java.io.IOException if an I/O error occurs in this operation. - */ - public ServiceTag addServiceTag(ServiceTag st) throws IOException { - List command = getCommandList(); - command.add("-a"); - if (st.getInstanceURN().length() > 0) { - ServiceTag sysSvcTag = getServiceTag(st.getInstanceURN()); - if (sysSvcTag != null) { - throw new IllegalArgumentException("Instance_urn = " + - st.getInstanceURN() + " already exists"); - } - command.add("-i"); - command.add(st.getInstanceURN()); - } - command.add("-p"); - command.add(st.getProductName()); - command.add("-e"); - command.add(st.getProductVersion()); - command.add("-t"); - command.add(st.getProductURN()); - if (st.getProductParentURN().length() > 0) { - command.add("-F"); - command.add(st.getProductParentURN()); - } - command.add("-P"); - command.add(st.getProductParent()); - if (st.getProductDefinedInstanceID().length() > 0) { - command.add("-I"); - command.add(st.getProductDefinedInstanceID()); - } - command.add("-m"); - command.add(st.getProductVendor()); - command.add("-A"); - command.add(st.getPlatformArch()); - command.add("-z"); - command.add(st.getContainer()); - command.add("-S"); - command.add(st.getSource()); - - BufferedReader in = null; - try { - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - if (isVerbose()) { - System.out.println("Output from stclient -a command:"); - System.out.println(output); - } - String urn = ""; - if (p.exitValue() == 0) { - // Obtain the instance urn from the stclient output - in = new BufferedReader(new StringReader(output)); - String line = null; - while ((line = in.readLine()) != null) { - line = line.trim(); - if (line.startsWith(INSTANCE_URN_DESC)) { - urn = line.substring(INSTANCE_URN_DESC.length()); - break; - } - } - if (urn.length() == 0) { - throw new IOException("Error in creating service tag:\n" + - output); - } - return getServiceTag(urn); - } else { - return checkReturnError(p.exitValue(), output, st); - } - } finally { - if (in != null) { - in.close(); - } - } - } - - /** - * Removes a service tag of the given instance_urn from this - * registry. - * - * @param instanceURN the instance_urn of the service tag - * to be removed. - * - * @return the {@code ServiceTag} object removed from this registry; - * or {@code null} if the service tag does not exist in this registry. - * - * @throws UnauthorizedAccessException if the user is not authorized to - * remove the service tag of the given instance_urn - * from this registry. - * - * @throws java.io.IOException if an I/O error occurs in this operation. - */ - public ServiceTag removeServiceTag(String instanceURN) throws IOException { - ServiceTag st = getServiceTag(instanceURN); - if (st == null) { - return null; - } - - List command = getCommandList(); - command.add("-d"); - command.add("-i"); - command.add(instanceURN); - - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - if (isVerbose()) { - System.out.println("Output from stclient -d command:"); - System.out.println(output); - } - if (p.exitValue() == 0) { - return st; - } else { - return checkReturnError(p.exitValue(), output, st); - } - } - - /** - * Updates the product_defined_instance_id in the service tag - * of the specified instance_urn in this registry. - * - * @param instanceURN the instance_urn of the service tag to be updated. - * @param productDefinedInstanceID the value of the - * product_defined_instance_id to be set. - * - * @return the updated {@code ServiceTag} object; - * or {@code null} if the service tag does not exist in this - * registry. - * - * @throws UnauthorizedAccessException if the user is not authorized to - * update the service tag from this registry. - * - * @throws IOException if an I/O error occurs in this operation. - */ - public ServiceTag updateServiceTag(String instanceURN, - String productDefinedInstanceID) - throws IOException { - ServiceTag svcTag = getServiceTag(instanceURN); - if (svcTag == null) { - return null; - } - - List command = getCommandList(); - command.add("-u"); - command.add("-i"); - command.add(instanceURN); - command.add("-I"); - if (productDefinedInstanceID.length() > 0) { - command.add(productDefinedInstanceID); - } else { - command.add("\"\""); - } - - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - if (isVerbose()) { - System.out.println("Output from stclient -u command:"); - System.out.println(output); - } - - if (p.exitValue() == 0) { - return getServiceTag(instanceURN); - } else { - return checkReturnError(p.exitValue(), output, svcTag); - } - } - - /** - * Returns a {@code ServiceTag} object of the given instance_urn - * in this registry. - * - * @param instanceURN the instance_urn of the service tag - * @return a {@code ServiceTag} object of the given instance_urn - * in this registry; or {@code null} if not found. - * - * @throws java.io.IOException if an I/O error occurs in this operation. - */ - public ServiceTag getServiceTag(String instanceURN) throws IOException { - if (instanceURN == null) { - throw new NullPointerException("instanceURN is null"); - } - - List command = getCommandList(); - command.add("-g"); - command.add("-i"); - command.add(instanceURN); - - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - if (isVerbose()) { - System.out.println("Output from stclient -g command:"); - System.out.println(output); - } - if (p.exitValue() == 0) { - return parseServiceTag(output); - } else { - return checkReturnError(p.exitValue(), output, null); - } - } - - private ServiceTag parseServiceTag(String output) throws IOException { - BufferedReader in = null; - try { - Properties props = new Properties(); - // parse the service tag output from stclient - in = new BufferedReader(new StringReader(output)); - String line = null; - while ((line = in.readLine()) != null) { - if ((line = line.trim()).length() > 0) { - String[] ss = line.trim().split("=", 2); - if (ss.length == 2) { - props.setProperty(ss[0].trim(), ss[1].trim()); - } else { - props.setProperty(ss[0].trim(), ""); - } - } - } - - String urn = props.getProperty(ST_NODE_INSTANCE_URN); - String productName = props.getProperty(ST_NODE_PRODUCT_NAME); - String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION); - String productURN = props.getProperty(ST_NODE_PRODUCT_URN); - String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT); - String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN); - String productDefinedInstanceID = - props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID); - String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR); - String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH); - String container = props.getProperty(ST_NODE_CONTAINER); - String source = props.getProperty(ST_NODE_SOURCE); - int installerUID = - Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID)); - Date timestamp = - Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP)); - - return new ServiceTag(urn, - productName, - productVersion, - productURN, - productParent, - productParentURN, - productDefinedInstanceID, - productVendor, - platformArch, - container, - source, - installerUID, - timestamp); - } finally { - if (in != null) { - in.close(); - } - } - - } - - /** - * Returns the service tags of the specified - * product_urn in this registry. - * - * @param productURN the product_urn to look up - * @return a {@code Set} of {@code ServiceTag} objects - * of the specified product_urn in this registry. - * - * @throws java.io.IOException if an I/O error occurs in this operation. - */ - public Set findServiceTags(String productURN) throws IOException { - if (productURN == null) { - throw new NullPointerException("productURN is null"); - } - - List command = getCommandList(); - command.add("-f"); - command.add("-t"); - command.add(productURN); - - BufferedReader in = null; - try { - ProcessBuilder pb = new ProcessBuilder(command); - Process p = pb.start(); - String output = commandOutput(p); - - Set instances = new HashSet(); - if (p.exitValue() == 0) { - // parse the service tag output from stclient - in = new BufferedReader(new StringReader(output)); - String line = null; - while ((line = in.readLine()) != null) { - String s = line.trim(); - if (s.startsWith("urn:st:")) { - instances.add(getServiceTag(s)); - } - } - } else { - checkReturnError(p.exitValue(), output, null); - } - return instances; - } finally { - if (in != null) { - in.close(); - } - } - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/ServiceTag.java b/jdk/src/share/classes/com/sun/servicetag/ServiceTag.java deleted file mode 100644 index 4794f8d0de1..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/ServiceTag.java +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -import java.util.Date; -import java.io.IOException; -import static com.sun.servicetag.RegistrationDocument.*; - -/** - * A service tag is an XML-based data structure that identifies a product or - * a component on a system. The service tag schema is defined by the - * Service Tags Technology. The location of the DTD file is platform dependent. - * On Solaris, see /usr/share/lib/xml/dtd/servicetag.dtd. - *

- * A valid {@code ServiceTag} instance must comply to the service tag schema - * and contain the following fields: - *

    - *
  • {@link #getInstanceURN instance_urn}
  • - *
  • {@link #getProductName product_name}
  • - *
  • {@link #getProductVersion product_version}
  • - *
  • {@link #getProductURN product_urn}
  • - *
  • {@link #getProductParent product_parent}
  • - *
  • {@link #getProductParentURN product_parent_urn}
  • - *
  • {@link #getProductDefinedInstanceID product_defined_inst_id}
  • - *
  • {@link #getProductVendor product_vendor}
  • - *
  • {@link #getPlatformArch platform_arch}
  • - *
  • {@link #getContainer container}
  • - *
  • {@link #getSource source}
  • - *
  • {@link #getInstallerUID installer_uid}
  • - *
  • {@link #getTimestamp timestamp}
  • - *
- * - * The instance_urn can be specified when a {@code ServiceTag} - * object is created, or it can be generated when it is added to - * a {@link RegistrationData} object, or {@link Registry - * system service tag registry}. The installer_uid and - * timestamp are set when a {@code ServiceTag} object - * is added to a {@link RegistrationData} object, or {@link Registry - * system service tag registry}. - * - * @see Service Tags FAQ - */ -public class ServiceTag { - - private String instanceURN; - private String productName; - private String productVersion; - private String productURN; - private String productParent; - private String productParentURN; - private String productDefinedInstanceID; - private String productVendor; - private String platformArch; - private String container; - private String source; - private int installerUID; - private Date timestamp; - - // Service Tag Field Lengths (defined in sthelper.h) - // Since the constants defined in sthelper.h includes the null-terminated - // character, so minus 1 from the sthelper.h defined values. - private final int MAX_URN_LEN = 256 - 1; - private final int MAX_PRODUCT_NAME_LEN = 256 - 1; - private final int MAX_PRODUCT_VERSION_LEN = 64 - 1; - private final int MAX_PRODUCT_PARENT_LEN = 256 - 1; - private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1; - private final int MAX_PLATFORM_ARCH_LEN = 64 - 1; - private final int MAX_CONTAINER_LEN = 64 - 1; - private final int MAX_SOURCE_LEN = 64 - 1; - - // private constructors - private ServiceTag() { - } - // package private - ServiceTag(String instanceURN, - String productName, - String productVersion, - String productURN, - String productParent, - String productParentURN, - String productDefinedInstanceID, - String productVendor, - String platformArch, - String container, - String source, - int installerUID, - Date timestamp) { - setInstanceURN(instanceURN); - setProductName(productName); - setProductVersion(productVersion); - setProductURN(productURN); - setProductParentURN(productParentURN); - setProductParent(productParent); - setProductDefinedInstanceID(productDefinedInstanceID); - setProductVendor(productVendor); - setPlatformArch(platformArch); - setContainer(container); - setSource(source); - setInstallerUID(installerUID); - setTimestamp(timestamp); - } - - /** - * Creates a service tag object with no instance_urn. - * - * @param productName the name of the product. - * @param productVersion the version of the product. - * @param productURN the uniform resource name of the product - * @param productParent the name of the product's parent. - * @param productParentURN the uniform resource name of the product's parent. - * @param productDefinedInstanceID the instance identifier. - * @param productVendor the vendor of the product. - * @param platformArch the operating system architecture. - * @param container the container of the product. - * @param source the source of the product. - * - * @throws IllegalArgumentException if any value of the input fields - * does not conform to the service tag XML schema. - */ - public static ServiceTag newInstance(String productName, - String productVersion, - String productURN, - String productParent, - String productParentURN, - String productDefinedInstanceID, - String productVendor, - String platformArch, - String container, - String source) { - return new ServiceTag("", /* empty instance_urn */ - productName, - productVersion, - productURN, - productParent, - productParentURN, - productDefinedInstanceID, - productVendor, - platformArch, - container, - source, - -1, - null); - } - - /** - * Creates a service tag object with a specified instance_urn. - * - * @param instanceURN the uniform resource name of this instance. - * @param productName the name of the product. - * @param productVersion the version of the product. - * @param productURN the uniform resource name of the product - * @param productParent the name of the product's parent. - * @param productParentURN the uniform resource name of the product's parent. - * @param productDefinedInstanceID the instance identifier. - * @param productVendor the vendor of the product. - * @param platformArch the operating system architecture. - * @param container the container of the product. - * @param source the source of the product. - * - * @throws IllegalArgumentException if any value of the input fields - * does not conform to the service tag XML schema. - */ - public static ServiceTag newInstance(String instanceURN, - String productName, - String productVersion, - String productURN, - String productParent, - String productParentURN, - String productDefinedInstanceID, - String productVendor, - String platformArch, - String container, - String source) { - return new ServiceTag(instanceURN, - productName, - productVersion, - productURN, - productParent, - productParentURN, - productDefinedInstanceID, - productVendor, - platformArch, - container, - source, - -1, - null); - } - - // Creates a copy of the ServiceTag instance - // with instance_urn and timestamp initialized - static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) { - String instanceURN = - (st.getInstanceURN().length() == 0 ? Util.generateURN() : - st.getInstanceURN()); - ServiceTag svcTag = new ServiceTag(instanceURN, - st.getProductName(), - st.getProductVersion(), - st.getProductURN(), - st.getProductParent(), - st.getProductParentURN(), - st.getProductDefinedInstanceID(), - st.getProductVendor(), - st.getPlatformArch(), - st.getContainer(), - st.getSource(), - st.getInstallerUID(), - new Date()); - return svcTag; - } - - /** - * Returns a uniform resource name (URN) in this format: - *
- * "urn:st:<32-char {@link java.util.UUID uuid}>" - *
- * @return a URN. - */ - public static String generateInstanceURN() { - return Util.generateURN(); - } - - /** - * Returns the uniform resource name of this service tag instance. - * - * @return the instance_urn of this service tag. - */ - public String getInstanceURN() { - return instanceURN; - } - - /** - * Returns the name of the product. - * - * @return the product name. - */ - public String getProductName() { - return productName; - } - - /** - * Returns the version of the product. - * - * @return the product version. - */ - public String getProductVersion() { - return productVersion; - } - - /** - * Returns the uniform resource name of the product. - * - * @return the product URN. - */ - public String getProductURN() { - return productURN; - } - - /** - * Returns the uniform resource name of the product's parent. - * - * @return the product's parent URN. - */ - public String getProductParentURN() { - return productParentURN; - } - - /** - * Returns the name of the product's parent. - * - * @return the product's parent name. - */ - public String getProductParent() { - return productParent; - } - - /** - * Returns the identifier defined for this product instance. - * - * @return the identifier defined for this product instance. - */ - public String getProductDefinedInstanceID() { - return productDefinedInstanceID; - } - - /** - * Returns the vendor of the product. - * - * @return the product vendor. - */ - public String getProductVendor() { - return productVendor; - } - - /** - * Returns the platform architecture on which the product - * is running on. - * - * @return the platform architecture on which the product is running on. - */ - public String getPlatformArch() { - return platformArch; - } - - /** - * Returns the timestamp. This timestamp is set when this service tag - * is added to or updated in a {@code RegistrationData} object or - * the system service tag registry. - * This method may return {@code null}. - * - * @return timestamp when this service tag - * is added to or updated in a {@code RegistrationData} object or - * the system service tag registry, or {@code null}. - */ - public Date getTimestamp() { - if (timestamp != null) { - return (Date) timestamp.clone(); - } else { - return null; - } - } - - - /** - * Returns the container of the product. - * - * @return the container of the product. - */ - public String getContainer() { - return container; - } - - /** - * Returns the source of this service tag. - * - * @return source of this service tag. - */ - public String getSource() { - return source; - } - - /** - * Returns the UID. The UID is set when this service tag - * is added to or updated in the system service tag registry. - * This is platform dependent whose default value is {@code -1}. - * When this service tag is added to a {@code RegistrationData}, - * the UID is not set. - * - * @return the UID of whom this service tag - * is added to or updated in the system service tag registry, - * or {@code -1}. - */ - public int getInstallerUID() { - return installerUID; - } - - // The following setter methods are used to validate the - // input field when constructing a ServiceTag instance - - private void setInstanceURN(String instanceURN) { - if (instanceURN == null) { - throw new NullPointerException("Parameter instanceURN cannot be null"); - } - if (instanceURN.length() > MAX_URN_LEN) { - throw new IllegalArgumentException("instanceURN \"" + instanceURN + - "\" exceeds maximum length " + MAX_URN_LEN); - } - this.instanceURN = instanceURN; - } - - private void setProductName(String productName) { - if (productName == null) { - throw new NullPointerException("Parameter productName cannot be null"); - } - if (productName.length() == 0) { - throw new IllegalArgumentException("product name cannot be empty"); - } - if (productName.length() > MAX_PRODUCT_NAME_LEN) { - throw new IllegalArgumentException("productName \"" + productName + - "\" exceeds maximum length " + MAX_PRODUCT_NAME_LEN); - } - this.productName = productName; - } - - private void setProductVersion(String productVersion) { - if (productVersion == null) { - throw new NullPointerException("Parameter productVersion cannot be null"); - } - - if (productVersion.length() == 0) { - throw new IllegalArgumentException("product version cannot be empty"); - } - if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) { - throw new IllegalArgumentException("productVersion \"" + - productVersion + "\" exceeds maximum length " + - MAX_PRODUCT_VERSION_LEN); - } - this.productVersion = productVersion; - } - - private void setProductURN(String productURN) { - if (productURN == null) { - throw new NullPointerException("Parameter productURN cannot be null"); - } - if (productURN.length() == 0) { - throw new IllegalArgumentException("product URN cannot be empty"); - } - if (productURN.length() > MAX_URN_LEN) { - throw new IllegalArgumentException("productURN \"" + productURN + - "\" exceeds maximum length " + MAX_URN_LEN); - } - this.productURN = productURN; - } - - private void setProductParentURN(String productParentURN) { - if (productParentURN == null) { - throw new NullPointerException("Parameter productParentURN cannot be null"); - } - // optional field - can be empty - if (productParentURN.length() > MAX_URN_LEN) { - throw new IllegalArgumentException("productParentURN \"" + - productParentURN + "\" exceeds maximum length " + - MAX_URN_LEN); - } - this.productParentURN = productParentURN; - } - - private void setProductParent(String productParent) { - if (productParent == null) { - throw new NullPointerException("Parameter productParent cannot be null"); - } - if (productParent.length() == 0) { - throw new IllegalArgumentException("product parent cannot be empty"); - } - if (productParent.length() > MAX_PRODUCT_PARENT_LEN) { - throw new IllegalArgumentException("productParent \"" + - productParent + "\" exceeds maximum length " + - MAX_PRODUCT_PARENT_LEN); - } - this.productParent = productParent; - } - - void setProductDefinedInstanceID(String productDefinedInstanceID) { - if (productDefinedInstanceID == null) { - throw new NullPointerException("Parameter productDefinedInstanceID cannot be null"); - } - if (productDefinedInstanceID.length() > MAX_URN_LEN) { - throw new IllegalArgumentException("productDefinedInstanceID \"" + - productDefinedInstanceID + "\" exceeds maximum length " + - MAX_URN_LEN); - } - // optional field - can be empty - this.productDefinedInstanceID = productDefinedInstanceID; - } - - private void setProductVendor(String productVendor) { - if (productVendor == null) { - throw new NullPointerException("Parameter productVendor cannot be null"); - } - if (productVendor.length() == 0) { - throw new IllegalArgumentException("product vendor cannot be empty"); - } - if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) { - throw new IllegalArgumentException("productVendor \"" + - productVendor + "\" exceeds maximum length " + - MAX_PRODUCT_VENDOR_LEN); - } - this.productVendor = productVendor; - } - - private void setPlatformArch(String platformArch) { - if (platformArch == null) { - throw new NullPointerException("Parameter platformArch cannot be null"); - } - if (platformArch.length() == 0) { - throw new IllegalArgumentException("platform architecture cannot be empty"); - } - if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) { - throw new IllegalArgumentException("platformArch \"" + - platformArch + "\" exceeds maximum length " + - MAX_PLATFORM_ARCH_LEN); - } - this.platformArch = platformArch; - } - - private void setTimestamp(Date timestamp) { - // can be null - this.timestamp = timestamp; - } - - private void setContainer(String container) { - if (container == null) { - throw new NullPointerException("Parameter container cannot be null"); - } - if (container.length() == 0) { - throw new IllegalArgumentException("container cannot be empty"); - } - if (container.length() > MAX_CONTAINER_LEN) { - throw new IllegalArgumentException("container \"" + - container + "\" exceeds maximum length " + - MAX_CONTAINER_LEN); - } - this.container = container; - } - - private void setSource(String source) { - if (source == null) { - throw new NullPointerException("Parameter source cannot be null"); - } - if (source.length() == 0) { - throw new IllegalArgumentException("source cannot be empty"); - } - if (source.length() > MAX_SOURCE_LEN) { - throw new IllegalArgumentException("source \"" + source + - "\" exceeds maximum length " + MAX_SOURCE_LEN); - } - this.source = source; - } - - private void setInstallerUID(int installerUID) { - this.installerUID = installerUID; - } - - /** - * Compares this service tag to the specified object. - * The result is {@code true} if and only if the argument is - * not {@code null} and is a {@code ServiceTag} object whose - * instance_urn is the same as the - * instance_urn of this service tag. - * - * @return {@code true} if this service tag is the same as - * the specified object. - */ - @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof ServiceTag)) { - return false; - } - ServiceTag st = (ServiceTag) obj; - if (st == this) { - return true; - } - return st.getInstanceURN().equals(getInstanceURN()); - } - - /** - * Returns the hash code value for this service tag. - * @return the hash code value for this service tag. - */ - @Override - public int hashCode() { - int hash = 7; - hash = 19 * hash + (this.instanceURN != null ? this.instanceURN.hashCode() : 0); - return hash; - } - - /** - * Returns the string representation of this service tag. - * The format is implementation specific. - * - * @return the string representation of this service tag. - */ - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN).append("\n"); - sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName).append("\n"); - sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(productVersion).append("\n"); - sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN).append("\n"); - sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(productParentURN).append("\n"); - sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(productParent).append("\n"); - sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(productDefinedInstanceID).append("\n"); - sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(productVendor).append("\n"); - sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(platformArch).append("\n"); - sb.append(ST_NODE_TIMESTAMP).append("=").append(Util.formatTimestamp(timestamp)).append("\n"); - sb.append(ST_NODE_CONTAINER).append("=").append(container).append("\n"); - sb.append(ST_NODE_SOURCE).append("=").append(source).append("\n"); - sb.append(ST_NODE_INSTALLER_UID).append("=").append(String.valueOf(installerUID)).append("\n"); - return sb.toString(); - } - - - /** - * Returns the {@link ServiceTag} instance for the running Java - * platform. The {@link ServiceTag#setSource source} field - * of the {@code ServiceTag} will be set to the given {@code source}. - * This method will return {@code null} if there is no service tag - * for the running Java platform. - *

- * This method is designed for Sun software that bundles the JDK - * or the JRE to use. It is recommended that the {@code source} - * string contains information about the bundling software - * such as the name and the version of the software bundle, - * for example, - *

- * NetBeans IDE 6.0 with JDK 6 Update 5 Bundle - *
- * in a NetBeans/JDK bundle. - *

- * At the first time to call this method the application - * is required to have the write permission to the installed - * directory of this running JDK or JRE instance. - * - * @param source the source that bundles the JDK or the JRE. - * @return a {@code ServiceTag} object for the Java platform, - * or {@code null} if not supported. - * @throws IOException if an error occurs in this operation. - */ - public static ServiceTag getJavaServiceTag(String source) throws IOException { - return Installer.getJavaServiceTag(source); - } - -} diff --git a/jdk/src/share/classes/com/sun/servicetag/SolarisServiceTag.java b/jdk/src/share/classes/com/sun/servicetag/SolarisServiceTag.java deleted file mode 100644 index 6b4ae39a1b0..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/SolarisServiceTag.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -import java.io.IOException; -import java.util.Set; - -/** - * Utility class to obtain the service tag for the Solaris Operating System. - */ -class SolarisServiceTag { - private final static String[] SolarisProductURNs = new String[] { - "urn:uuid:a7a38948-2bd5-11d6-98ce-9d3ac1c0cfd7", /* Solaris 8 */ - "urn:uuid:4f82caac-36f3-11d6-866b-85f428ef944e", /* Solaris 9 */ - "urn:uuid:a19de03b-48bc-11d9-9607-080020a9ed93", /* Solaris 9 sparc */ - "urn:uuid:4c35c45b-4955-11d9-9607-080020a9ed93", /* Solaris 9 x86 */ - "urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113", /* Solaris 10 */ - "urn:uuid:6df19e63-7ef5-11db-a4bd-080020a9ed93" /* Solaris 11 */ - }; - - /** - * Returns null if not found. - * - * There is only one service tag for the operating system. - */ - static ServiceTag getServiceTag() throws IOException { - if (Registry.isSupported()) { - Registry streg = Registry.getSystemRegistry(); - for (String parentURN : SolarisProductURNs) { - Set instances = streg.findServiceTags(parentURN); - for (ServiceTag st : instances) { - // there should have only one service tag for the OS - return st; - } - } - } - return null; - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java deleted file mode 100644 index 19cbae0b4a1..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/SolarisSystemEnvironment.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -// This class is a copy of the com.sun.scn.servicetags.SolarisSystemEnvironment -// class from the Sun Connection source. -// -// The Service Tags team maintains the latest version of the implementation -// for system environment data collection. JDK will include a copy of -// the most recent released version for a JDK release. We rename -// the package to com.sun.servicetag so that the Sun Connection -// product always uses the latest version from the com.sun.scn.servicetags -// package. JDK and users of the com.sun.servicetag API -// (e.g. NetBeans and SunStudio) will use the version in JDK. -// -// So we keep this class in src/share/classes instead of src//classes. - -import java.io.*; - -/** - * Solaris implementation of the SystemEnvironment class. - */ -class SolarisSystemEnvironment extends SystemEnvironment { - private static final String ORACLE = "Oracle Corporation"; - SolarisSystemEnvironment() { - setHostId(getCommandOutput("/usr/bin/hostid")); - setSystemModel(getCommandOutput("/usr/bin/uname", "-i")); - setSystemManufacturer(getSolarisSystemManufacturer()); - setCpuManufacturer(getSolarisCpuManufacturer()); - setSerialNumber(getSolarisSN()); - } - - /** - * Tries to obtain the cpu manufacturer. - * @return The cpu manufacturer (an empty string if not found or an error occurred) - */ - private String getSolarisCpuManufacturer() { - // not fully accurate, this could be another manufacturer (fujitsu for example) - if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return ORACLE; - } - - // if we're here, then we'll try smbios (type 4) - return getSmbiosData("4", "Manufacturer: "); - } - - /** - * Tries to obtain the system manufacturer. - * @return The system manufacturer (an empty string if not found or an error occurred) - */ - private String getSolarisSystemManufacturer() { - // not fully accurate, this could be another manufacturer (fujitsu for example) - if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { - return ORACLE; - } - - // if we're here, then we'll try smbios (type 1) - return getSmbiosData("1", "Manufacturer: "); - } - - /** - * Tries to obtain the serial number. - * @return The serial number (empty string if not found or an error occurred) - */ - private String getSolarisSN() { - // try to read from the psn file if it exists - String tmp = getFileContent("/var/run/psn"); - if (tmp.length() > 0) { - return tmp.trim(); - } - - // if we're here, then we'll try sneep - String tmpSN = getSneepSN(); - if (tmpSN.length() > 0) { - return tmpSN; - } - - // if we're here, then we'll try smbios (type 1) - tmpSN = getSmbiosData("1", "Serial Number: "); - if (tmpSN.length() > 0) { - return tmpSN; - } - - // if we're here, then we'll try smbios (type 3) - tmpSN = getSmbiosData("3", "Serial Number: "); - if (tmpSN.length() > 0) { - return tmpSN; - } - - // give up and return - return ""; - } - - // Sample smbios output segment: - // ID SIZE TYPE - // 1 150 SMB_TYPE_SYSTEM (system information) - // - // Manufacturer: Oracle Corporation - // Product: Sun Fire X4600 - // Version: To Be Filled By O.E.M. - // Serial Number: 00:14:4F:45:0C:2A - private String getSmbiosData(String type, String target) { - String output = getCommandOutput("/usr/sbin/smbios", "-t", type); - for (String s : output.split("\n")) { - if (s.contains(target)) { - int indx = s.indexOf(target) + target.length(); - if (indx < s.length()) { - String tmp = s.substring(indx).trim(); - String lowerCaseStr = tmp.toLowerCase(); - if (!lowerCaseStr.startsWith("not available") - && !lowerCaseStr.startsWith("to be filled by o.e.m")) { - return tmp; - } - } - } - } - - return ""; - } - - private String getSneepSN() { - String basedir = getCommandOutput("pkgparam","SUNWsneep","BASEDIR"); - File f = new File(basedir + "/bin/sneep"); - if (f.exists()) { - String sneepSN = getCommandOutput(basedir + "/bin/sneep"); - if (sneepSN.equalsIgnoreCase("unknown")) { - return ""; - } else { - return sneepSN; - } - } else { - return ""; - } - } - -} diff --git a/jdk/src/share/classes/com/sun/servicetag/SunConnection.java b/jdk/src/share/classes/com/sun/servicetag/SunConnection.java deleted file mode 100644 index f5a13b61380..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/SunConnection.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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.servicetag; - -import java.io.*; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.io.OutputStreamWriter; -import java.util.Locale; -import javax.net.ssl.HttpsURLConnection; - -/** - * Sun Connection Class for Product Registration. - * - * Registration Web Application Interface - * 1) POST the product registry to the output stream of the registration - * relay service. - * 2) Open the webapp URL from a browser with the following parameters: - * registry-urn - * product=jdk - * locale= - * version= - * - * @see https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/ - * - */ -class SunConnection { - - private static String JDK_REGISTRATION_URL = "https://hs-ws1.oracle.com/"; - private static String SANDBOX_TESTING_URL = "https://hs-ws1-tst.oracle.com/"; - private static String REGISTRATION_WEB_PATH = "RegistrationWeb/register"; - - // System properties for testing - private static String SVCTAG_REGISTER_TESTING = "servicetag.register.testing"; - private static String SVCTAG_REGISTRATION_URL = "servicetag.registration.url"; - private static String SVCTAG_CONNECTION_TIMEOUT = "servicetag.connection.timeout"; - - private SunConnection() { - } - - /** - * Returns a URL for JDK registration interfacing with the Sun Connection - * registration relay service in this form: - * /?product=jdk&locale= - * - * The can be overridden by an environment - * variable or a system property. - * - * 1) "servicetag.register.testing" system property to switch to the - * Sun Connection registration sandbox testing. - * 2) "servicetag.registration.url" system property to override - * the URL - * 3) Default production URL - * - */ - static URL getRegistrationURL(String registrationURN, Locale locale, String version) { - String url = System.getProperty(SVCTAG_REGISTRATION_URL); - if (url == null) { - if (System.getProperty(SVCTAG_REGISTER_TESTING) != null) { - url = SANDBOX_TESTING_URL; - } else { - url = JDK_REGISTRATION_URL; - } - } - url += REGISTRATION_WEB_PATH; - - // trim whitespaces - url = url.trim(); - if (url.length() == 0) { - throw new InternalError("Empty registration url set"); - } - - // Add the registry_urn in the URL's query - String registerURL = rewriteURL(url, registrationURN, locale, version); - try { - return new URL(registerURL); - } catch (MalformedURLException ex) { - // should never reach here - throw new InternalError(ex.getMessage(), ex); - } - } - - private static String rewriteURL(String url, String registryURN, Locale locale, String version) { - StringBuilder sb = new StringBuilder(url.trim()); - int len = sb.length(); - if (sb.charAt(len-1) != '/') { - sb.append('/'); - } - sb.append(registryURN); - sb.append("?"); - sb.append("product=jdk"); - sb.append("&"); - sb.append("locale=").append(locale.toString()); - sb.append("&"); - sb.append("version=").append(version); - return sb.toString(); - } - - /** - * Registers all products in the given product registry. If it fails - * to post the service tag registry, open the browser with the offline - * registration page. - * - * @param regData registration data to be posted to the Sun Connection - * for registration. - * @param locale Locale - * @param version JDK version - * - * @throws IOException if I/O error occurs in this operation - */ - public static void register(RegistrationData regData, - Locale locale, - String version) throws IOException { - // Gets the URL for SunConnection registration relay service - URL url = getRegistrationURL(regData.getRegistrationURN(), - locale, - version); - - // Post the Product Registry to Sun Connection - boolean succeed = postRegistrationData(url, regData); - if (succeed) { - // service tags posted successfully - // now prompt for registration - openBrowser(url); - } else { - // open browser with the offline registration page - openOfflineRegisterPage(); - } - } - - /** - * Opens a browser for JDK product registration. - * @param url Registration Webapp URL - */ - private static void openBrowser(URL url) throws IOException { - if (!BrowserSupport.isSupported()) { - if (Util.isVerbose()) { - System.out.println("Browser is not supported"); - } - return; - } - - try { - BrowserSupport.browse(url.toURI()); - } catch (URISyntaxException ex) { - throw new InternalError("Error in registering: " + ex.getMessage(), ex); - } catch (IllegalArgumentException ex) { - if (Util.isVerbose()) { - ex.printStackTrace(); - } - } catch (UnsupportedOperationException ex) { - // ignore if not supported - if (Util.isVerbose()) { - ex.printStackTrace(); - } - } - } - - /** - * POST service tag registry to Sun Connection - * @param loc the URL of the webapp to handle the POST request - * @param streg the Service Tag registry - * @return true if posting succeeds; otherwise, false. - */ - private static boolean postRegistrationData(URL url, - RegistrationData registration) { - try { - HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); - con.setDoInput(true); - con.setDoOutput(true); - con.setUseCaches(false); - con.setAllowUserInteraction(false); - - // default 10 seconds timeout - String timeout = System.getProperty(SVCTAG_CONNECTION_TIMEOUT, "10"); - con.setConnectTimeout(Util.getIntValue(timeout) * 1000); - - if (Util.isVerbose()) { - System.out.println("Connecting to post registration data at " + url); - } - - con.setRequestMethod("POST"); - con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\""); - con.connect(); - - OutputStream out = null; - try { - out = con.getOutputStream(); - registration.storeToXML(out); - out.flush(); - } finally { - if (out != null) { - out.close(); - } - } - - int returnCode = con.getResponseCode(); - if (Util.isVerbose()) { - System.out.println("POST return status = " + returnCode); - printReturnData(con, returnCode); - } - return (returnCode == HttpURLConnection.HTTP_OK); - } catch (MalformedURLException me) { - // should never reach here - throw new InternalError("Error in registering: " + me.getMessage(), me); - } catch (Exception ioe) { - // SocketTimeoutException, IOException or UnknownHostException - if (Util.isVerbose()) { - ioe.printStackTrace(); - } - return false; - } - } - - /** - * Opens the offline registratioin page in the browser. - * - */ - private static void openOfflineRegisterPage() - throws IOException { - if (!BrowserSupport.isSupported()) { - if (Util.isVerbose()) { - System.out.println("Browser is not supported"); - } - return; - } - - File registerPage = Installer.getRegistrationHtmlPage(); - try { - BrowserSupport.browse(registerPage.toURI()); - } catch (FileNotFoundException ex) { - // should never reach here - throw new InternalError( - "Error in launching " + registerPage + ": " + ex.getMessage() - , ex); - } catch (IllegalArgumentException ex) { - if (Util.isVerbose()) { - ex.printStackTrace(); - } - } catch (UnsupportedOperationException ex) { - // ignore if not supported - if (Util.isVerbose()) { - ex.printStackTrace(); - } - } - } - - private static void printReturnData(HttpURLConnection con, int returnCode) - throws IOException { - BufferedReader reader = null; - try { - if (returnCode < 400) { - reader = new BufferedReader( - new InputStreamReader(con.getInputStream())); - } else { - reader = new BufferedReader( - new InputStreamReader(con.getErrorStream())); - } - StringBuilder sb = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - sb.append(line).append("\n"); - } - System.out.println("Response is : "); - System.out.println(sb.toString()); - } finally { - if (reader != null) { - reader.close(); - } - } - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/SystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/SystemEnvironment.java deleted file mode 100644 index d1ec3fe733b..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/SystemEnvironment.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -// This class is a copy of the com.sun.scn.servicetags.SystemEnvironment -// class from the Sun Connection source. -// -// The Service Tags team maintains the latest version of the implementation -// for system environment data collection. JDK will include a copy of -// the most recent released version for a JDK release. We rename -// the package to com.sun.servicetag so that the Sun Connection -// product always uses the latest version from the com.sun.scn.servicetags -// package. JDK and users of the com.sun.servicetag API -// (e.g. NetBeans and SunStudio) will use the version in JDK. - -import java.io.*; -import java.net.InetAddress; -import java.net.UnknownHostException; - -/** - * SystemEnvironment class collects the environment data with the - * best effort from the underlying platform. - */ -public class SystemEnvironment { - private String hostname; - private String hostId; - private String osName; - private String osVersion; - private String osArchitecture; - private String systemModel; - private String systemManufacturer; - private String cpuManufacturer; - private String serialNumber; - private static SystemEnvironment sysEnv = null; - - public static synchronized SystemEnvironment getSystemEnvironment() { - if (sysEnv == null) { - String os = System.getProperty("os.name"); - if (os.equals("SunOS")) { - sysEnv = new SolarisSystemEnvironment(); - } else if (os.equals("Linux")) { - sysEnv = new LinuxSystemEnvironment(); - } else if (os.startsWith("Windows")) { - sysEnv = new WindowsSystemEnvironment(); - } else { - sysEnv = new SystemEnvironment(); - } - } - return sysEnv; - } - - // package-private - SystemEnvironment() { - try { - this.hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException ex) { - this.hostname = "Unknown host"; - } - this.hostId = ""; - this.osName = System.getProperty("os.name"); - this.osVersion = System.getProperty("os.version"); - this.osArchitecture = System.getProperty("os.arch"); - this.systemModel = ""; - this.systemManufacturer = ""; - this.cpuManufacturer = ""; - this.serialNumber = ""; - } - - - /** - * Sets the hostname. - * @param hostname The hostname to set. - */ - public void setHostname(String hostname) { - this.hostname = hostname; - } - - /** - * Sets the OS name. - * @param osName The osName to set. - */ - public void setOsName(String osName) { - this.osName = osName; - } - - /** - * Sets the OS version. - * @param osVersion The osVersion to set. - */ - public void setOsVersion(String osVersion) { - this.osVersion = osVersion; - } - - /** - * Sets the OS architecture. - * @param osArchitecture The osArchitecture to set. - */ - public void setOsArchitecture(String osArchitecture) { - this.osArchitecture = osArchitecture; - } - - /** - * Sets the system model. - * @param systemModel The systemModel to set. - */ - public void setSystemModel(String systemModel) { - this.systemModel = systemModel; - } - - /** - * Sets the system manufacturer. - * @param systemManufacturer The systemManufacturer to set. - */ - public void setSystemManufacturer(String systemManufacturer) { - this.systemManufacturer = systemManufacturer; - } - - /** - * Sets the cpu manufacturer. - * @param cpuManufacturer The cpuManufacturer to set. - */ - public void setCpuManufacturer(String cpuManufacturer) { - this.cpuManufacturer = cpuManufacturer; - } - - /** - * Sets the serial number. - * @param serialNumber The serialNumber to set. - */ - public void setSerialNumber(String serialNumber) { - this.serialNumber = serialNumber; - } - - /** - * Sets the hostid. Truncates to a max length of 16 chars. - * @param hostId The hostid to set. - */ - public void setHostId(String hostId) { - if (hostId == null || hostId.equals("null")) { - hostId = ""; - } - if (hostId.length() > 16) { - hostId = hostId.substring(0,16); - } - this.hostId = hostId; - } - - /** - * Returns the hostname. - * @return The hostname. - */ - public String getHostname() { - return hostname; - } - - /** - * Returns the osName. - * @return The osName. - */ - public String getOsName() { - return osName; - } - - /** - * Returns the osVersion. - * @return The osVersion. - */ - public String getOsVersion() { - return osVersion; - } - - /** - * Returns the osArchitecture. - * @return The osArchitecture. - */ - public String getOsArchitecture() { - return osArchitecture; - } - - /** - * Returns the systemModel. - * @return The systemModel. - */ - public String getSystemModel() { - return systemModel; - } - - /** - * Returns the systemManufacturer. - * @return The systemManufacturer. - */ - public String getSystemManufacturer() { - return systemManufacturer; - } - - /** - * Returns the serialNumber. - * @return The serialNumber. - */ - public String getSerialNumber() { - return serialNumber; - } - - /** - * Returns the hostId. - * @return The hostId. - */ - public String getHostId() { - return hostId; - } - - /** - * Returns the cpuManufacturer. - * @return The cpuManufacturer. - */ - public String getCpuManufacturer() { - return cpuManufacturer; - } - - protected String getCommandOutput(String... command) { - StringBuilder sb = new StringBuilder(); - BufferedReader br = null; - Process p = null; - try { - ProcessBuilder pb = new ProcessBuilder(command); - p = pb.start(); - p.waitFor(); - - if (p.exitValue() == 0) { - br = new BufferedReader(new InputStreamReader(p.getInputStream())); - String line = null; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (line.length() > 0) { - if (sb.length() > 0) { - sb.append("\n"); - } - sb.append(line); - } - } - } - return sb.toString(); - } catch (InterruptedException ie) { - // in case the command hangs - if (p != null) { - p.destroy(); - } - return ""; - } catch (Exception e) { - // ignore exception - return ""; - } finally { - if (p != null) { - try { - p.getErrorStream().close(); - } catch (IOException e) { - // ignore - } - try { - p.getInputStream().close(); - } catch (IOException e) { - // ignore - } - try { - p.getOutputStream().close(); - } catch (IOException e) { - // ignore - } - p = null; - } - if (br != null) { - try { - br.close(); - } catch (IOException e) { - // ignore - } - } - } - } - - protected String getFileContent(String filename) { - File f = new File(filename); - if (!f.exists()) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader(f)); - String line = null; - while ((line = br.readLine()) != null) { - line = line.trim(); - if (line.length() > 0) { - if (sb.length() > 0) { - sb.append("\n"); - } - sb.append(line); - } - } - return sb.toString(); - } catch (Exception e) { - // ignore exception - return ""; - } finally { - if (br != null) { - try { - br.close(); - } catch (IOException e) { - // ignore - } - } - } - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/UnauthorizedAccessException.java b/jdk/src/share/classes/com/sun/servicetag/UnauthorizedAccessException.java deleted file mode 100644 index 6d85ca3931d..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/UnauthorizedAccessException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -/** - * Thrown if the user is not authorized to - * {@link Registry#updateServiceTag update} or - * {@link Registry#removeServiceTag remove} - * a service tag from a {@link Registry}. - */ -public class UnauthorizedAccessException extends RuntimeException { - - /** - * Constructs an UnauthorizedAccessException object - * without detail message. - */ - public UnauthorizedAccessException() { - } - - - /** - * Constructs an UnauthorizedAccessException object - * with the specified detail message. - * - * @param msg the detail message. - */ - public UnauthorizedAccessException(String msg) { - super(msg); - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/Util.java b/jdk/src/share/classes/com/sun/servicetag/Util.java deleted file mode 100644 index 055edfac159..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/Util.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -import java.io.*; -import java.util.Date; -import java.text.SimpleDateFormat; -import java.text.ParseException; -import java.util.TimeZone; -import java.util.UUID; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -// Utility class for com.sun.servicetag package -class Util { - private static boolean verbose = (System.getProperty("servicetag.verbose") != null); - private static String jrepath = null; - private static final String REGKEY_TAIL = - "microsoft\\windows\\currentversion\\app paths\\stclient.exe"; - private static final String STCLIENT_TAIL = "sun\\servicetag\\stclient.exe"; - private static final String WIN32_STCLIENT = - "c:\\Program Files (x86)\\" + STCLIENT_TAIL; - - // for debugging and tracing - static boolean isVerbose() { - return verbose; - } - - /** - * Gets the pathname of JRE in the running platform - * This can be a JDK or JRE. - */ - static synchronized String getJrePath() { - if (jrepath == null) { - // Determine the JRE path by checking the existence of - // /jre/lib and /lib. - String javaHome = System.getProperty("java.home"); - jrepath = javaHome + File.separator + "jre"; - File f = new File(jrepath, "lib"); - if (!f.exists()) { - // java.home usually points to the JRE path - jrepath = javaHome; - } - } - return jrepath; - } - - /** - * Tests if the running platform is a JDK. - */ - static boolean isJdk() { - // /jre exists which implies it's a JDK - return getJrePath().endsWith(File.separator + "jre"); - } - - /** - * Generates the URN string of "urn:st" namespace - */ - static String generateURN() { - return "urn:st:" + UUID.randomUUID().toString(); - } - - static int getIntValue(String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("\"" + value + "\"" + - " expected to be an integer"); - } - } - - /** - * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT. - * @param timestamp Date - * @return a string representation of the timestamp - * in the YYYY-MM-dd HH:mm:ss GMT format. - */ - static String formatTimestamp(Date timestamp) { - if (timestamp == null) { - return "[No timestamp]"; - } - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - df.setTimeZone(TimeZone.getTimeZone("GMT")); - return df.format(timestamp); - } - - /** - * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format. - * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format. - * @return Date - */ - static Date parseTimestamp(String timestamp) { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - df.setTimeZone(TimeZone.getTimeZone("GMT")); - try { - return df.parse(timestamp); - } catch (ParseException e) { - // should not reach here - e.printStackTrace(); - return new Date(); - } - } - - static String commandOutput(Process p) throws IOException { - Reader r = null; - Reader err = null; - try { - r = new InputStreamReader(p.getInputStream()); - err = new InputStreamReader(p.getErrorStream()); - String output = commandOutput(r); - String errorMsg = commandOutput(err); - p.waitFor(); - return output + errorMsg.trim(); - } catch (InterruptedException e) { - if (isVerbose()) { - e.printStackTrace(); - } - return e.getMessage(); - } finally { - try { - if (r != null) { - r.close(); - } - } finally { - if (err != null) { - err.close(); - } - } - } - } - - static String commandOutput(Reader r) throws IOException { - StringBuilder sb = new StringBuilder(); - int c; - while ((c = r.read()) > 0) { - if (c != '\r') { - sb.append((char) c); - } - } - return sb.toString(); - } - - static int getJdkVersion() { - parseVersion(); - return jdkVersion; - } - - static int getUpdateVersion() { - parseVersion(); - return jdkUpdate; - } - - private static int jdkVersion = 0; - private static int jdkUpdate = 0; - private static synchronized void parseVersion() { - if (jdkVersion > 0) { - return; - } - - // parse java.runtime.version - // valid format of the version string is: - // n.n.n[_uu[c]][-]-bxx - String cs = System.getProperty("java.runtime.version"); - if (cs.length() >= 5 && - Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && - Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && - Character.isDigit(cs.charAt(4))) { - jdkVersion = Character.digit(cs.charAt(2), 10); - cs = cs.substring(5, cs.length()); - if (cs.charAt(0) == '_' && cs.length() >= 3 && - Character.isDigit(cs.charAt(1)) && - Character.isDigit(cs.charAt(2))) { - int nextChar = 3; - try { - String uu = cs.substring(1, 3); - jdkUpdate = Integer.valueOf(uu).intValue(); - } catch (NumberFormatException e) { - // not conforming to the naming convention - return; - } - } - } else { - throw new InternalError("Invalid java.runtime.version" + cs); - } - } - - /** - * Returns this java string as a null-terminated byte array - */ - private static byte[] stringToByteArray(String str) { - return (str + "\u0000").getBytes(); - } - - /** - * Converts a null-terminated byte array to java string - */ - private static String byteArrayToString(byte[] array) { - return new String(array, 0, array.length -1); - } - - /** - * Gets the stclient path using a well known location from - * the Windows platform Registry, ensuring the path returned - * by the registry is really the one we are looking for, - * otherwise it will return null. - */ - private static File getWindowsStClientFile(boolean wow64) { - File out = null; - String regKey = (wow64 == true) - ? "software\\Wow6432Node\\" + REGKEY_TAIL - : "software\\" + REGKEY_TAIL; - String keyName = "" ; // use the default key - String path = getRegistryKey(regKey, keyName); - if (path != null - && (new File(path)).exists() - && path.toLowerCase().endsWith(STCLIENT_TAIL.toLowerCase())) { - out = new File(path); - } - if (isVerbose()) { - System.out.println("stclient=" + out); - } - return out; - } - - /** - * Finds a stclient in 32 and 64 bit environments, first by querying - * the windows registry, if not then get the well known paths for - * 64bit see http://support.microsoft.com/kb/896459 - */ - - static File getWindowsStClientFile() { - File stclient = null; - if (System.getProperty("os.arch").equals("x86")) { - // try to get the default entry - stclient = getWindowsStClientFile(false); - if (stclient != null) { - return stclient; - } - } else { // we are on 64-bit system - // try the wow64 area - stclient = getWindowsStClientFile(true); - if (stclient != null) { - return stclient; - } - // try the default hard coded path, maybe wow64 registry is missing - stclient = new File(WIN32_STCLIENT); - if (stclient.canExecute()) { - if (isVerbose()) { - System.out.println("stclient(default)=" + stclient); - } - return stclient; - } - } - if (isVerbose()) { - System.out.println("stclient not found"); - } - return null; - } - - /** - * This uses reflection to access a private java windows registry - * interface, any changes to that Class must be appropriately adjusted. - * Returns a null if unsuccessful. - */ - private static String getRegistryKey(String regKey, String keyName) { - String out = null; - try { - Class clazz = Class.forName("java.util.prefs.WindowsPreferences"); - - // Get the registry methods - Method winRegOpenKeyM = clazz.getDeclaredMethod("WindowsRegOpenKey", - int.class, byte[].class, int.class); - winRegOpenKeyM.setAccessible(true); - - Method winRegCloseKeyM = clazz.getDeclaredMethod("WindowsRegCloseKey", - int.class); - winRegCloseKeyM.setAccessible(true); - - Method winRegQueryValueM = clazz.getDeclaredMethod("WindowsRegQueryValueEx", - int.class, byte[].class); - winRegQueryValueM.setAccessible(true); - - // Get all the constants we need - int HKLM = getValueFromStaticField("HKEY_LOCAL_MACHINE", clazz); - int KEY_READ = getValueFromStaticField("KEY_READ", clazz); - int ERROR_CODE = getValueFromStaticField("ERROR_CODE", clazz); - int NATIVE_HANDLE = getValueFromStaticField("NATIVE_HANDLE", clazz); - int ERROR_SUCCESS = getValueFromStaticField("ERROR_SUCCESS", clazz); - - // Convert keys - byte[] reg = stringToByteArray(regKey); - byte[] key = stringToByteArray(keyName); - - // Open the registry - int[] result = (int[]) winRegOpenKeyM.invoke(null, HKLM, reg, KEY_READ); - - if (result[ERROR_CODE] == ERROR_SUCCESS) { - byte[] stvalue = (byte[]) winRegQueryValueM.invoke(null, - result[NATIVE_HANDLE], key); - out = byteArrayToString(stvalue); - winRegCloseKeyM.invoke(null, result[NATIVE_HANDLE]); - } - } catch (Exception ex) { - if (isVerbose()) { - ex.printStackTrace(); - } - } - return out; - } - - private static int getValueFromStaticField(String fldName, Class klass) throws Exception { - Field f = klass.getDeclaredField(fldName); - f.setAccessible(true); - return f.getInt(null); - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/WindowsSystemEnvironment.java b/jdk/src/share/classes/com/sun/servicetag/WindowsSystemEnvironment.java deleted file mode 100644 index 3203926b5ed..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/WindowsSystemEnvironment.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2008, 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.servicetag; - -// This class is a copy of the com.sun.scn.servicetags.WindowsSystemEnvironment -// class from the Sun Connection source. -// -// The Service Tags team maintains the latest version of the implementation -// for system environment data collection. JDK will include a copy of -// the most recent released version for a JDK release. We rename -// the package to com.sun.servicetag so that the Sun Connection -// product always uses the latest version from the com.sun.scn.servicetags -// package. JDK and users of the com.sun.servicetag API -// (e.g. NetBeans and SunStudio) will use the version in JDK. -// -// So we keep this class in src/share/classes instead of src//classes. - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -/** - * Windows implementation of the SystemEnvironment class. - */ -class WindowsSystemEnvironment extends SystemEnvironment { - WindowsSystemEnvironment() { - super(); - - // run a call to make sure things are initialized - // ignore the first call result as the system may - // give inconsistent data on the first invocation ever - getWmicResult("computersystem", "get", "model"); - - setSystemModel(getWmicResult("computersystem", "get", "model")); - setSystemManufacturer(getWmicResult("computersystem", "get", "manufacturer")); - setSerialNumber(getWmicResult("bios", "get", "serialnumber")); - - String cpuMfr = getWmicResult("cpu", "get", "manufacturer"); - // this isn't as good an option, but if we couldn't get anything - // from wmic, try the processor_identifier - if (cpuMfr.length() == 0) { - String procId = System.getenv("processor_identifer"); - if (procId != null) { - String[] s = procId.split(","); - cpuMfr = s[s.length - 1].trim(); - } - } - setCpuManufacturer(cpuMfr); - - // try to remove the temp file that gets created from running wmic cmds - try { - // look in the current working directory - File f = new File("TempWmicBatchFile.bat"); - if (f.exists()) { - f.delete(); - } - } catch (Exception e) { - // ignore the exception - } - } - - - /** - * This method invokes wmic outside of the normal environment - * collection routines. - * - * An initial call to wmic can be costly in terms of time. - * - * - * Details of why the first call is costly can be found at: - * - * http://support.microsoft.com/kb/290216/en-us - * - * "When you run the Wmic.exe utility for the first time, the utility - * compiles its .mof files into the repository. To save time during - * Windows installation, this operation takes place as necessary." - * - */ - private String getWmicResult(String alias, String verb, String property) { - String res = ""; - BufferedReader in = null; - try { - ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property); - Process p = pb.start(); - // need this for executing windows commands (at least - // needed for executing wmic command) - BufferedWriter bw = null; - try { - bw = new BufferedWriter( - new OutputStreamWriter(p.getOutputStream())); - bw.write(13); - bw.flush(); - } finally { - if (bw != null) { - bw.close(); - } - } - - p.waitFor(); - if (p.exitValue() == 0) { - in = new BufferedReader(new InputStreamReader(p.getInputStream())); - String line = null; - while ((line = in.readLine()) != null) { - line = line.trim(); - if (line.length() == 0) { - continue; - } - res = line; - } - // return the *last* line read - return res; - } - - } catch (Exception e) { - // ignore the exception - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - // ignore - } - } - } - return res.trim(); - } -} diff --git a/jdk/src/share/classes/com/sun/servicetag/package.html b/jdk/src/share/classes/com/sun/servicetag/package.html deleted file mode 100644 index 8c7c90a1162..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/package.html +++ /dev/null @@ -1,71 +0,0 @@ -CTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> - - - - - - - -This package contains classes that allow the creation -and manipulation of service tags. -This com.sun.servicetag package is intended for -Sun internal use only. -

-

-
Service Tag
-
A service tag is an XML-based data structure that contains identifying -information about an instance of a product or component on a system. -
-
-
-
Service Tag Registry
-
A service tag registry is a XML-based registry that contains -the service tags of all the tagged components on a system. The -service tag registry is present on systems that have the -Service Tags software installed. -
-
-
-
Registration Data
-
A registration data is a container of one or more -service tags that identify the -components for product registration and will be used to interface -with the Sun Connection registration services. -
-
- -This package contains the methods to create service tags, set up the -registration data for product registration, add service tags to and -remove them from the system service tag registry. -

-All methods defined in this package will throw {@code NullPointerException} -if {@code null} is passed in any input parameter unless it is stated otherwise. -In addition, they are multi-thread safe. - - - - diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt b/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt deleted file mode 100644 index 70e8cffbd6f..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/Putback-Notes.txt +++ /dev/null @@ -1,25 +0,0 @@ -README for auto-generating of the offline registration page. - -1. register.html is defined by the xDesign team. - -2. Before putback in the workspace, we need to modify the - register.html to contain the following: - - (a) replace the pathname of the jdk_header.png image to - - - (b) replace the product name from: - Java Development Kit Version 6 Update 5 (e.g.) - to: - Java Development Kit @@JDK_VERSION@@ - - (c) replace the form action for the "Register My JDK" button with: - -

- - (d) Add this input in the form for posting data after - the line: - - - -3. The jdk_header.png is located under /lib/servicetag directory. diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties b/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties deleted file mode 100644 index 2d7ee83bcdb..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2008, 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. - -servicetag.jdk.urn = urn:uuid:d5bed446-05f2-42ed-ba0a-153105a52413 -servicetag.jdk.name = J2SE 5.0 Development Kit -servicetag.jre.urn = urn:uuid:5c6686aa-fd05-46a6-ba3e-700e2d5f7043 -servicetag.jre.name = J2SE 5.0 Runtime Environment -servicetag.parent.urn = urn:uuid:f3c20172-557a-11d7-93d0-d6a41ea318df -servicetag.parent.name = Java 2 Platform, Standard Edition 5.0 diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties b/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties deleted file mode 100644 index 13657156120..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2008, 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. - -servicetag.jdk.urn = urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 -servicetag.jdk.name = Java SE 6 Development Kit -servicetag.jre.urn = urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -servicetag.jre.name = Java SE 6 Runtime Environment -servicetag.parent.urn = urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -servicetag.parent.name = Java Platform Standard Edition 6 (Java SE 6) diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties b/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties deleted file mode 100644 index 97c5ef842d6..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2008, 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. - -servicetag.jdk.urn = JSEZ9-007-ZZZZ -servicetag.jdk.name = Java SE 7 Development Kit -servicetag.jre.urn = JSERE-007-ZZZZ -servicetag.jre.name = Java SE 7 Runtime Environment -servicetag.parent.urn = urn:uuid:dc1704fe-264f-11dc-9482-080020a9ed93 -servicetag.parent.name = Java Platform Standard Edition 7 (Java SE 7) diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/javase_servicetag.properties b/jdk/src/share/classes/com/sun/servicetag/resources/javase_servicetag.properties deleted file mode 100644 index 7ff81b27827..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/javase_servicetag.properties +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2011, 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. - -servicetag.jdk.urn = Q8549 -servicetag.jdk.name = Java Development Kit -servicetag.jre.urn = Q8549 -servicetag.jre.name = Java Runtime Environment -servicetag.parent.urn = Q8549 -servicetag.parent.name = Java Platform, Standard Edition diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png b/jdk/src/share/classes/com/sun/servicetag/resources/jdk_header.png deleted file mode 100644 index ccfe6dad8c8731c12aee5e4f255a6ae941791173..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8705 zcmV+cBL3ZpP)b=iPz)n*y;4^{QpdNl~H|~KWBmZ$I1Wx`}P0-Re_#HZiuJ5$vIthKxl%> z&C@zwc3y& zt2S9|L288dkCSACnwho7`LMHMe2$c=xlo0tNN|ep{{MrUtnp1#Fh}Iuftp8gieZeYT6~h><>*9ghVyD~T7;e9 z?DbuSqT}=YQG}(?+~wQx{%Db@YK);vca*5MzWDk2T!*JtfS6-}ms)q@$pJ)f@y`BzR}u4YlUiqlS+fA zOLL7jTXkK8p3UIxLS}(Qa*|SZk!6UUk*&dep}1OyqVe|rsldq#bR)n2BWq?L%g@32S`~Uy(@9p#a|4wm?QGl3TlC)ljo=$g^S9+If zg`hrghE;{8bA*mmfSo^Mef0SHIbC;Kf}diKu4j#>UWJ%!e~wUrrBQmA+u!0tZjb8m z`1t+*`~3ete4Jv2sPFgtT#v2y`~OLDkV15rU4D%{Xn#+8o=A3xS%#!FWq^#d(@}Ps zP;ii1h@d-SfB5|TRfC#NbC)`0e^G^?f{~t1Wqd|%fjwq>L}7GThMz%efH!D=NpqH8 zgQi)6r$T^?T7#H3Tz5NKY+Hn&Jz;t8I6pjFa5GnLI9F+0grY-wj!|@rReYaghn7`` zp;(ER;Ns$6bb@Y@qFRNeKxBMbgrr!5qg#fiT!^JziKhSm|MQ%OOaK5LhemRX(;dLLde@Y4&^;rIwISeRe@MkdA#K5YLM81kWi7=0A|qZs1qe@0BzH}3aT z>sgo~raCcmJrPFNGsnNz_*Q}VFcy$ytyq{hn8gSE`;vph!eQ!$_`d(9B6godhvq(<3Ts->ifl2{ry!}KRRYy&bWTR_yroRuIeX;NieQ&GM^@X;l;Y7 z8+9}Xq$dj((r!37)FHVa1>Nlb?ifu*`!vbn1}(_pChhx=Wc7dfZnWN~Ri4L>*U=Ux zIUun+-1z>xtKWS0&5KpyzlamQxq9sT?oVkB-#FCK7F<2{QB}YFM-KCqsScE>w5j^j zz1|Gwt51|O zs$V6mudA=GsxsBSskEv5x}czXS<*sUQcx1o6Iv3Y#qlbKs|y2v63ecBPkS+lwy<7I zbGWgf>e$u49CsKOpSZtYY>xYrOYRcWTcW_8bsuzos>gvTZ zhlL-}?2$VL%~L#Cy`Svu|CFHaPnfCk3ra#B2Qrx~X~>AAAP0MzgDjy+{GC`_A9Pim zcf>ivzzyp{fks2r?qch(KiR z+1J-g5*FkwSddUr^^HApuazOUY9oy6S1epe*%hB7Hgz52@iYg5PkZD=@RPi}s=~m8e>}X&{}Lp1 zr$~mA_*-`hZOCnVCwrQGqhmOvuBz&f+lci|)%)Nk>-MawK>Z}9r5fs`iW6{HZzO+P zC|N=as=zP>Ff1UHqpGSHm&FoiY-sL{pap&ytgoaWhs{Z_w=gG|%?D3U!-^UrQYO1b z7XW^NBX~}Nlf9FtlT4Dn2UY-BK%vM)Ri$<_WQ~*6SEqJYpy8Y#<8t;Bq8Y=uoYM$~ zbb@DhcVty^%9}+_o`?)vJw3ZG*XLkiO3~M-ObBx&si+E-SK-N^$+nTNY-MyC+DmN| zVla7)-S(MSvS%tI;Xy;g1qI?Z!7Cvs(m|4b2|xuop`sfw6q(wOiMeSU&u~Pub2I@{ z18Hi&CL6%X>OJekOcrmT35>2|4j=OLJ~&OJ`;($;sGYE%(-bKT-0E56S(L5|Ikmvu zBe4N0R|nmWEUcKUUIiny;`G_d%TCY8))5S8brB;qGQk;2r)+hyM*@=SjLfGl9g$4=*R27T_M{CF7VdL7v12 zRHy3{C`Og8l%PB5DfTelVsGrYb^zHmC^zOx~Js|k$brXaWILeIwZ zvskVtt>V;TIQ&&c^|5P*CR@K1ktOQW>nbmsYTs1a6zU-B>TY!<_SGV!Xp2*ktgHKW zW92H_?4&CMUG&3iMfQ=Ysf?Db|3TS^L0w~fVW<}=*@*SZt0xuV6ojG=8K?)4TVbIm zD*p`NyPk3EP`d3IVGwDTVsS-LOTxpoknh&{hN*#`Y(OWw(ahAuOtqYWk=1B69~cw4 zEoou6uL9(eky~YIR356LLegFRVa3CT*Zzy~N#HS*S{)df%1~E4%u{!DTU#@}U@#&X zg+=Lmfh&cnUv!Z|KO@&yU!$b{$A2Aq>#b}5{3|2jl>34%hSOiae)v%GVIakjFJV-x z(TYk&o>O&dLf%8;J4ooO#Q^s z7E-^p)(7*&WeM^GDrK%?ClsbeB0U}(v9Z)lAN`&&hYu+I_a$oskwcUie6aSEx}{*T zSY|obnh}A0J^i1Ik4XnN#;5TX;A#AuCUDndw(h_OSD3lEOa2xRmcqKBWFQ zpTLBnOkn~eB9!SUBa!}k63z6EVO;Se2w)&nSS5+9mLNVv7Fl(-5Q)Ta z6h!;EK``0_W#4nVbP3ZvZ5I~1M2_-G#6r8A8(SIeTPa?IaDYj^|8-9fgAx+@ekB?U z5S-QZ{CH@UEet_RxCxCP7qyfO`CubIqsXZ!Bwg-dqXDnjZSWbL?gSj~Xy`Si^3txt zYm^de+_^+bNlD=Y04G5VZ+XN#S4k?7IBtgA^D&B?FK+97;DxMnR<|Ih8AXv}jHPD! zNRPDUmSQ?LLKMpy+f0U*U$9a)%= zj{#u)jyI0+;fFO3bZ-L}UT^T(D5rqo@$fnT3oSYN$rm3>x=KitO2uY(0zg)GweVVc zP{{T@_HXbyTibOCriY=w6!K1A(xJk8B%Dv;!IFV^j3gRX8?cW2u=w`c)Vf7HO6+UckS$oDs%8EZa1mW#fI=^vaf@ zA}0K1uRP5M8w0~}^iaA;h!4(PHWYd;%Kf2Vbi1nM5Y}djBVc-Wbt+6GD4~{K7RHYy+8CBY9=rsj>uKaTns zjdhngOh+cgv^q9yU#mzF#qxT(S|drVXWP{1eXuD& z;Vz())g+ma01({SJZ~tB9n;bJ<^ed(#-EKo;O3r}=a+(w#&T+rvd)@Q#%f zI6@oQJv}`mo%UbP^zmqFI@n{Ac@FX69_ay`$+q#giB%KM5t{Tq?0L5#QxXsx)3x5( zpMpELi!CYeZ!e(uk1>{->7%D%STLsYO`V@={mIHrwcb?YG0~2Z4=XmU*fN^f@(S|G zgg7yhe0liA=kBJvNao8!8F#mgcVP5*!igvM4?{i}g|&efTOdSyC@8cku(KoC@ZHf^ zZwire`t|bOCUB@)mA4keBCDfmJx}jLK+L_^CTGRoe5>_1I1_b6 zo|n&j+a|yrqrkCi+!Gb$>&r6F8S;62{p|eLL%0Vi?hoKf9>0{Hb_t`_XoTn! zXwMDtg_R_F!9^J3WqU= zz{jiU^MHGHh!5*y%GT?BD6sPnV584vHudn*w!=9g4Qr(}h!5>nt%whFUPoD3EN^t! z?8Z_veKalFO<=0rWcjAb%@I%duxR4jlm5Tqg}q{E`M)vrXh62qcZ~{9^kI}0Iukw= z7f*;o!|Tu>K6qudQ`|xU-DcYZTVTghQEvXFa}odF3m^={#KfjC8xGhWIItZ#5mQ#y zUfVwELqO9$_}x>x52AHGI^7=I&6_t%gG=QQAa`|y&{t}&V^;1R$;Vr*&c(nUb|3J= zA;+##?!BX5DFpHlUUP)ex!D^uA4DsboIH3xWtC&|dOLomBHA5KWqS$YIR*R_*w*%d zE#!0H+@qT1`yT+_yR%mNd)uPvG1(II*>^s__4Cg)HLFK_*eoRrV6WK2O}!dAT9MYl z)1<8mr$csv?W$1iaT*y}ZwJOo~n{^fEW1}e`D&fsDMzPz=tTfpk- zhzkvg>8qFX!xY}C!*<1GvAqEt@3Yv5+UlPJau>t9RHO*>fo-|9Ki3>-sy$Lu#>Fsw zU84nVo&I$6-fj5ytPiq&DelY4D#cv#puPqof8Wp8upeIugd_*oc)%|SV@3F~#SL!F zckZLl?JKqm&h^DcXVo6IdKF-DU(;>`aPAq)KfhJ18OZ+e#|MC8dz)2<_eu=6wq2TX z){)E2#mACVrNK2{)}|?Zs1YeJI+>DnKISAE^3ML@RymNu-_JW`=r8_4!@g`hzO9VB zZiz+}5d6|kGQaGX4*pjFkmFuj@HYUGp9(=*Sl!I#vC4d*B_I#a3GV0}8?mv}Odn0) z@Ce1T%v@b(lIuRXe;7;XKdcVDFD<&Oe*;=H;(_7T|Axu^!-QSPlRj{PAs;57;p=?> zypHh7cb@S(c%(!g!t}t`W=L_s5@8tDnGNoCV}{6M{QZxHz-gNG#fN*#IEW9cun`&5 z!xZ`3Og9%*ZsI!fQT7i%oG;~G-%!R~t4PT`&3tvYiXL`??B`DB({s6aja4p2k+z|U z9@c=nZ$~}PEe9~d-mEkzO!!z-%6eOoMy$<6@7>oI+iFUw-YqGU7KGLWQwAw1-xh=Mb74f`)sjs?&T1c+{}}5 zG^J$N7c9k#I(mD@Mru{==syE&IN!b3x=ho3%`mz92=R**;)SO#rFDo@E`uCm0C8UfkWY!_IWK_;5r?&G9K7*Wwrg;( zsQH$50L+J&UJ8QLPMfRGN8UI3T={f-C{x7ZmBDn1_;*5-}g;fxzmj$8g$VTiLT(j zy>EYY${9z1Fpl_Jw?Ho@HZkYX{reG8BCD7q#K5NkM^L3I&BtPwI6e|dL6EN8A%F##tSqYtq#f+59J((A155}CEvG97RUX@IF<3|dWIEUG zsNtvh?2|S(pCm(Mkj_8+DgfcLIrK~>00^*9{H|BqSMLbHy5)j+(LNX>wW9JfFDL{+ zit~DE7E2q|$1T6m@ZNQ$FcSiBYwY5X_dDX}9nNT-0t)pt^p~Flh4}SRIem%S6Ip|- z<_8Thpoi>S8r7-dyR8Hwe!jRqQwLnXLW*d0uuguU+w4vv&j${NqfGbNc>!RitbM-}3}#&iMc~>n02ZX+@hpRQ7-gnCog5aVzmFp!cn>VpzeY&7o3R zd`E2PBkgLf91U%JhlB# z64%5Dg>h18g!FOeE#mbImgWxl=>AFY$d_4t5z*s@u1k-`(c`3|PO3|=vRrW54^J0LLB3MUab2TaLmbrBDxKXsT{Z9Z`NeI> zev`!lk&1LWpWlqc9Oujr;J6HSN|iiTC-Kf2VO*S)Edo11P3;i_|RSHHdiYI+41A`onqrc~*)TJR|U;t`kg=dUva;JTrb<8Fgd48>sAy8ZcE3d8&cC;=LoZ7Ul%A z_y9cV0}*sxv+W%Y$6Vup3*Y4&p(Ng#tLt_4(Q|g~>$6JR=8OmXSX5KxkZtrD-zCm? z%S!!y`2cc6BBe+~G}k!fK62)*N4BhUb-gwYpXy%3Id~lEzWvUzqiUOQpEtOhU z>hH{lJ`m*efqmv02V!srvV&$lo~!GrI7&QU#2Nq*9YAFJWU?R&hn*^r1F|~Xk-zm{QcZ62G*lLg*kQhL`IqGxe~y?h zK5$st!9MMv*@kaGt3s~s!kV+s=_;*@T|4re&}v-}8BO{SrQNM5?q&5_7WnVW2Ng@p z8l1b=_b2!PxdnF&1{3GZhk+<+CpF4NOQj-r0%C?KAE?wQ7J`dqf&adI7<4Jt7PHJZ zd_SD$gRaEu*XL^ZU836Bva*qPv^Ld67dx$KAKKcetSHO!{>}Rk6*cfQqDB~)CQ&9B z_?1l7-m_kJy74_(ek?W9M>EQNpBSTjbNC>I5FZ9CSeSp9#Rp)>hsRID5ZB{rVyb_S zej(Tp96mhO`|#L;h53iseE7wJh53g$eE8)o;)6!> z>jKw29?)n8ekq%Fy%C)z< zrBYdG28{cuv0&lZF^3Nt+Zph|e?b3#@lsV5A1wS9d{}P5!u-P=K5XzodsXh6ZU%T(ugy7gzOym7smZfCZ~ zb-Lp{TjOP_y=krwpSkzJr(M6Fwlc6`cCnfw)2%;K<&EpjbUU*>uG1aw*%~iX?M-ui zoLD*MoN(3qfVW`50v<1=)6XG302VC#j=@3@Qvf&Y+^+N4u75t*TCngtrlA4Zs%+n^ f-%smw|0BQv5oyF1P3^3r00000NkvXXu0mjf6iFrP diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd b/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd deleted file mode 100644 index 43d27455b46..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/product_registration.xsd +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register.html b/jdk/src/share/classes/com/sun/servicetag/resources/register.html deleted file mode 100644 index d1bf2351f6f..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/register.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - -Register your JDK - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  -
 

Thank you for installing the - Java Development Kit @@JDK_VERSION@@ - from Oracle Corporation.

-

Registering your product will give you the following benefits:

-
    -
  • Notification of new versions, patches, and updates
  • -
  • Special offers on Oracle developer products, services and training
  • -
  • Access to early releases and documentation
  • -
-

Product registration is FREE, quick and easy!

-
-

All you need is an Oracle.com account. If you don't already have one, you will be prompted to create one.

- - - - - -
- - - - You need to be connected to the Internet to register this Oracle product.
-
-
  -

Oracle Corporation respects your privacy. - We will use your personal information for communications - and management of your Oracle.com account, the services - and applications you access using your Oracle.com account, - and the products and systems you register with your Oracle.com account.

-

For more information on the data that will be collected as - part of the registration process and how it will be managed
- see http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html.
-
- For more information on Oracle's Privacy Policy see http://www.oracle.com/html/privacy.html or contact privacy_ww@oracle.com.

  
  
- - diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html deleted file mode 100644 index c49c313da97..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/register_ja.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - -JDK 製品登録 - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 

Oracle Corporation の Java Development Kit @@JDK_VERSION@@ をインストールしていただき、ありがとうございます。

-

製品登録をすると、次のような特典を受けることができます。

-
    -
  • 最新のバージョン、パッチ、および更新についての通知
  • -
  • Oracle の開発者向け製品、サービス、およびトレーニングの特別販売
  • -
  • アーリーリリースおよびドキュメントへのアクセス
  • -
-

製品登録は無料であり、迅速で簡単です。

-
-

必要になるのは、Oracle.com アカウントだけです。 まだアカウントがない場合は、アカウントの作成が求められます。

- - - - - -
- - -
この Oracle 製品を登録するには、インターネットに接続している必要があります。
-
-
  -

Oracle Corporation は、お客様のプライバシーを尊重します。 お客様の個人情報は、お客様の Oracle.com アカウント、お客様が Oracle.com アカウントを使用してアクセスするサービスとアプリケーション、およびお客様が Oracle.com アカウントで登録する製品とシステムの通信と管理に使用します。

-

登録の際に収集されるデータや、それらがどのように管理されるかについての詳細は、
http://java.sun.com/javase/ja/registration/JDKRegistrationPrivacy.html を参照してください。

Oracle のプライバシーポリシーについての詳細は、http://www.oracle.com/html/privacy.html を参照するか、お問い合わせフォームからお問い合わせください。

  
  
- - diff --git a/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html b/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html deleted file mode 100644 index bff0f69b3a5..00000000000 --- a/jdk/src/share/classes/com/sun/servicetag/resources/register_zh_CN.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - -注册您的 JDK - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 

感谢您安装 Oracle Corporation 的 Java Development Kit @@JDK_VERSION@@

-

注册产品后您将获得如下增值服务:

-
    -
  • 获得新版本、修补程序和更新的通知服务
  • -
  • 获得有关 Oracle 开发者产品、服务和培训的优惠
  • -
  • 获得对早期版本和文档的访问权限
  • -
-

产品注册是免费的,即快速又轻松!

-
-

您需要具有 Oracle.com 帐户。如果您没有,系统将提示您创建一个。

- - - - - -
- - -
您需要连接到 Internet 来注册此 Oracle 产品。
-
-
  -

Oracle 尊重您的隐私。我们会将您的个人信息用于通信和 Oracle.com 帐户的管理、Oracle.com 帐户访问的服务和应用程序以及用于使用 Oracle.com 帐户注册的产品和系统。

-

有关注册过程中收集的数据以及这些数据的管理方式的更多信息,
请访问 http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html

有关 Oracle 隐私政策的更多信息,请访问 http://www.oracle.com/html/privacy.html 或与 privacy_ww@oracle.com 联系。

  
  
- - diff --git a/jdk/test/com/sun/servicetag/DeleteServiceTag.java b/jdk/test/com/sun/servicetag/DeleteServiceTag.java deleted file mode 100644 index 5fcaa782659..00000000000 --- a/jdk/test/com/sun/servicetag/DeleteServiceTag.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for deleting a service tag in a product registration - * @author Mandy Chung - * - * @run build DeleteServiceTag Util - * @run main DeleteServiceTag - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class DeleteServiceTag { - private static RegistrationData registration; - private static File regFile; - private static Map stMap = - new LinkedHashMap(); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - - public static void main(String[] argv) throws Exception { - String registrationDir = System.getProperty("test.classes"); - String servicetagDir = System.getProperty("test.src"); - - File original = new File(servicetagDir, "registration.xml"); - regFile = new File(registrationDir, "registration.xml"); - copyRegistrationXML(original, regFile); - - // loads all the service tags - for (String f : files) { - File stfile = new File(servicetagDir, f); - ServiceTag svcTag = Util.newServiceTag(stfile); - stMap.put(svcTag.getInstanceURN(), svcTag); - } - - // load the registration data with all service tags - BufferedInputStream in = new BufferedInputStream(new FileInputStream(regFile)); - registration = RegistrationData.loadFromXML(in); - - if (stMap.size() != files.length) { - throw new RuntimeException("Invalid service tag count= " + - stMap.size() + " expected=" + files.length); - } - // check the service tags - Util.checkRegistrationData(regFile.getCanonicalPath(), stMap); - - // delete a service tag - deleteServiceTag(servicetagDir, files[0]); - - System.out.println("Test passed: service tags deleted."); - } - - private static void copyRegistrationXML(File from, File to) throws IOException { - - to.delete(); - BufferedReader reader = new BufferedReader(new FileReader(from)); - PrintWriter writer = new PrintWriter(to); - try { - String line = null; - while ((line = reader.readLine()) != null) { - writer.println(line); - } - writer.flush(); - } finally { - writer.close(); - } - } - - private static void deleteServiceTag(String parent, String filename) throws Exception { - File f = new File(parent, filename); - ServiceTag svcTag = Util.newServiceTag(f); - - ServiceTag st = registration.removeServiceTag(svcTag.getInstanceURN()); - if (st == null) { - throw new RuntimeException("RegistrationData.remove method" + - " returns null"); - } - if (!Util.matches(st, svcTag)) { - throw new RuntimeException("ServiceTag added in the registration " + - " doesn't match."); - } - // check the service tags before storing the updated data - Util.checkRegistrationData(regFile.getCanonicalPath(), stMap); - - ServiceTag st1 = registration.getServiceTag(svcTag.getInstanceURN()); - if (st1 != null) { - throw new RuntimeException("RegistrationData.get method returns " + - "non-null."); - } - // Now remove the service tag from the map and store to the XML file - stMap.remove(svcTag.getInstanceURN()); - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(regFile)); - try { - registration.storeToXML(out); - } finally { - out.close(); - } - } -} diff --git a/jdk/test/com/sun/servicetag/DuplicateNotFound.java b/jdk/test/com/sun/servicetag/DuplicateNotFound.java deleted file mode 100644 index fa1d11b0c4e..00000000000 --- a/jdk/test/com/sun/servicetag/DuplicateNotFound.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for RegistrationData.removeServiceTag and - * updateServiceTag. - * @author Mandy Chung - * - * @run build DuplicateNotFound Util - * @run main DuplicateNotFound - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class DuplicateNotFound { - private static String servicetagDir = System.getProperty("test.src"); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - - private static RegistrationData registration = new RegistrationData(); - - public static void main(String[] argv) throws Exception { - ServiceTag svcTag; - registration.addServiceTag(loadServiceTag(files[0])); - registration.addServiceTag(loadServiceTag(files[1])); - testDuplicate(files[0]); - testDuplicate(files[1]); - testNotFound(files[2]); - } - - private static void testDuplicate(String filename) throws Exception { - boolean dup = false; - try { - registration.addServiceTag(loadServiceTag(filename)); - } catch (IllegalArgumentException e) { - dup = true; - } - if (!dup) { - throw new RuntimeException(filename + - " added successfully but expected to be a duplicated."); - } - } - private static void testNotFound(String filename) throws Exception { - ServiceTag st = loadServiceTag(filename); - ServiceTag svctag = registration.getServiceTag(st.getInstanceURN()); - if (svctag != null) { - throw new RuntimeException(st.getInstanceURN() + - " exists but expected not found"); - } - - svctag = registration.removeServiceTag(st.getInstanceURN()); - if (svctag != null) { - throw new RuntimeException(st.getInstanceURN() + - " exists but expected not found"); - } - - svctag = registration.updateServiceTag(st.getInstanceURN(), "testing"); - if (svctag != null) { - throw new RuntimeException(st.getInstanceURN() + - " updated successfully but expected not found."); - } - } - - private static ServiceTag loadServiceTag(String filename) throws Exception { - File f = new File(servicetagDir, filename); - return Util.newServiceTag(f); - } -} diff --git a/jdk/test/com/sun/servicetag/FindServiceTags.java b/jdk/test/com/sun/servicetag/FindServiceTags.java deleted file mode 100644 index 349cc7648bd..00000000000 --- a/jdk/test/com/sun/servicetag/FindServiceTags.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2008, 2010, 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 6622366 - * @summary Basic Test for Registry.findServiceTags() - * @author Mandy Chung - * - * @run build FindServiceTags SvcTagClient Util - * @run main FindServiceTags - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -// This test creates a few service tags in the Registry. -// Check if the findServiceTags method returns the expected ones. -public class FindServiceTags { - private static String registryDir = System.getProperty("test.classes"); - private static String servicetagDir = System.getProperty("test.src"); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties", - "servicetag4.properties", - "servicetag5.properties" - }; - - private static Registry registry; - private static Set set = new HashSet(); - private static Set productUrns = new HashSet(); - private static int expectedUrnCount = 3; - - public static void main(String[] argv) throws Exception { - try { - registry = Util.getSvcTagClientRegistry(); - runTest(); - } finally { - // restore empty registry file - Util.emptyRegistryFile(); - } - System.out.println("Test passed."); - } - - public static void runTest() throws Exception { - for (String filename : files) { - File f = new File(servicetagDir, filename); - ServiceTag svcTag = Util.newServiceTag(f); - ServiceTag st = registry.addServiceTag(svcTag); - - set.add(st); - productUrns.add(st.getProductURN()); - } - if (productUrns.size() != expectedUrnCount) { - throw new RuntimeException("Unexpected number of product URNs = " + - productUrns.size() + " expected " + expectedUrnCount); - } - if (set.size() != files.length) { - throw new RuntimeException("Unexpected number of service tags = " + - set.size() + " expected " + files.length); - } - String purn = null; - for (String urn : productUrns) { - if (purn == null) { - // save the first product_urn for later use - purn = urn; - } - findServiceTags(urn); - } - - // remove all service tags of purn - Set tags = registry.findServiceTags(purn); - for (ServiceTag st : tags) { - System.out.println("Removing service tag " + st.getInstanceURN()); - registry.removeServiceTag(st.getInstanceURN()); - } - tags = registry.findServiceTags(purn); - if (tags.size() != 0) { - throw new RuntimeException("Unexpected service tag count = " + - tags.size()); - } - - } - - private static void findServiceTags(String productUrn) throws Exception { - Set found = registry.findServiceTags(productUrn); - Set matched = new HashSet(); - System.out.println("Finding service tags of product_urn=" + - productUrn); - for (ServiceTag st : set) { - if (st.getProductURN().equals(productUrn)) { - System.out.println(st.getInstanceURN()); - matched.add(st); - } - } - if (found.size() != matched.size()) { - throw new RuntimeException("Unmatched service tag count = " + - found.size() + " expected " + matched.size()); - } - - for (ServiceTag st0 : found) { - ServiceTag st = null; - for (ServiceTag st1 : matched) { - if (Util.matches(st0, st1)) { - st = st1; - break; - } - } - if (st == null) { - System.out.println("product_urn=" + st0.getProductURN()); - System.out.println("instance_urn=" + st0.getInstanceURN() ); - throw new RuntimeException(st0.getInstanceURN() + - " not expected in the returned list"); - } - } - } -} diff --git a/jdk/test/com/sun/servicetag/InstanceUrnCheck.java b/jdk/test/com/sun/servicetag/InstanceUrnCheck.java deleted file mode 100644 index b01d46b637a..00000000000 --- a/jdk/test/com/sun/servicetag/InstanceUrnCheck.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for checking instance_urn - * @author Mandy Chung - * - * @run build InstanceUrnCheck Util - * @run main InstanceUrnCheck - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class InstanceUrnCheck { - private static String servicetagDir = System.getProperty("test.src"); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - private static RegistrationData registration = new RegistrationData(); - - public static void main(String[] argv) throws Exception { - for (String f : files) { - addServiceTag(f); - } - } - - private static void addServiceTag(String filename) throws Exception { - File f = new File(servicetagDir, filename); - ServiceTag svcTag = Util.newServiceTag(f, true /* no instance_urn */); - ServiceTag st = registration.addServiceTag(svcTag); - if (!Util.matchesNoInstanceUrn(svcTag, st)) { - throw new RuntimeException("ServiceTag " + - " doesn't match."); - } - System.out.println("New service tag instance_urn=" + st.getInstanceURN()); - if (!st.getInstanceURN().startsWith("urn:st:")) { - throw new RuntimeException("Invalid generated instance_urn " + - st.getInstanceURN()); - } - if (st.getInstallerUID() != -1) { - throw new RuntimeException("Invalid installer_uid " + - st.getInstallerUID()); - } - if (st.getTimestamp() == null) { - throw new RuntimeException("null timestamp "); - } - } -} diff --git a/jdk/test/com/sun/servicetag/InvalidRegistrationData.java b/jdk/test/com/sun/servicetag/InvalidRegistrationData.java deleted file mode 100644 index 31b5bbfdcd7..00000000000 --- a/jdk/test/com/sun/servicetag/InvalidRegistrationData.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for invalid product registry - * @author Mandy Chung - * - * @run build InvalidRegistrationData - * @run main InvalidRegistrationData - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class InvalidRegistrationData { - public static void main(String[] argv) throws Exception { - String servicetagDir = System.getProperty("test.src"); - - checkRegistrationData(servicetagDir, "missing-environ-field.xml"); - checkRegistrationData(servicetagDir, "newer-registry-version.xml"); - } - - private static void checkRegistrationData(String parent, String filename) - throws Exception { - boolean thrown = false; - File f = new File(parent, filename); - BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); - try { - RegistrationData regData = RegistrationData.loadFromXML(in); - } catch (IllegalArgumentException e) { - System.out.println(e.getMessage() + " thrown expected"); - thrown = true; - } - - if (!thrown) { - throw new RuntimeException("ERROR: No IllegalArgumentException thrown"); - } - } - -} diff --git a/jdk/test/com/sun/servicetag/InvalidServiceTag.java b/jdk/test/com/sun/servicetag/InvalidServiceTag.java deleted file mode 100644 index 0b90fc2e13e..00000000000 --- a/jdk/test/com/sun/servicetag/InvalidServiceTag.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for ServiceTag.newServiceTag() to test invalid fields. - * @author Mandy Chung - * - * @run build InvalidServiceTag - * @run main InvalidServiceTag - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class InvalidServiceTag { - private final static int MAX_CONTAINER_LEN = 64 - 1; - public static void main(String[] argv) throws Exception { - // all fields valid - ServiceTag st1 = ServiceTag.newInstance("product name", - "product version", - "product urn", - "product parent", - "product parent urn", - "product defined instance ID", - "product vendor", - "platform arch", - "container", - "source"); - // empty optional field - ServiceTag st2 = ServiceTag.newInstance("product name", - "product version", - "product urn", - "product parent", - "", - "", - "product vendor", - "platform arch", - "container", - "source"); - // Invalid - empty required field - setInvalidContainer(""); - // Invalid - required field exceeds max length. - StringBuilder sb = new StringBuilder(); - for (int i = 0; i <= MAX_CONTAINER_LEN; i++) { - sb.append('x'); - } - setInvalidContainer(sb.toString()); - System.out.println("Test passed."); - } - private static void setInvalidContainer(String container) { - boolean exceptionThrown = false; - try { - ServiceTag st2 = ServiceTag.newInstance("product name", - "product version", - "product urn", - "product parent", - "product parent urn", - "product defined instance ID", - "product vendor", - "platform arch", - container, - "source"); - } catch (IllegalArgumentException iae) { - iae.printStackTrace(); - exceptionThrown = true; - } - if (!exceptionThrown) { - throw new RuntimeException("IllegalArgumentException not thrown"); - } - } -} diff --git a/jdk/test/com/sun/servicetag/JavaServiceTagTest.java b/jdk/test/com/sun/servicetag/JavaServiceTagTest.java deleted file mode 100644 index a411fa973ee..00000000000 --- a/jdk/test/com/sun/servicetag/JavaServiceTagTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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 6622366 7078024 - * @summary Basic Test for ServiceTag.getJavaServiceTag() - * Disable creating the service tag in the system registry. - * Verify the existence of registration.xml file and the - * content of the service tag. - * @author Mandy Chung - * - * @run build JavaServiceTagTest - * @run main JavaServiceTagTest - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class JavaServiceTagTest { - public static void main(String[] argv) throws Exception { - String registrationDir = System.getProperty("test.classes"); - - // disable calling to stclient - System.setProperty("servicetag.sthelper.supported", "false"); - - if (Registry.isSupported()) { - throw new RuntimeException("Registry.isSupported() should " + - "return false"); - } - // For debugging - // System.setProperty("servicetag.verbose", ""); - - // cleanup the registration.xml and servicetag file in the test directory - System.setProperty("servicetag.dir.path", registrationDir); - File regFile = new File(registrationDir, "registration.xml"); - regFile.delete(); - File svcTagFile = new File(registrationDir, "servicetag"); - svcTagFile.delete(); - - ServiceTag svctag = ServiceTag.getJavaServiceTag("JavaServiceTagTest"); - checkServiceTag(svctag); - - if (svcTagFile.exists()) { - throw new RuntimeException(svcTagFile + " should not exist."); - } - - // registration.xml should be created - if (!regFile.exists()) { - throw new RuntimeException(regFile + " not created."); - } - BufferedInputStream in = new BufferedInputStream(new FileInputStream(regFile)); - RegistrationData registration = RegistrationData.loadFromXML(in); - Set c = registration.getServiceTags(); - if (c.size() != 1) { - throw new RuntimeException(regFile + " has " + c.size() + - " service tags. Expected 1."); - } - ServiceTag st = registration.getServiceTag(svctag.getInstanceURN()); - if (!Util.matches(st, svctag)) { - throw new RuntimeException("ServiceTag " + - " doesn't match."); - } - } - - /** - * Tests if the running platform is a JDK. - */ - static boolean isJDK() { - // Determine the JRE path by checking the existence of - // /jre/lib and /lib. - String javaHome = System.getProperty("java.home"); - String jrepath = javaHome + File.separator + "jre"; - File f = new File(jrepath, "lib"); - if (!f.exists()) { - // java.home usually points to the JRE path - jrepath = javaHome; - } - - return jrepath.endsWith(File.separator + "jre"); - } - - private static void checkServiceTag(ServiceTag st) throws IOException { - Properties props = loadServiceTagProps(); - // jdk 8 and later, JDK and JRE have the same product URN. - String jdkUrn = props.getProperty("servicetag.jdk.urn"); - String jreUrn = props.getProperty("servicetag.jre.urn"); - boolean isJdk = isJDK(); - - if (isJdk) { - if (!st.getProductURN().equals(jdkUrn) || - !st.getProductName().equals( - props.getProperty("servicetag.jdk.name"))) { - throw new RuntimeException("Product URN and name don't match."); - } - } else { - if (!st.getProductURN().equals(jreUrn) || - !st.getProductName().equals( - props.getProperty("servicetag.jre.name"))) { - throw new RuntimeException("Product URN and name don't match."); - } - } - if (!st.getProductVersion(). - equals(System.getProperty("java.version"))) { - throw new RuntimeException("Unexpected product_version: " + - st.getProductVersion()); - } - if (!st.getProductParent(). - equals(props.getProperty("servicetag.parent.name"))) { - throw new RuntimeException("Unexpected product_parent: " + - st.getProductParent()); - } - if (!st.getProductParentURN(). - equals(props.getProperty("servicetag.parent.urn"))) { - throw new RuntimeException("Unexpected product_parent_urn: " + - st.getProductParentURN()); - } - if (!st.getPlatformArch(). - equals(System.getProperty("os.arch"))) { - throw new RuntimeException("Unexpected platform_arch: " + - st.getPlatformArch()); - } - String vendor = System.getProperty("java.vendor"); - if (!st.getProductVendor(). - equals(vendor)) { - throw new RuntimeException("Unexpected product_vendor: " + - st.getProductVendor()); - } - if (!st.getSource(). - equals("JavaServiceTagTest")) { - throw new RuntimeException("Unexpected source: " + - st.getSource()); - } - String[] ss = st.getProductDefinedInstanceID().split(","); - boolean id = false; - boolean dir = false; - for (String s : ss) { - String[] values = s.split("="); - if (values[0].equals("id")) { - id = true; - String[] sss = values[1].split(" "); - if (!sss[0].equals(System.getProperty("java.runtime.version"))) { - throw new RuntimeException("Unexpected version in id: " + - sss[0]); - } - if (sss.length < 2) { - throw new RuntimeException("Unexpected id=" + values[1]); - } - } else if (values[0].equals("dir")) { - dir = true; - } - } - if (!id || !dir) { - throw new RuntimeException("Unexpected product_defined_instance_id: " + - st.getProductDefinedInstanceID()); - } - } - - private static Properties loadServiceTagProps() - throws IOException { - String filename = "/com/sun/servicetag/resources/javase_servicetag.properties"; - try (InputStream in = Installer.class.getClass().getResourceAsStream(filename)) { - Properties props = new Properties(); - props.load(in); - return props; - } - } -} diff --git a/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java b/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java deleted file mode 100644 index d220bf0bc41..00000000000 --- a/jdk/test/com/sun/servicetag/JavaServiceTagTest1.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2008, 2011, 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 6622366 7078024 - * @summary Basic Test for ServiceTag.getJavaServiceTag(String) - * to verify that the registration.xml and servicetag files - * are both created correctly. - * @author Mandy Chung - * - * @run build JavaServiceTagTest1 SvcTagClient Util - * @run main JavaServiceTagTest1 - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class JavaServiceTagTest1 { - private static String registrationDir = System.getProperty("test.classes"); - private static String servicetagDir = System.getProperty("test.src"); - private static File regFile; - private static File svcTagFile; - private static Registry registry; - public static void main(String[] argv) throws Exception { - try { - registry = Util.getSvcTagClientRegistry(); - runTest(); - } finally { - // restore empty registry file - Util.emptyRegistryFile(); - } - } - - private static void runTest() throws Exception { - // cleanup the registration.xml and servicetag file in the test directory - System.setProperty("servicetag.dir.path", registrationDir); - regFile = new File(registrationDir, "registration.xml"); - regFile.delete(); - - svcTagFile = new File(registrationDir, "servicetag"); - svcTagFile.delete(); - - // verify that only one service tag is created - ServiceTag st1 = testJavaServiceTag("Test1"); - - // getJavaServiceTag method should create a new service tag - // and delete the old one - ServiceTag st2 = testJavaServiceTag("Test2"); - if (registry.getServiceTag(st1.getInstanceURN()) != null) { - throw new RuntimeException("instance_urn: " + st1.getInstanceURN() + - " exists but expected to be removed"); - } - - // expected to have different instance_urn - if (st1.getInstanceURN().equals(st2.getInstanceURN())) { - throw new RuntimeException("instance_urn: " + st1.getInstanceURN() + - " == " + st2.getInstanceURN()); - } - - // Delete the service tag from the Registry and the servicetag file - if (registry.removeServiceTag(st2.getInstanceURN()) == null) { - throw new RuntimeException("Failed to remove " + - st1.getInstanceURN() + " from the registry"); - } - svcTagFile.delete(); - - // call the getJavaServiceTag(String) method again - // should create the servicetag file. - ServiceTag st3 = testJavaServiceTag("Test2"); - if (!Util.matches(st2, st3)) { - System.out.println(st2); - System.out.println(st3); - throw new RuntimeException("Test Failed: Expected to be the same"); - } - - } - - private static ServiceTag testJavaServiceTag(String source) throws Exception { - ServiceTag svctag = ServiceTag.getJavaServiceTag(source); - checkServiceTag(svctag, source); - - // verify if registration.xml is created - if (!regFile.exists()) { - throw new RuntimeException(regFile + " not created."); - } - - // verify the registration.xml content is the expected service tag - BufferedInputStream in = new BufferedInputStream(new FileInputStream(regFile)); - RegistrationData registration = RegistrationData.loadFromXML(in); - Set c = registration.getServiceTags(); - if (c.size() != 1) { - throw new RuntimeException(regFile + " has " + c.size() + - " service tags. Expected 1."); - } - ServiceTag st = registration.getServiceTag(svctag.getInstanceURN()); - if (!Util.matches(st, svctag)) { - throw new RuntimeException("RegistrationData ServiceTag " + - " doesn't match."); - } - - // verify the service tag added in the registry - st = registry.getServiceTag(svctag.getInstanceURN()); - if (!Util.matches(st, svctag)) { - throw new RuntimeException("Registry ServiceTag " + - " doesn't match."); - } - - // verify if servicetag file is created - if (!svcTagFile.exists()) { - throw new RuntimeException(svcTagFile + " not created."); - } - - // verify that the servicetag file only contains one instance_urn - BufferedReader reader = new BufferedReader(new FileReader(svcTagFile)); - int count = 0; - try { - String line; - while ((line = reader.readLine()) != null) { - if (line.equals(svctag.getInstanceURN())) { - count++; - } else { - throw new RuntimeException("servicetag contains " + - " unexpected instance_urn " + line); - } - } - } finally { - reader.close(); - } - if (count != 1) { - throw new RuntimeException("servicetag contains unexpected " + - "number of instance_urn = " + count); - } - return svctag; - } - - /** - * Tests if the running platform is a JDK. - */ - static boolean isJDK() { - // Determine the JRE path by checking the existence of - // /jre/lib and /lib. - String javaHome = System.getProperty("java.home"); - String jrepath = javaHome + File.separator + "jre"; - File f = new File(jrepath, "lib"); - if (!f.exists()) { - // java.home usually points to the JRE path - jrepath = javaHome; - } - - return jrepath.endsWith(File.separator + "jre"); - } - - private static void checkServiceTag(ServiceTag st, String source) - throws IOException { - Properties props = loadServiceTagProps(); - // jdk 8 and later, JDK and JRE have the same product URN. - String jdkUrn = props.getProperty("servicetag.jdk.urn"); - String jreUrn = props.getProperty("servicetag.jre.urn"); - boolean isJdk = isJDK(); - - if (isJdk) { - if (!st.getProductURN().equals(jdkUrn) || - !st.getProductName().equals( - props.getProperty("servicetag.jdk.name"))) { - throw new RuntimeException("Product URN and name don't match."); - } - } else { - if (!st.getProductURN().equals(jreUrn) || - !st.getProductName().equals( - props.getProperty("servicetag.jre.name"))) { - throw new RuntimeException("Product URN and name don't match."); - } - } - - if (!st.getProductVersion(). - equals(System.getProperty("java.version"))) { - throw new RuntimeException("Unexpected product_version: " + - st.getProductVersion()); - } - if (!st.getProductParent(). - equals(props.getProperty("servicetag.parent.name"))) { - throw new RuntimeException("Unexpected product_parent: " + - st.getProductParent()); - } - if (!st.getProductParentURN(). - equals(props.getProperty("servicetag.parent.urn"))) { - throw new RuntimeException("Unexpected product_parent_urn: " + - st.getProductParentURN()); - } - if (!st.getPlatformArch(). - equals(System.getProperty("os.arch"))) { - throw new RuntimeException("Unexpected platform_arch: " + - st.getPlatformArch()); - } - - String vendor = System.getProperty("java.vendor"); - if (!st.getProductVendor(). - equals(vendor)) { - throw new RuntimeException("Unexpected product_vendor: " + - st.getProductVendor()); - } - if (!st.getSource(). - equals(source)) { - throw new RuntimeException("Unexpected source: " + - st.getSource() + " expected: " + source); - } - String[] ss = st.getProductDefinedInstanceID().split(","); - boolean id = false; - boolean dir = false; - for (String s : ss) { - String[] values = s.split("="); - if (values[0].equals("id")) { - id = true; - String[] sss = values[1].split(" "); - if (!sss[0].equals(System.getProperty("java.runtime.version"))) { - throw new RuntimeException("Unexpected version in id: " + - sss[0]); - } - if (sss.length < 2) { - throw new RuntimeException("Unexpected id=" + values[1]); - } - } else if (values[0].equals("dir")) { - dir = true; - } - } - if (!id || !dir) { - throw new RuntimeException("Unexpected product_defined_instance_id: " + - st.getProductDefinedInstanceID()); - } - } - - private static Properties loadServiceTagProps() - throws IOException { - String filename = "/com/sun/servicetag/resources/javase_servicetag.properties"; - try (InputStream in = Installer.class.getClass().getResourceAsStream(filename)) { - Properties props = new Properties(); - props.load(in); - return props; - } - } -} diff --git a/jdk/test/com/sun/servicetag/NewRegistrationData.java b/jdk/test/com/sun/servicetag/NewRegistrationData.java deleted file mode 100644 index d2b6c8bf6d0..00000000000 --- a/jdk/test/com/sun/servicetag/NewRegistrationData.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for Registration Data - * @author Mandy Chung - * - * @run build NewRegistrationData Util - * @run main NewRegistrationData - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class NewRegistrationData { - private static RegistrationData regData; - private static Map stMap = new LinkedHashMap(); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - - public static void main(String[] argv) throws Exception { - String regDataDir = System.getProperty("test.classes"); - String servicetagDir = System.getProperty("test.src"); - - File reg = new File(regDataDir, "registration.xml"); - // Make sure a brand new file is created - reg.delete(); - - regData = new RegistrationData(); - if (regData.getRegistrationURN().isEmpty()) { - throw new RuntimeException("Empty registration urn"); - } - - int count = 0; - for (String f : files) { - addServiceTag(servicetagDir, f, ++count); - } - - // check if the registration data contains all service tags - Set c = regData.getServiceTags(); - for (ServiceTag st : c) { - if (!Util.matches(st, regData.getServiceTag(st.getInstanceURN()))) { - throw new RuntimeException("ServiceTag added in the regData " + - " doesn't match."); - } - } - - // store the service tag to a file - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(reg)); - try { - regData.storeToXML(out); - } finally { - out.close(); - } - - Util.checkRegistrationData(reg.getCanonicalPath(), stMap); - System.out.println("Test passed: " + count + " service tags added"); - } - - private static void addServiceTag(String parent, String filename, int count) throws Exception { - File f = new File(parent, filename); - ServiceTag svcTag = Util.newServiceTag(f); - regData.addServiceTag(svcTag); - stMap.put(svcTag.getInstanceURN(), svcTag); - - Set c = regData.getServiceTags(); - if (c.size() != count) { - throw new RuntimeException("Invalid service tag count= " + - c.size() + " expected=" + count); - } - ServiceTag st = regData.getServiceTag(svcTag.getInstanceURN()); - if (!Util.matches(st, svcTag)) { - throw new RuntimeException("ServiceTag added in the regData " + - " doesn't match."); - } - } -} diff --git a/jdk/test/com/sun/servicetag/SvcTagClient.java b/jdk/test/com/sun/servicetag/SvcTagClient.java deleted file mode 100644 index d888a4492a5..00000000000 --- a/jdk/test/com/sun/servicetag/SvcTagClient.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2008, 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. - */ - -/* - * @bug 6622366 - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -/** - * A utility class simulating stclient for testing purpose. - */ -public class SvcTagClient { - private static File xmlFile; - private static RegistrationData registration; - private static String instanceURN; - private static String productName; - private static String productVersion; - private static String productURN; - private static String productParent; - private static String productParentURN = ""; // optional - private static String productDefinedInstanceID = ""; //optional - private static String productVendor; - private static String platformArch; - private static String container; - private static String source; - - // stclient exit value - private static final int ST_ERR_REC_NOT_FOUND = 225; - - public static void main(String[] args) throws Exception { - String path = System.getProperty("stclient.registry.path"); - if (path == null) { - System.err.println("stclient registry path missing"); - System.exit(-1); - } - xmlFile = new File(path); - if (xmlFile.exists()) { - BufferedInputStream in = new BufferedInputStream(new FileInputStream(xmlFile)); - registration = RegistrationData.loadFromXML(in); - } else { - registration = new RegistrationData(); - } - boolean add = false; - boolean delete = false; - boolean update = false; - boolean get = false; - boolean find = false; - - int count = 0; - while (count < args.length) { - String arg = args[count]; - if (!arg.startsWith("-")) { - System.err.println("Invalid option:" + arg); - System.exit(-1); - } - if (arg.equals("-a")) { - add = true; - } else if (arg.equals("-d")) { - delete = true; - } else if (arg.equals("-u")) { - update = true; - } else if (arg.equals("-g")) { - get = true; - } else if (arg.equals("-f")) { - find = true; - productURN = ""; - } else if (arg.equals("-t")) { - productURN = args[++count]; - } else if (arg.equals("-i")) { - instanceURN = args[++count]; - } else if (arg.equals("-p")) { - productName = args[++count]; - } else if (arg.equals("-e")) { - productVersion = args[++count]; - } else if (arg.equals("-t")) { - productURN = args[++count]; - } else if (arg.equals("-F")) { - productParentURN = args[++count]; - } else if (arg.equals("-P")) { - productParent = args[++count]; - } else if (arg.equals("-I")) { - productDefinedInstanceID = args[++count]; - } else if (arg.equals("-m")) { - productVendor = args[++count]; - } else if (arg.equals("-A")) { - platformArch = args[++count]; - } else if (arg.equals("-z")) { - container = args[++count]; - } else if (arg.equals("-S")) { - source = args[++count]; - } else { - System.err.println("Invalid option:" + arg); - System.exit(-1); - } - count++; - } - - if (add) { - addServiceTag(); - } else if (delete) { - deleteServiceTag(); - } else if (update) { - updateServiceTag(); - } else if (get) { - getServiceTag(); - } else if (find) { - findServiceTags(); - } else { - System.err.println("Error"); - System.exit(-1); - } - updateXmlFile(); - } - private static String OUTPUT = "Product instance URN="; - - private static void addServiceTag() { - if (instanceURN == null) { - instanceURN = ServiceTag.generateInstanceURN(); - } - ServiceTag st = ServiceTag.newInstance(instanceURN, - productName, - productVersion, - productURN, - productParent, - productParentURN, - productDefinedInstanceID, - productVendor, - platformArch, - container, - source); - registration.addServiceTag(st); - System.out.println(OUTPUT + st.getInstanceURN()); - } - - private static void deleteServiceTag() { - registration.removeServiceTag(instanceURN); - System.out.println("instance_urn=" + instanceURN + " deleted"); - } - - private static void updateServiceTag() { - registration.updateServiceTag(instanceURN, productDefinedInstanceID); - System.out.println("instance_urn=" + instanceURN + " updated"); - } - - private static void getServiceTag() { - ServiceTag st = registration.getServiceTag(instanceURN); - if (st == null) { - System.err.println("instance_urn=" + instanceURN + " not found"); - System.exit(ST_ERR_REC_NOT_FOUND); - } else { - System.out.println(st); - } - } - - private static void findServiceTags() { - Set set = registration.getServiceTags(); - for (ServiceTag st : set) { - if (st.getProductURN().equals(productURN)) { - System.out.println(st.getInstanceURN()); - } - } - if (set.size() == 0) { - System.out.println("No records found"); - System.exit(ST_ERR_REC_NOT_FOUND); - } - } - private static void updateXmlFile() throws IOException { - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(xmlFile)); - try { - registration.storeToXML(out); - } finally { - out.close(); - } - } -} diff --git a/jdk/test/com/sun/servicetag/SystemRegistryTest.java b/jdk/test/com/sun/servicetag/SystemRegistryTest.java deleted file mode 100644 index 4ec459c2bb3..00000000000 --- a/jdk/test/com/sun/servicetag/SystemRegistryTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2008, 2010, 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 6622366 - * @summary Basic Test for registry class - * by replacing stclient with SvcTagClient utility - * @author Mandy Chung - * - * @run build SvcTagClient SystemRegistryTest Util - * @run main SystemRegistryTest - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class SystemRegistryTest { - private static String registryDir = System.getProperty("test.classes"); - private static String servicetagDir = System.getProperty("test.src"); - private static List list = new ArrayList(); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - - private static Registry registry; - public static void main(String[] argv) throws Exception { - try { - registry = Util.getSvcTagClientRegistry(); - runTest(); - } finally { - // restore empty registry file - Util.emptyRegistryFile(); - } - } - - private static void runTest() throws Exception { - for (String filename : files) { - File f = new File(servicetagDir, filename); - ServiceTag svcTag = Util.newServiceTag(f); - ServiceTag st = registry.addServiceTag(svcTag); - list.add(st); - System.out.println(st); - } - - testDuplicate(list.get(0)); - testNotFound(); - - // remove a service tag - String urn = list.get(0).getInstanceURN(); - ServiceTag svcTag = registry.removeServiceTag(urn); - if (!Util.matches(svcTag, list.get(0))) { - throw new RuntimeException(urn + - " deleted but does not match."); - } - - // get a service tag - svcTag = list.get(1); - urn = svcTag.getInstanceURN(); - ServiceTag st = registry.getServiceTag(urn); - if (!Util.matches(svcTag, st)) { - throw new RuntimeException(urn + - " returned from getServiceTag but does not match."); - } - // update the service tag - registry.updateServiceTag(urn, "My new defined ID"); - st = registry.getServiceTag(urn); - if (Util.matches(svcTag, st)) { - throw new RuntimeException(urn + - " updated but expected to be different."); - } - - if (!st.getProductDefinedInstanceID().equals("My new defined ID")) { - throw new RuntimeException("Invalid product_defined_instance_id " + - st.getProductDefinedInstanceID()); - } - if (st.getInstallerUID() != -1) { - throw new RuntimeException("Invalid installer_uid " + - st.getInstallerUID()); - } - if (st.getTimestamp().equals(svcTag.getTimestamp())) { - throw new RuntimeException("Timestamp " + - st.getTimestamp() + " == " + svcTag.getTimestamp()); - } - - } - private static void testDuplicate(ServiceTag st) throws IOException { - boolean dup = false; - try { - registry.addServiceTag(st); - } catch (IllegalArgumentException e) { - dup = true; - } - if (!dup) { - throw new RuntimeException(st.getInstanceURN() + - " added successfully but expected to be a duplicated."); - } - } - - private static void testNotFound() throws Exception { - String instanceURN = "urn:st:721cf98a-f4d7-6231-bb1d-f2f5aa903ef7"; - ServiceTag svctag = registry.removeServiceTag(instanceURN); - if (svctag != null) { - throw new RuntimeException(instanceURN + - " exists but expected not found"); - } - - svctag = registry.updateServiceTag(instanceURN, "testing"); - if (svctag != null) { - throw new RuntimeException(instanceURN + - " exists but expected not found"); - } - } -} diff --git a/jdk/test/com/sun/servicetag/TestLoadFromXML.java b/jdk/test/com/sun/servicetag/TestLoadFromXML.java deleted file mode 100644 index a41d016ae75..00000000000 --- a/jdk/test/com/sun/servicetag/TestLoadFromXML.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for RegistrationData.loadFromXML - * @author Mandy Chung - * - * @run build TestLoadFromXML - * @run main TestLoadFromXML - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class TestLoadFromXML { - public static void main(String[] argv) throws Exception { - String registrationDir = System.getProperty("test.classes"); - String servicetagDir = System.getProperty("test.src"); - - File inFile = new File(servicetagDir, "registration.xml"); - File outFile = new File(registrationDir, "out.xml"); - BufferedInputStream in = new BufferedInputStream(new FileInputStream(inFile)); - RegistrationData regData = RegistrationData.loadFromXML(in); - boolean closed = false; - try { - in.read(); - } catch (IOException e) { - // expect the InputStream is closed - closed = true; - System.out.println("*** Expected IOException ***"); - e.printStackTrace(); - } - if (!closed) { - throw new RuntimeException("InputStream not closed after " + - "RegistrationData.loadFromXML() call"); - } - - BufferedOutputStream out = - new BufferedOutputStream(new FileOutputStream(outFile)); - regData.storeToXML(out); - // should be able to write to the OutputStream - out.write(0); - } -} diff --git a/jdk/test/com/sun/servicetag/UpdateServiceTagTest.java b/jdk/test/com/sun/servicetag/UpdateServiceTagTest.java deleted file mode 100644 index b564ea37160..00000000000 --- a/jdk/test/com/sun/servicetag/UpdateServiceTagTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for RegistrationData.updateServiceTag - * @author Mandy Chung - * - * @run build UpdateServiceTagTest Util - * @run main UpdateServiceTagTest - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class UpdateServiceTagTest { - private static String servicetagDir = System.getProperty("test.src"); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - private static RegistrationData registration = new RegistrationData(); - private static Set set = new HashSet(); - - public static void main(String[] argv) throws Exception { - for (String f : files) { - ServiceTag st = addServiceTag(f); - set.add(st); - } - Thread.sleep(1000); - for (ServiceTag st : set) { - updateServiceTag(st); - } - } - - private static ServiceTag addServiceTag(String filename) throws Exception { - File f = new File(servicetagDir, filename); - ServiceTag svcTag = Util.newServiceTag(f, true /* no instance_urn */); - ServiceTag st = registration.addServiceTag(svcTag); - if (!Util.matchesNoInstanceUrn(svcTag, st)) { - throw new RuntimeException("ServiceTag " + - " doesn't match."); - } - String urn = st.getInstanceURN(); - if (!urn.startsWith("urn:st:")) { - throw new RuntimeException("Invalid generated instance_urn " + - urn); - } - if (st.getInstallerUID() != -1) { - throw new RuntimeException("Invalid installer_uid " + - st.getInstallerUID()); - } - if (st.getTimestamp() == null) { - throw new RuntimeException("null timestamp "); - } - return st; - } - - private static String newID = "New product defined instance ID"; - private static void updateServiceTag(ServiceTag svcTag) throws Exception { - // update the service tag - String urn = svcTag.getInstanceURN(); - registration.updateServiceTag(urn, newID); - - // get the updated service tag - ServiceTag st = registration.getServiceTag(urn); - if (Util.matches(svcTag, st)) { - throw new RuntimeException("ServiceTag " + - " should not match."); - } - if (!st.getProductDefinedInstanceID().equals(newID)) { - throw new RuntimeException("Invalid product_defined_instance_id " + - st.getProductDefinedInstanceID()); - } - if (st.getInstallerUID() != -1) { - throw new RuntimeException("Invalid installer_uid " + - st.getInstallerUID()); - } - if (st.getTimestamp().equals(svcTag.getTimestamp())) { - throw new RuntimeException("Timestamp " + - st.getTimestamp() + " == " + svcTag.getTimestamp()); - } - } -} diff --git a/jdk/test/com/sun/servicetag/Util.java b/jdk/test/com/sun/servicetag/Util.java deleted file mode 100644 index d0d33019bab..00000000000 --- a/jdk/test/com/sun/servicetag/Util.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2008, 2010, 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. - */ - -/* - * @bug 6622366 - * @summary Utility class used by other jtreg tests - */ - -import com.sun.servicetag.RegistrationData; -import com.sun.servicetag.ServiceTag; -import com.sun.servicetag.Registry; - -import java.util.Set; -import java.util.Date; -import java.util.Map; -import java.util.Properties; -import java.util.TimeZone; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.io.*; - -public class Util { - public static ServiceTag newServiceTag(File f) - throws FileNotFoundException, IOException, NumberFormatException { - return newServiceTag(f, false /* with instance_urn */); - } - - public static ServiceTag newServiceTag(File f, boolean noInstanceURN) - throws FileNotFoundException, IOException, NumberFormatException { - Properties props = new Properties(); - FileReader reader = new FileReader(f); - try { - props.load(reader); - } finally { - reader.close(); - } - if (noInstanceURN) { - return ServiceTag.newInstance( - props.getProperty("product_name"), - props.getProperty("product_version"), - props.getProperty("product_urn"), - props.getProperty("product_parent"), - props.getProperty("product_parent_urn"), - props.getProperty("product_defined_inst_id"), - props.getProperty("product_vendor"), - props.getProperty("platform_arch"), - props.getProperty("container"), - props.getProperty("source")); - } else { - return ServiceTag.newInstance( - props.getProperty("instance_urn"), - props.getProperty("product_name"), - props.getProperty("product_version"), - props.getProperty("product_urn"), - props.getProperty("product_parent"), - props.getProperty("product_parent_urn"), - props.getProperty("product_defined_inst_id"), - props.getProperty("product_vendor"), - props.getProperty("platform_arch"), - props.getProperty("container"), - props.getProperty("source")); - } - } - - public static boolean matches(ServiceTag st1, ServiceTag st2) { - if (!st1.getInstanceURN().equals(st2.getInstanceURN())) { - System.out.println("instance_urn: " + st1.getInstanceURN() + - " != " + st2.getInstanceURN()); - return false; - } - return matchesNoInstanceUrn(st1, st2); - } - - public static boolean matchesNoInstanceUrn(ServiceTag st1, ServiceTag st2) { - if (!st1.getProductName().equals(st2.getProductName())) { - System.out.println("product_name: " + st1.getProductName() + - " != " + st2.getProductName()); - return false; - } - - if (!st1.getProductVersion().equals(st2.getProductVersion())) { - System.out.println("product_version: " + st1.getProductVersion() + - " != " + st2.getProductVersion()); - return false; - } - if (!st1.getProductURN().equals(st2.getProductURN())) { - System.out.println("product_urn: " + st1.getProductURN() + - " != " + st2.getProductURN()); - return false; - } - if (!st1.getProductParentURN().equals(st2.getProductParentURN())) { - System.out.println("product_parent_urn: " + st1.getProductParentURN() + - " != " + st2.getProductParentURN()); - return false; - } - if (!st1.getProductParent().equals(st2.getProductParent())) { - System.out.println("product_parent: " + st1.getProductParent() + - " != " + st2.getProductParent()); - return false; - } - if (!st1.getProductDefinedInstanceID().equals(st2.getProductDefinedInstanceID())) { - System.out.println("product_defined_inst_id: " + - st1.getProductDefinedInstanceID() + - " != " + st2.getProductDefinedInstanceID()); - return false; - } - if (!st1.getProductVendor().equals(st2.getProductVendor())) { - System.out.println("product_vendor: " + st1.getProductVendor() + - " != " + st2.getProductVendor()); - return false; - } - if (!st1.getPlatformArch().equals(st2.getPlatformArch())) { - System.out.println("platform_arch: " + st1.getPlatformArch() + - " != " + st2.getPlatformArch()); - return false; - } - if (!st1.getContainer().equals(st2.getContainer())) { - System.out.println("container: " + st1.getContainer() + - " != " + st2.getContainer()); - return false; - } - if (!st1.getSource().equals(st2.getSource())) { - System.out.println("source: " + st1.getSource() + - " != " + st2.getSource()); - return false; - } - return true; - } - - public static void checkRegistrationData(String regFile, - Map stMap) - throws IOException { - BufferedInputStream in = new BufferedInputStream(new FileInputStream(regFile)); - RegistrationData registration = RegistrationData.loadFromXML(in); - Set svcTags = registration.getServiceTags(); - if (svcTags.size() != stMap.size()) { - throw new RuntimeException("Invalid service tag count= " + - svcTags.size() + " expected=" + stMap.size()); - } - for (ServiceTag st : svcTags) { - ServiceTag st1 = stMap.get(st.getInstanceURN()); - if (!matches(st, st1)) { - System.err.println(st); - System.err.println(st1); - throw new RuntimeException("ServiceTag in the registry " + - "does not match the one in the map"); - } - } - } - - - /** - * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT. - * @param timestamp Date - * @return a string representation of the timestamp in the YYYY-MM-dd HH:mm:ss GMT format. - */ - static String formatTimestamp(Date timestamp) { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - df.setTimeZone(TimeZone.getTimeZone("GMT")); - return df.format(timestamp); - } - - /** - * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format. - * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format. - * @return Date - */ - static Date parseTimestamp(String timestamp) { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); - df.setTimeZone(TimeZone.getTimeZone("GMT")); - try { - return df.parse(timestamp); - } catch (ParseException e) { - // should not reach here - e.printStackTrace(); - return new Date(); - } - } - - /** - * Returns the command simulating stclient behavior. - */ - static String getSvcClientCommand(String stclientRegistry) { - String regDir = System.getProperty("test.classes"); - - StringBuilder sb = new StringBuilder(); - // wrap each argument to the command with double quotes - sb.append("\""); - sb.append(System.getProperty("java.home")); - sb.append(File.separator).append("bin"); - sb.append(File.separator).append("java"); - sb.append("\""); - sb.append(" -cp "); - sb.append("\"").append(regDir).append("\""); - sb.append(" \"-Dstclient.registry.path="); - sb.append(stclientRegistry).append("\""); - sb.append(" SvcTagClient"); - return sb.toString(); - } - - private static Registry registry = null; - private static File registryFile = null; - /** - * Returns the Registry processed by SvcTagClient that simulates - * stclient. - */ - static synchronized Registry getSvcTagClientRegistry() throws IOException { - String regDir = System.getProperty("test.classes"); - File f = new File(regDir, "registry.xml"); - if (registry != null) { - if (!f.equals(registryFile) && f.length() != 0) { - throw new AssertionError("Has to be empty registry.xml to run in samevm"); - } - return registry; - } - - // System.setProperty("servicetag.verbose", "true"); - // enable the helper class - System.setProperty("servicetag.sthelper.supported", "true"); - registryFile = f; - - String stclientCmd = Util.getSvcClientCommand(registryFile.getCanonicalPath()); - System.out.println("stclient cmd: " + stclientCmd); - System.setProperty("servicetag.stclient.cmd", stclientCmd); - - // get the Registry object after the system properties are set - registry = Registry.getSystemRegistry(); - return registry; - } - - static void emptyRegistryFile() throws IOException { - if (registryFile.exists()) { - BufferedOutputStream out = new BufferedOutputStream( - new FileOutputStream(registryFile)); - try { - RegistrationData data = new RegistrationData(); - data.storeToXML(out); - } finally { - out.close(); - } - } - } -} diff --git a/jdk/test/com/sun/servicetag/ValidRegistrationData.java b/jdk/test/com/sun/servicetag/ValidRegistrationData.java deleted file mode 100644 index affcb8c3b0c..00000000000 --- a/jdk/test/com/sun/servicetag/ValidRegistrationData.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2008, 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 6622366 - * @summary Basic Test for reading a valid registration - * @author Mandy Chung - * - * @run build ValidRegistrationData - * @run main ValidRegistrationData - */ - -import com.sun.servicetag.*; -import java.io.*; -import java.util.*; - -public class ValidRegistrationData { - private static String registrationDir = System.getProperty("test.classes"); - private static String servicetagDir = System.getProperty("test.src"); - private static RegistrationData registration; - private static Map stMap = - new LinkedHashMap(); - private static String[] files = new String[] { - "servicetag1.properties", - "servicetag2.properties", - "servicetag3.properties" - }; - private static String URN = "urn:st:9543ffaa-a4f1-4f77-b2d1-f561922d4e4a"; - - public static void main(String[] argv) throws Exception { - File f = new File(servicetagDir, "registration.xml"); - - // load the registration data with all service tags - BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); - registration = RegistrationData.loadFromXML(in); - if (!registration.getRegistrationURN().equals(URN)){ - throw new RuntimeException("Invalid URN=" + - registration.getRegistrationURN()); - } - Map environMap = registration.getEnvironmentMap(); - checkEnvironmentMap(environMap); - - // set environment - setInvalidEnvironment("hostname", ""); - setInvalidEnvironment("osName", ""); - setInvalidEnvironment("invalid", ""); - } - - private static void checkEnvironmentMap(Map envMap) - throws Exception { - Properties props = new Properties(); - File f = new File(servicetagDir, "environ.properties"); - FileReader reader = new FileReader(f); - try { - props.load(reader); - } finally { - reader.close(); - } - for (Map.Entry entry : envMap.entrySet()) { - String name = entry.getKey(); - String value = entry.getValue(); - String expected = props.getProperty(name); - if (expected == null || !value.equals(expected)) { - throw new RuntimeException("Invalid environment " + - name + "=" + value); - } - props.remove(name); - } - if (!props.isEmpty()) { - System.out.println("Environment missing: "); - for (String s : props.stringPropertyNames()) { - System.out.println(" " + s + "=" + props.getProperty(s)); - } - throw new RuntimeException("Invalid environment read"); - } - } - private static void setInvalidEnvironment(String name, String value) { - boolean invalid = false; - try { - registration.setEnvironment(name, value); - } catch (IllegalArgumentException e) { - invalid = true; - } - if (!invalid) { - throw new RuntimeException(name + "=" + value + - " set but expected to fail."); - } - } -} diff --git a/jdk/test/com/sun/servicetag/environ.properties b/jdk/test/com/sun/servicetag/environ.properties deleted file mode 100644 index 22163e587d8..00000000000 --- a/jdk/test/com/sun/servicetag/environ.properties +++ /dev/null @@ -1,9 +0,0 @@ -hostname=ko -hostId=83abc1ab -osName=SunOS -osVersion=5.10 -osArchitecture=sparc -systemModel=Sun-Fire-V440 -systemManufacturer=Oracle Corporation -cpuManufacturer=Oracle Corporation -serialNumber=BEL078932 diff --git a/jdk/test/com/sun/servicetag/missing-environ-field.xml b/jdk/test/com/sun/servicetag/missing-environ-field.xml deleted file mode 100644 index 775bbaab1b3..00000000000 --- a/jdk/test/com/sun/servicetag/missing-environ-field.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - -ko - -SunOS -5.10 -sparc - - - - - - -urn:st:9efff93a-767c-4714-fcfa-c48988293110 -Java SE 6 Runtime Environment -1.6.0-internal -urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -Java Platform Standard Edition 6 (Java SE 6) -id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Oracle Corporation -sparc -2007-11-12 06:15:11 GMT -global -servicetag1.properties -121937 - - -urn:st:0e9712bf-4832-e315-8e40-c4b17ffac9a9 -Java SE 6 Development Kit -1.6.0 -urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 -urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -Java Platform Standard Edition 6 (Java SE 6) -id=1.6.0_05-b01 sparc,dir=/myjdk/solaris-i586 -Oracle Corporation -i386 -2007-11-12 06:15:11 GMT -global -servicetag2.properties -121937 - - - diff --git a/jdk/test/com/sun/servicetag/newer-registry-version.xml b/jdk/test/com/sun/servicetag/newer-registry-version.xml deleted file mode 100644 index fe9fdf3bdec..00000000000 --- a/jdk/test/com/sun/servicetag/newer-registry-version.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - -ko - -SunOS -5.10 -sparc - - - - - - - -urn:st:9efff93a-767c-4714-fcfa-c48988293110 -Java SE 6 Runtime Environment -1.6.0-internal -urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -Java Platform Standard Edition 6 (Java SE 6) -id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Oracle Corporation -sparc -2007-11-13 00:49:01 GMT -global -servicetag1.properties -121937 - - - - diff --git a/jdk/test/com/sun/servicetag/registration.xml b/jdk/test/com/sun/servicetag/registration.xml deleted file mode 100644 index 287590ab153..00000000000 --- a/jdk/test/com/sun/servicetag/registration.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - -ko -83abc1ab -SunOS -5.10 -sparc -Sun-Fire-V440 -Oracle Corporation -Oracle Corporation -BEL078932 - - - -urn:st:9efff93a-767c-4714-fcfa-c48988293110 -Java SE 6 Runtime Environment -1.6.0-internal -urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -Java Platform Standard Edition 6 (Java SE 6) -id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -Oracle Corporation -sparc -2007-11-13 00:49:01 GMT -global -servicetag1.properties -121937 - - -urn:st:0e9712bf-4832-e315-8e40-c4b17ffac9a9 -Java SE 6 Development Kit -1.6.0 -urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 -urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -Java Platform Standard Edition 6 (Java SE 6) -id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586 -Oracle Corporation -i386 -2007-11-13 00:49:01 GMT -global -servicetag2.properties -121937 - - -urn:st:8a6ff75e-21a4-c8d7-bbda-de2c971bd67d -Solaris 10 Operating System -10 -urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113 -urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92 -Solaris Operating System - -Oracle Corporation -sparc -2007-11-13 00:49:01 GMT -global -servicetag3.properties -212883 - - - diff --git a/jdk/test/com/sun/servicetag/servicetag1.properties b/jdk/test/com/sun/servicetag/servicetag1.properties deleted file mode 100644 index c37bc365231..00000000000 --- a/jdk/test/com/sun/servicetag/servicetag1.properties +++ /dev/null @@ -1,13 +0,0 @@ -instance_urn=urn:st:9efff93a-767c-4714-fcfa-c48988293110 -product_name=Java SE 6 Runtime Environment -product_version=1.6.0-internal -product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -product_parent=Java Platform Standard Edition 6 (Java SE 6) -product_defined_inst_id=id=1.6.0-internal-b00 sparc,dir=/myjdk/solaris-sparc -product_vendor=Oracle Corporation -platform_arch=sparc -timestamp=2007-11-12 05:19:40 GMT -container=global -source=servicetag1.properties -installer_uid=121937 diff --git a/jdk/test/com/sun/servicetag/servicetag2.properties b/jdk/test/com/sun/servicetag/servicetag2.properties deleted file mode 100644 index 54867f7a6b0..00000000000 --- a/jdk/test/com/sun/servicetag/servicetag2.properties +++ /dev/null @@ -1,13 +0,0 @@ -instance_urn=urn:st:0e9712bf-4832-e315-8e40-c4b17ffac9a9 -product_name=Java SE 6 Development Kit -product_version=1.6.0 -product_urn=urn:uuid:b58ef9a8-5ae8-11db-a023-080020a9ed93 -product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -product_parent=Java Platform Standard Edition 6 (Java SE 6) -product_defined_inst_id=id=1.6.0_05-b01 i386,dir=/myjdk/solaris-i586 -product_vendor=Oracle Corporation -platform_arch=i386 -timestamp=2007-11-12 06:12:21 GMT -container=global -source=servicetag2.properties -installer_uid=121937 diff --git a/jdk/test/com/sun/servicetag/servicetag3.properties b/jdk/test/com/sun/servicetag/servicetag3.properties deleted file mode 100644 index 5bd4e477843..00000000000 --- a/jdk/test/com/sun/servicetag/servicetag3.properties +++ /dev/null @@ -1,13 +0,0 @@ -instance_urn=urn:st:8a6ff75e-21a4-c8d7-bbda-de2c971bd67d -product_name=Solaris 10 Operating System -product_version=10 -product_urn=urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113 -product_parent_urn=urn:uuid:596ffcfa-63d5-11d7-9886-ac816a682f92 -product_parent=Solaris Operating System -product_defined_inst_id= -product_vendor=Oracle Corporation -platform_arch=sparc -timestamp=2007-06-20 22:07:11 GMT -container=global -source=servicetag3.properties -installer_uid=212883 diff --git a/jdk/test/com/sun/servicetag/servicetag4.properties b/jdk/test/com/sun/servicetag/servicetag4.properties deleted file mode 100644 index 02892041f5a..00000000000 --- a/jdk/test/com/sun/servicetag/servicetag4.properties +++ /dev/null @@ -1,13 +0,0 @@ -instance_urn=urn:st:b8171b45-a087-47b3-92c8-f2d9fb34e8c2 -product_name=Java SE 6 Runtime Environment -product_version=1.6.0_05 -product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -product_parent=Java Platform Standard Edition 6 (Java SE 6) -product_defined_inst_id=id=1.6.0_05-b01 amd64,dir=/myjdk/linux-amd64 -product_vendor=Oracle Corporation -platform_arch=x64 -timestamp=2007-12-12 05:19:40 GMT -container=global -source=servicetag4.properties -installer_uid=121937 diff --git a/jdk/test/com/sun/servicetag/servicetag5.properties b/jdk/test/com/sun/servicetag/servicetag5.properties deleted file mode 100644 index f7e53bfc0e0..00000000000 --- a/jdk/test/com/sun/servicetag/servicetag5.properties +++ /dev/null @@ -1,13 +0,0 @@ -instance_urn=urn:st:1d4269a1-71e3-4e44-bc8f-3793da7928ed -product_name=Java SE 6 Runtime Environment -product_version=1.6.0_06 -product_urn=urn:uuid:92d1de8c-1e59-42c6-a280-1c379526bcbc -product_parent_urn=urn:uuid:fdc90b21-018d-4cab-b866-612c7c119ed3 -product_parent=Java Platform Standard Edition 6 (Java SE 6) -product_defined_inst_id=id=1.6.0_06-b06 i386,dir=/w/mchung/bundles/jdk1.6.0_05/jre -product_vendor=Oracle Corporation -platform_arch=x86 -timestamp=2007-11-29 17:59:42 GMT -container=global -source=servicetag5.properties -installer_uid=-1 From f20cadfd8bd161011d2f59049f49b630564af33c Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Tue, 26 Mar 2013 08:42:35 +0100 Subject: [PATCH 116/137] 8010706: -Dnashorn.args system property to create command lines to wrapped nashorn.jar:s Reviewed-by: hannesw, sundar --- nashorn/docs/DEVELOPER_README | 11 +++++++++++ .../jdk/nashorn/internal/runtime/options/Options.java | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/nashorn/docs/DEVELOPER_README b/nashorn/docs/DEVELOPER_README index 3bd220b2a7c..d0587ce6f1a 100644 --- a/nashorn/docs/DEVELOPER_README +++ b/nashorn/docs/DEVELOPER_README @@ -13,6 +13,17 @@ properties described herein are subject to change without notice. This documentation of the system property flags assume that the default value of the flag is false, unless otherwise specified. +SYSTEM PROPERTY: -Dnashorn.args= + +This property takes as its value a space separated list of Nashorn +command line options that should be passed to Nashorn. This might be useful +in environments where it is hard to tell how a nashorn.jar is launched. + +Example: + +> java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar +> ant -Dnashorn.args="--log=codegen" antjob + SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x This property controls how many call site misses are allowed before a diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java index 0f30b1a171d..3e09fa57c08 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java @@ -66,6 +66,9 @@ public final class Options { /** The options map of enabled options */ private final TreeMap> options; + /** System property that can be used for command line option propagation */ + private static final String NASHORN_ARGS_PROPERTY = "nashorn.args"; + /** * Constructor * @@ -386,6 +389,14 @@ public final class Options { final LinkedList argList = new LinkedList<>(); Collections.addAll(argList, args); + final String extra = getStringProperty(NASHORN_ARGS_PROPERTY, null); + if (extra != null) { + final StringTokenizer st = new StringTokenizer(extra); + while (st.hasMoreTokens()) { + argList.add(st.nextToken()); + } + } + while (!argList.isEmpty()) { final String arg = argList.remove(0); From 97d7f98a215734face729dbb39070d88cbd8704c Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 26 Mar 2013 18:26:19 +0530 Subject: [PATCH 117/137] 8010720: Linkage problem with java.lang.String.length() Reviewed-by: hannesw, lagergren --- .../internal/objects/NativeString.java | 13 +++++ .../runtime/linker/PrimitiveLookup.java | 1 - nashorn/test/script/basic/JDK-8010720.js | 49 +++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8010720.js diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java index b2b1cf2bcbc..5f48ad98ecb 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java @@ -122,6 +122,19 @@ public final class NativeString extends ScriptObject { return value.length(); } + // This is to support length as method call as well. + @Override + protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { + final String name = desc.getNameToken(2); + + // if str.length(), then let the bean linker handle it + if ("length".equals(name) && "getMethod".equals(operator)) { + return null; + } + + return super.findGetMethod(desc, request, operator); + } + // This is to provide array-like access to string characters without creating a NativeString wrapper. @Override protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java index 968dba91e58..eaba64f4629 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java @@ -109,7 +109,6 @@ public class PrimitiveLookup { } return new GuardedInvocation(method, guard, link.getSwitchPoint()); } - assert desc.getNameTokenCount() <= 2; // Named operations would hit the return null after findProperty return null; } } diff --git a/nashorn/test/script/basic/JDK-8010720.js b/nashorn/test/script/basic/JDK-8010720.js new file mode 100644 index 00000000000..1dddf22be85 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8010720.js @@ -0,0 +1,49 @@ +/* + * 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-8010720: Linkage problem with java.lang.String.length() + * + * @test + * @run + */ + +var s = new java.lang.String("nashorn"); + +if (s.length() != 7) { + fail("s.length() does not return expected value"); +} + +if (s.length != 7) { + fail("s.length does not return expected value"); +} + + +if ('hello'.length() != 5) { + fail("'hello'.length() does not return expected value"); +} + +if ('hello'.length != 5) { + fail("'hello'.length does not return expected value"); +} + From feec2af7b40bf40bb149a4fcf2675b764a2cbc2d Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Tue, 26 Mar 2013 09:06:16 -0400 Subject: [PATCH 118/137] 8009595: The UseSplitVerifier option needs to be deprecated Put UseSplitVerifier option on the deprecated list. Reviewed-by: dcubed, kmo, acorn --- hotspot/src/share/vm/classfile/classFileParser.cpp | 3 +-- hotspot/src/share/vm/classfile/verifier.cpp | 3 +-- hotspot/src/share/vm/runtime/arguments.cpp | 1 + hotspot/src/share/vm/runtime/globals.hpp | 3 --- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 9f2a9f419a4..47692ac6342 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2196,8 +2196,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface, true, // is LVTT CHECK_(nullHandle)); lvtt_cnt++; - } else if (UseSplitVerifier && - _major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION && + } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION && _cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) { // Stack map is only needed by the new verifier in JDK1.5. if (parsed_stackmap_attribute) { diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp index 96912df1971..f5261c5a67c 100644 --- a/hotspot/src/share/vm/classfile/verifier.cpp +++ b/hotspot/src/share/vm/classfile/verifier.cpp @@ -127,8 +127,7 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul if (TraceClassInitialization) { tty->print_cr("Start class verification for: %s", klassName); } - if (UseSplitVerifier && - klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { + if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { ClassVerifier split_verifier(klass, THREAD); split_verifier.verify_class(THREAD); exception_name = split_verifier.result(); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index a2bcb956249..91561005174 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -260,6 +260,7 @@ static ObsoleteFlag obsolete_jvm_flags[] = { { "CMSRevisitStackSize", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "PrintRevisitStats", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "UseVectoredExceptions", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UseSplitVerifier", JDK_Version::jdk(8), JDK_Version::jdk(9) }, #ifdef PRODUCT { "DesiredMethodLimit", JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 681a0f72d93..e73e5089bab 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -679,9 +679,6 @@ class CommandLineFlags { product(bool, UseCompilerSafepoints, true, \ "Stop at safepoints in compiled code") \ \ - product(bool, UseSplitVerifier, true, \ - "use split verifier with StackMapTable attributes") \ - \ product(bool, FailOverToOldVerifier, true, \ "fail over to old verifier when split verifier fails") \ \ From ee3ea81f6549243ed02deda33e09d9907aa380a1 Mon Sep 17 00:00:00 2001 From: Joel Borggren-Franck Date: Tue, 26 Mar 2013 15:00:34 +0100 Subject: [PATCH 119/137] 8009382: Add JVM_Get{Field|Method}TypeAnnotations Reviewed-by: dcubed, rbackman --- hotspot/make/bsd/makefiles/mapfile-vers-debug | 2 + .../make/bsd/makefiles/mapfile-vers-product | 2 + .../make/linux/makefiles/mapfile-vers-debug | 2 + .../make/linux/makefiles/mapfile-vers-product | 2 + hotspot/make/solaris/makefiles/mapfile-vers | 2 + hotspot/src/share/vm/prims/jvm.cpp | 78 +++++++++++++++---- hotspot/src/share/vm/prims/jvm.h | 8 ++ 7 files changed, 81 insertions(+), 15 deletions(-) diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug index 24144fe9b70..eb33112062c 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug @@ -135,6 +135,7 @@ SUNWprivate_1.1 { JVM_GetEnclosingMethodInfo; JVM_GetFieldAnnotations; JVM_GetFieldIxModifiers; + JVM_GetFieldTypeAnnotations; JVM_GetHostName; JVM_GetInheritedAccessControlContext; JVM_GetInterfaceVersion; @@ -156,6 +157,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; JVM_GetMethodParameters; + JVM_GetMethodTypeAnnotations; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product index c165c16e2d8..ace133748b7 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-product +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product @@ -135,6 +135,7 @@ SUNWprivate_1.1 { JVM_GetEnclosingMethodInfo; JVM_GetFieldAnnotations; JVM_GetFieldIxModifiers; + JVM_GetFieldTypeAnnotations; JVM_GetHostName; JVM_GetInheritedAccessControlContext; JVM_GetInterfaceVersion; @@ -156,6 +157,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; JVM_GetMethodParameters; + JVM_GetMethodTypeAnnotations; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug index 27238f5720a..b18fb74fd9a 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-debug +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug @@ -131,6 +131,7 @@ SUNWprivate_1.1 { JVM_GetEnclosingMethodInfo; JVM_GetFieldAnnotations; JVM_GetFieldIxModifiers; + JVM_GetFieldTypeAnnotations; JVM_GetHostName; JVM_GetInheritedAccessControlContext; JVM_GetInterfaceVersion; @@ -152,6 +153,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; JVM_GetMethodParameters; + JVM_GetMethodTypeAnnotations; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product index 04531fa15aa..168d84c1e90 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-product +++ b/hotspot/make/linux/makefiles/mapfile-vers-product @@ -131,6 +131,7 @@ SUNWprivate_1.1 { JVM_GetEnclosingMethodInfo; JVM_GetFieldAnnotations; JVM_GetFieldIxModifiers; + JVM_GetFieldTypeAnnotations; JVM_GetHostName; JVM_GetInheritedAccessControlContext; JVM_GetInterfaceVersion; @@ -152,6 +153,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; JVM_GetMethodParameters; + JVM_GetMethodTypeAnnotations; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers index d58807b046d..1a0b572a5c6 100644 --- a/hotspot/make/solaris/makefiles/mapfile-vers +++ b/hotspot/make/solaris/makefiles/mapfile-vers @@ -131,6 +131,7 @@ SUNWprivate_1.1 { JVM_GetEnclosingMethodInfo; JVM_GetFieldAnnotations; JVM_GetFieldIxModifiers; + JVM_GetFieldTypeAnnotations; JVM_GetHostName; JVM_GetInheritedAccessControlContext; JVM_GetInterfaceVersion; @@ -152,6 +153,7 @@ SUNWprivate_1.1 { JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; JVM_GetMethodParameters; + JVM_GetMethodTypeAnnotations; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index ce66961269f..4e599d8dd75 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1457,7 +1457,7 @@ JVM_END JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls)) assert (cls != NULL, "illegal class"); JVMWrapper("JVM_GetClassAnnotations"); - ResourceMark rm(THREAD); + // Return null for arrays and primitives if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); @@ -1470,20 +1470,15 @@ JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls)) JVM_END -JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field)) - assert(field != NULL, "illegal field"); - JVMWrapper("JVM_GetFieldAnnotations"); - +static bool jvm_get_field_common(jobject field, fieldDescriptor& fd, TRAPS) { // some of this code was adapted from from jni_FromReflectedField - // field is a handle to a java.lang.reflect.Field object oop reflected = JNIHandles::resolve_non_null(field); oop mirror = java_lang_reflect_Field::clazz(reflected); Klass* k = java_lang_Class::as_Klass(mirror); int slot = java_lang_reflect_Field::slot(reflected); int modifiers = java_lang_reflect_Field::modifiers(reflected); - fieldDescriptor fd; KlassHandle kh(THREAD, k); intptr_t offset = InstanceKlass::cast(kh())->field_offset(slot); @@ -1491,16 +1486,29 @@ JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field)) // for static fields we only look in the current class if (!InstanceKlass::cast(kh())->find_local_field_from_offset(offset, true, &fd)) { assert(false, "cannot find static field"); - return NULL; // robustness + return false; } } else { // for instance fields we start with the current class and work // our way up through the superclass chain if (!InstanceKlass::cast(kh())->find_field_from_offset(offset, false, &fd)) { assert(false, "cannot find instance field"); - return NULL; // robustness + return false; } } + return true; +} + +JVM_ENTRY(jbyteArray, JVM_GetFieldAnnotations(JNIEnv *env, jobject field)) + // field is a handle to a java.lang.reflect.Field object + assert(field != NULL, "illegal field"); + JVMWrapper("JVM_GetFieldAnnotations"); + + fieldDescriptor fd; + bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL); + if (!gotFd) { + return NULL; + } return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.annotations(), THREAD)); JVM_END @@ -1525,12 +1533,8 @@ static Method* jvm_get_method_common(jobject method) { Klass* k = java_lang_Class::as_Klass(mirror); Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); - if (m == NULL) { - assert(false, "cannot find method"); - return NULL; // robustness - } - - return m; + assert(m != NULL, "cannot find method"); + return m; // caller has to deal with NULL in product mode } @@ -1539,6 +1543,10 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodAnnotations(JNIEnv *env, jobject method)) // method is a handle to a java.lang.reflect.Method object Method* m = jvm_get_method_common(method); + if (m == NULL) { + return NULL; + } + return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotations(), THREAD)); JVM_END @@ -1549,6 +1557,10 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject m // method is a handle to a java.lang.reflect.Method object Method* m = jvm_get_method_common(method); + if (m == NULL) { + return NULL; + } + return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotation_default(), THREAD)); JVM_END @@ -1559,6 +1571,10 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject met // method is a handle to a java.lang.reflect.Method object Method* m = jvm_get_method_common(method); + if (m == NULL) { + return NULL; + } + return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->parameter_annotations(), THREAD)); JVM_END @@ -1583,6 +1599,38 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) return NULL; JVM_END +JVM_ENTRY(jbyteArray, JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method)) + assert (method != NULL, "illegal method"); + JVMWrapper("JVM_GetMethodTypeAnnotations"); + + // method is a handle to a java.lang.reflect.Method object + Method* m = jvm_get_method_common(method); + if (m == NULL) { + return NULL; + } + + AnnotationArray* type_annotations = m->type_annotations(); + if (type_annotations != NULL) { + typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL); + return (jbyteArray) JNIHandles::make_local(env, a); + } + + return NULL; +JVM_END + +JVM_ENTRY(jbyteArray, JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field)) + assert (field != NULL, "illegal field"); + JVMWrapper("JVM_GetFieldTypeAnnotations"); + + fieldDescriptor fd; + bool gotFd = jvm_get_field_common(field, fd, CHECK_NULL); + if (!gotFd) { + return NULL; + } + + return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.type_annotations(), THREAD)); +JVM_END + static void bounds_check(constantPoolHandle cp, jint index, TRAPS) { if (!cp->is_within_bounds(index)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds"); diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h index 52cef93077c..486b13531af 100644 --- a/hotspot/src/share/vm/prims/jvm.h +++ b/hotspot/src/share/vm/prims/jvm.h @@ -523,6 +523,14 @@ JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method); JNIEXPORT jbyteArray JNICALL JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); +// field is a handle to a java.lang.reflect.Field object +JNIEXPORT jbyteArray JNICALL +JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field); + +// method is a handle to a java.lang.reflect.Method object +JNIEXPORT jbyteArray JNICALL +JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method); + /* * New (JDK 1.4) reflection implementation */ From 7c46953faf0f170ba173e0dd53767533f1c8470f Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 26 Mar 2013 14:11:21 -0400 Subject: [PATCH 120/137] 8010651: create.bat still builds the kernel Remove old kernel build targets and VS C++ projects created by create.bat on Windows Reviewed-by: coleenp, sla --- hotspot/make/windows/build.make | 8 ++--- hotspot/make/windows/create.bat | 4 +-- hotspot/make/windows/makefiles/compile.make | 7 ----- hotspot/make/windows/makefiles/product.make | 8 ----- hotspot/make/windows/makefiles/vm.make | 4 --- .../make/windows/projectfiles/kernel/Makefile | 27 ----------------- .../make/windows/projectfiles/kernel/vm.def | 7 ----- .../make/windows/projectfiles/kernel/vm.dsw | 29 ------------------ .../tools/ProjectCreator/BuildConfig.java | 30 ------------------- .../ProjectCreator/WinGammaPlatform.java | 6 ---- 10 files changed, 5 insertions(+), 125 deletions(-) delete mode 100644 hotspot/make/windows/projectfiles/kernel/Makefile delete mode 100644 hotspot/make/windows/projectfiles/kernel/vm.def delete mode 100644 hotspot/make/windows/projectfiles/kernel/vm.dsw diff --git a/hotspot/make/windows/build.make b/hotspot/make/windows/build.make index 8a53ee5d4b1..e2f50542523 100644 --- a/hotspot/make/windows/build.make +++ b/hotspot/make/windows/build.make @@ -110,8 +110,6 @@ VARIANT_TEXT=Server !endif !elseif "$(Variant)" == "tiered" VARIANT_TEXT=Tiered -!elseif "$(Variant)" == "kernel" -VARIANT_TEXT=Kernel !endif ######################################################################### @@ -305,9 +303,9 @@ $(variantDir)\local.make: checks checks: checkVariant checkWorkSpace checkSA checkVariant: - @ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false - @ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "kernel" if "$(Variant)" NEQ "core" \ - echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false + @ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false + @ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "core" \ + echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false checkWorkSpace: @ if "$(WorkSpace)"=="" echo Need to specify "WorkSpace=..." && false diff --git a/hotspot/make/windows/create.bat b/hotspot/make/windows/create.bat index ee4a1865e51..16602c8ea90 100644 --- a/hotspot/make/windows/create.bat +++ b/hotspot/make/windows/create.bat @@ -148,7 +148,7 @@ echo HotSpotJDKDist=%HotSpotJDKDist% REM This is now safe to do. :copyfiles -for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( +for /D %%i in (compiler1, compiler2, tiered, core) do ( if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL ) @@ -156,7 +156,7 @@ copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\ REM force regneration of ProjectFile if exist %ProjectFile% del %ProjectFile% -for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( +for /D %%i in (compiler1, compiler2, tiered, core) do ( echo -- %%i -- echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index 38c0bd57c9a..819aae43e22 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -221,13 +221,6 @@ LD_FLAGS = /SAFESEH $(LD_FLAGS) !endif !endif -# Compile for space above time. -!if "$(Variant)" == "kernel" -PRODUCT_OPT_OPTION = /O1 /Oy- -FASTDEBUG_OPT_OPTION = /O1 /Oy- -DEBUG_OPT_OPTION = /Od -!endif - # If NO_OPTIMIZATIONS is defined in the environment, turn everything off !ifdef NO_OPTIMIZATIONS PRODUCT_OPT_OPTION = $(DEBUG_OPT_OPTION) diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make index 2b21d1ceb58..f166f7377bf 100644 --- a/hotspot/make/windows/makefiles/product.make +++ b/hotspot/make/windows/makefiles/product.make @@ -51,13 +51,6 @@ HS_BUILD_ID=$(HS_BUILD_VER) # Force resources to be rebuilt every time $(Res_Files): FORCE -# Kernel doesn't need exported vtbl symbols. -!if "$(Variant)" == "kernel" -$(AOUT): $(Res_Files) $(Obj_Files) - $(LD) @<< - $(LD_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files) -<< -!else vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh @@ -65,7 +58,6 @@ $(AOUT): $(Res_Files) $(Obj_Files) vm.def $(LD) @<< $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << -!endif !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make index 2e501a7b9f7..bd02d42fa4f 100644 --- a/hotspot/make/windows/makefiles/vm.make +++ b/hotspot/make/windows/makefiles/vm.make @@ -89,12 +89,8 @@ STACK_SIZE= # AsyncGetCallTrace is not supported on IA64 yet AGCT_EXPORT= !else -!if "$(Variant)" == "kernel" -AGCT_EXPORT= -!else AGCT_EXPORT=/export:AsyncGetCallTrace !endif -!endif # If you modify exports below please do the corresponding changes in # src/share/tools/ProjectCreator/WinGammaPlatformVC7.java diff --git a/hotspot/make/windows/projectfiles/kernel/Makefile b/hotspot/make/windows/projectfiles/kernel/Makefile deleted file mode 100644 index a11b06b3850..00000000000 --- a/hotspot/make/windows/projectfiles/kernel/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (c) 2007, 2010, 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 ../local.make - -!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile diff --git a/hotspot/make/windows/projectfiles/kernel/vm.def b/hotspot/make/windows/projectfiles/kernel/vm.def deleted file mode 100644 index b450e81fd01..00000000000 --- a/hotspot/make/windows/projectfiles/kernel/vm.def +++ /dev/null @@ -1,7 +0,0 @@ -; -; This .DEF file is a placeholder for one which is automatically -; generated during the build process. See -; make\windows\build_vm_def.sh and -; make\windows\makefiles\projectcreator.make (esp. the "-prelink" -; options). -; diff --git a/hotspot/make/windows/projectfiles/kernel/vm.dsw b/hotspot/make/windows/projectfiles/kernel/vm.dsw deleted file mode 100644 index 934f51afdb3..00000000000 --- a/hotspot/make/windows/projectfiles/kernel/vm.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "vm"=.\vm.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java index 00441dfb220..953967fccd4 100644 --- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java +++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java @@ -568,36 +568,6 @@ class CoreProductConfig extends ProductConfig { } } -class KernelDebugConfig extends GenericDebugConfig { - String getOptFlag() { - return getCI().getNoOptFlag(); - } - - KernelDebugConfig() { - initNames("kernel", "debug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - - -class KernelFastDebugConfig extends GenericDebugConfig { - String getOptFlag() { - return getCI().getOptFlag(); - } - - KernelFastDebugConfig() { - initNames("kernel", "fastdebug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - - -class KernelProductConfig extends ProductConfig { - KernelProductConfig() { - initNames("kernel", "product", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java index 2cc6f542ee5..db93a27cf72 100644 --- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java +++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java @@ -564,12 +564,6 @@ public abstract class WinGammaPlatform { allConfigs.add(new CoreFastDebugConfig()); allConfigs.add(new CoreProductConfig()); - if (platform.equals("Win32")) { - allConfigs.add(new KernelDebugConfig()); - allConfigs.add(new KernelFastDebugConfig()); - allConfigs.add(new KernelProductConfig()); - } - return allConfigs; } From cf6d13410cad6bf1708873c5ec7740f79f5be422 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 27 Mar 2013 10:55:37 +0100 Subject: [PATCH 121/137] 8010818: NPG: Remove metaspace memory pools Reviewed-by: mgerdin, stefank --- hotspot/src/share/vm/memory/metaspace.hpp | 8 +- hotspot/src/share/vm/memory/universe.cpp | 1 - .../src/share/vm/services/memoryManager.cpp | 4 - .../src/share/vm/services/memoryManager.hpp | 10 --- hotspot/src/share/vm/services/memoryPool.cpp | 34 --------- hotspot/src/share/vm/services/memoryPool.hpp | 26 ------- .../src/share/vm/services/memoryService.cpp | 21 +----- .../src/share/vm/services/memoryService.hpp | 5 -- .../metaspace/TestMetaspaceMemoryPools.java | 75 ------------------- 9 files changed, 7 insertions(+), 177 deletions(-) delete mode 100644 hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 56197fdd070..f704804795f 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -157,16 +157,16 @@ class Metaspace : public CHeapObj { class MetaspaceAux : AllStatic { - static size_t free_chunks_total(Metaspace::MetadataType mdtype); - static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); - - public: // Statistics for class space and data space in metaspace. static size_t used_in_bytes(Metaspace::MetadataType mdtype); static size_t free_in_bytes(Metaspace::MetadataType mdtype); static size_t capacity_in_bytes(Metaspace::MetadataType mdtype); static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); + static size_t free_chunks_total(Metaspace::MetadataType mdtype); + static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); + + public: // Total of space allocated to metadata in all Metaspaces static size_t used_in_bytes() { return used_in_bytes(Metaspace::ClassType) + diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 4406addc9e8..79e092a3b19 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1108,7 +1108,6 @@ bool universe_post_init() { // Initialize performance counters for metaspaces MetaspaceCounters::initialize_performance_counters(); - MemoryService::add_metaspace_memory_pools(); GC_locker::unlock(); // allow gc after bootstrapping diff --git a/hotspot/src/share/vm/services/memoryManager.cpp b/hotspot/src/share/vm/services/memoryManager.cpp index d5e54f5ff15..3996d2163c8 100644 --- a/hotspot/src/share/vm/services/memoryManager.cpp +++ b/hotspot/src/share/vm/services/memoryManager.cpp @@ -61,10 +61,6 @@ MemoryManager* MemoryManager::get_code_cache_memory_manager() { return (MemoryManager*) new CodeCacheMemoryManager(); } -MemoryManager* MemoryManager::get_metaspace_memory_manager() { - return (MemoryManager*) new MetaspaceMemoryManager(); -} - GCMemoryManager* MemoryManager::get_copy_memory_manager() { return (GCMemoryManager*) new CopyMemoryManager(); } diff --git a/hotspot/src/share/vm/services/memoryManager.hpp b/hotspot/src/share/vm/services/memoryManager.hpp index 12c0a0ec458..370d830e977 100644 --- a/hotspot/src/share/vm/services/memoryManager.hpp +++ b/hotspot/src/share/vm/services/memoryManager.hpp @@ -56,7 +56,6 @@ public: enum Name { Abstract, CodeCache, - Metaspace, Copy, MarkSweepCompact, ParNew, @@ -89,7 +88,6 @@ public: // Static factory methods to get a memory manager of a specific type static MemoryManager* get_code_cache_memory_manager(); - static MemoryManager* get_metaspace_memory_manager(); static GCMemoryManager* get_copy_memory_manager(); static GCMemoryManager* get_msc_memory_manager(); static GCMemoryManager* get_parnew_memory_manager(); @@ -110,14 +108,6 @@ public: const char* name() { return "CodeCacheManager"; } }; -class MetaspaceMemoryManager : public MemoryManager { -public: - MetaspaceMemoryManager() : MemoryManager() {} - - MemoryManager::Name kind() { return MemoryManager::Metaspace; } - const char *name() { return "MetaspaceManager"; } -}; - class GCStatInfo : public ResourceObj { private: size_t _index; diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 969ed7f22bf..e2895b1f816 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -26,15 +26,12 @@ #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "oops/oop.inline.hpp" -#include "runtime/globals.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" -#include "runtime/os.hpp" #include "services/lowMemoryDetector.hpp" #include "services/management.hpp" #include "services/memoryManager.hpp" #include "services/memoryPool.hpp" -#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" MemoryPool::MemoryPool(const char* name, @@ -259,34 +256,3 @@ MemoryUsage CodeHeapPool::get_memory_usage() { return MemoryUsage(initial_size(), used, committed, maxSize); } - -MetaspacePoolBase::MetaspacePoolBase(const char *name, - Metaspace::MetadataType md_type, - size_t max_size) : - _md_type(md_type), - MemoryPool(name, NonHeap, MetaspaceAux::capacity_in_bytes(_md_type), max_size, - true, false) { } - -size_t MetaspacePoolBase::used_in_bytes() { - return MetaspaceAux::used_in_bytes(_md_type); -} - -MemoryUsage MetaspacePoolBase::get_memory_usage() { - size_t used = MetaspaceAux::used_in_bytes(_md_type); - size_t committed = align_size_down_(MetaspaceAux::capacity_in_bytes(_md_type), os::vm_page_size()); - return MemoryUsage(initial_size(), used, committed, max_size()); -} - -ClassMetaspacePool::ClassMetaspacePool() : - MetaspacePoolBase("Class Metaspace", Metaspace::ClassType, calculate_max_size()) { } - -size_t ClassMetaspacePool::calculate_max_size() { - return UseCompressedKlassPointers ? ClassMetaspaceSize : _undefined_max_size; -} - -MetaspacePool::MetaspacePool() : - MetaspacePoolBase("Metaspace", Metaspace::NonClassType, calculate_max_size()) { } - -size_t MetaspacePool::calculate_max_size() { - return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : _undefined_max_size; -} diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp index f36c3984ced..82606185340 100644 --- a/hotspot/src/share/vm/services/memoryPool.hpp +++ b/hotspot/src/share/vm/services/memoryPool.hpp @@ -28,7 +28,6 @@ #include "gc_implementation/shared/mutableSpace.hpp" #include "memory/defNewGeneration.hpp" #include "memory/heap.hpp" -#include "memory/metaspace.hpp" #include "memory/space.hpp" #include "services/memoryUsage.hpp" #include "utilities/macros.hpp" @@ -223,29 +222,4 @@ public: size_t used_in_bytes() { return _codeHeap->allocated_capacity(); } }; -class MetaspacePoolBase : public MemoryPool { -private: - Metaspace::MetadataType _md_type; -protected: - static const size_t _undefined_max_size = (size_t) -1; -public: - MetaspacePoolBase(const char *name, Metaspace::MetadataType md_type, size_t max_size); - MemoryUsage get_memory_usage(); - size_t used_in_bytes(); -}; - -class ClassMetaspacePool : public MetaspacePoolBase { -private: - size_t calculate_max_size(); -public: - ClassMetaspacePool(); -}; - -class MetaspacePool : public MetaspacePoolBase { -private: - size_t calculate_max_size(); -public: - MetaspacePool(); -}; - #endif // SHARE_VM_SERVICES_MEMORYPOOL_HPP diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index 41f7328d8a8..75693dbcf69 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -60,11 +60,9 @@ GrowableArray* MemoryService::_pools_list = GrowableArray* MemoryService::_managers_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(init_managers_list_size, true); -GCMemoryManager* MemoryService::_minor_gc_manager = NULL; -GCMemoryManager* MemoryService::_major_gc_manager = NULL; -MemoryPool* MemoryService::_code_heap_pool = NULL; -MemoryPool* MemoryService::_metaspace_pool = NULL; -MemoryPool* MemoryService::_class_metaspace_pool = NULL; +GCMemoryManager* MemoryService::_minor_gc_manager = NULL; +GCMemoryManager* MemoryService::_major_gc_manager = NULL; +MemoryPool* MemoryService::_code_heap_pool = NULL; class GcThreadCountClosure: public ThreadClosure { private: @@ -401,19 +399,6 @@ void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) { _managers_list->append(mgr); } -void MemoryService::add_metaspace_memory_pools() { - _metaspace_pool = new MetaspacePool(); - _class_metaspace_pool = new ClassMetaspacePool(); - - MemoryManager* mgr = MemoryManager::get_metaspace_memory_manager(); - mgr->add_pool(_metaspace_pool); - mgr->add_pool(_class_metaspace_pool); - - _pools_list->append(_metaspace_pool); - _pools_list->append(_class_metaspace_pool); - _managers_list->append(mgr); -} - MemoryManager* MemoryService::get_memory_manager(instanceHandle mh) { for (int i = 0; i < _managers_list->length(); i++) { MemoryManager* mgr = _managers_list->at(i); diff --git a/hotspot/src/share/vm/services/memoryService.hpp b/hotspot/src/share/vm/services/memoryService.hpp index fcd2fdf421d..44cf62ea3cb 100644 --- a/hotspot/src/share/vm/services/memoryService.hpp +++ b/hotspot/src/share/vm/services/memoryService.hpp @@ -73,10 +73,6 @@ private: // Code heap memory pool static MemoryPool* _code_heap_pool; - // Metaspace pools - static MemoryPool* _metaspace_pool; - static MemoryPool* _class_metaspace_pool; - static void add_generation_memory_pool(Generation* gen, MemoryManager* major_mgr, MemoryManager* minor_mgr); @@ -125,7 +121,6 @@ private: public: static void set_universe_heap(CollectedHeap* heap); static void add_code_heap_memory_pool(CodeHeap* heap); - static void add_metaspace_memory_pools(); static MemoryPool* get_memory_pool(instanceHandle pool); static MemoryManager* get_memory_manager(instanceHandle mgr); diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java deleted file mode 100644 index 884f377bc22..00000000000 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPools.java +++ /dev/null @@ -1,75 +0,0 @@ -import java.util.List; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryManagerMXBean; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryUsage; - -/* @test TestMetaspaceMemoryPools - * @bug 8000754 - * @summary Tests that two MemoryPoolMXBeans are created, one for metaspace and - * one for class metaspace, is created and that a MemoryManagerMXBean - * is created. - * @run main/othervm TestMetaspaceMemoryPools defined undefined - * @run main/othervm -XX:-UseCompressedKlassPointers TestMetaspaceMemoryPools undefined undefined - * @run main/othervm -XX:-UseCompressedKlassPointers -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPools undefined defined - */ -public class TestMetaspaceMemoryPools { - public static void main(String[] args) { - boolean isClassMetaspaceMaxDefined = args[0].equals("defined"); - boolean isMetaspaceMaxDefined = args[1].equals("defined"); - - verifyThatMetaspaceMemoryManagerExists(); - - verifyMemoryPool(getMemoryPool("Class Metaspace"), isClassMetaspaceMaxDefined); - verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined); - } - - private static void verifyThatMetaspaceMemoryManagerExists() { - List managers = ManagementFactory.getMemoryManagerMXBeans(); - for (MemoryManagerMXBean manager : managers) { - if (manager.getName().equals("MetaspaceManager")) { - return; - } - } - - throw new RuntimeException("Expected to find a metaspace memory manager"); - } - - private static MemoryPoolMXBean getMemoryPool(String name) { - List pools = ManagementFactory.getMemoryPoolMXBeans(); - for (MemoryPoolMXBean pool : pools) { - if (pool.getName().equals(name)) { - return pool; - } - } - - throw new RuntimeException("Expected to find a memory pool with name " + name); - } - - private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) { - MemoryUsage mu = pool.getUsage(); - assertDefined(mu.getInit(), "init"); - assertDefined(mu.getUsed(), "used"); - assertDefined(mu.getCommitted(), "committed"); - - if (isMaxDefined) { - assertDefined(mu.getMax(), "max"); - } else { - assertUndefined(mu.getMax(), "max"); - } - } - - private static void assertDefined(long value, String name) { - assertTrue(value != -1, "Expected " + name + " to be defined"); - } - - private static void assertUndefined(long value, String name) { - assertTrue(value == -1, "Expected " + name + " to be undefined"); - } - - private static void assertTrue(boolean condition, String msg) { - if (!condition) { - throw new RuntimeException(msg); - } - } -} From c2a873f014b8b7cad55091c382c8958d5be0a70a Mon Sep 17 00:00:00 2001 From: Gary Collins Date: Wed, 27 Mar 2013 09:49:51 -0700 Subject: [PATCH 122/137] 8009152: A number of jtreg tests need review/improvement Added a new test_env.txt file to capture common shell variable. Added concept of COMPILEJAVA for use when TESTJAVA is a JRE. If COMPILEJAVA not set then TESTJAVA will be the default with assumption it is a JDK. Reviewed-by: kvn, brutisso, coleenp --- hotspot/test/compiler/5091921/Test6890943.sh | 24 +-- hotspot/test/compiler/5091921/Test7005594.sh | 23 +-- hotspot/test/compiler/6857159/Test6857159.sh | 23 +-- hotspot/test/compiler/7068051/Test7068051.sh | 22 +-- hotspot/test/compiler/7070134/Test7070134.sh | 23 +-- hotspot/test/compiler/7200264/Test7200264.sh | 47 +---- hotspot/test/gc/6941923/test6941923.sh | 39 ++-- hotspot/test/runtime/6626217/Test6626217.sh | 69 +------ hotspot/test/runtime/6878713/Test6878713.sh | 54 +----- hotspot/test/runtime/6929067/Test6929067.sh | 26 ++- hotspot/test/runtime/7020373/Test7020373.sh | 52 +---- hotspot/test/runtime/7051189/Xchecksig.sh | 24 +-- hotspot/test/runtime/7107135/Test7107135.sh | 21 +- hotspot/test/runtime/7110720/Test7110720.sh | 19 +- hotspot/test/runtime/7158804/Test7158804.sh | 11 +- hotspot/test/runtime/7162488/Test7162488.sh | 24 +-- hotspot/test/test_env.sh | 193 +++++++++++++++++++ 17 files changed, 310 insertions(+), 384 deletions(-) create mode 100644 hotspot/test/test_env.sh diff --git a/hotspot/test/compiler/5091921/Test6890943.sh b/hotspot/test/compiler/5091921/Test6890943.sh index 7ebda8f6e8e..755f56890f1 100644 --- a/hotspot/test/compiler/5091921/Test6890943.sh +++ b/hotspot/test/compiler/5091921/Test6890943.sh @@ -22,26 +22,16 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + set -x @@ -50,7 +40,7 @@ cp ${TESTSRC}/input6890943.txt . cp ${TESTSRC}/output6890943.txt . cp ${TESTSRC}/Test6890943.sh . -${TESTJAVA}/bin/javac -d . Test6890943.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6890943.java ${TESTJAVA}/bin/java -XX:-PrintVMOptions -XX:+IgnoreUnrecognizedVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > pretest.out 2>&1 diff --git a/hotspot/test/compiler/5091921/Test7005594.sh b/hotspot/test/compiler/5091921/Test7005594.sh index 858e38a4e8a..9458a16bb55 100644 --- a/hotspot/test/compiler/5091921/Test7005594.sh +++ b/hotspot/test/compiler/5091921/Test7005594.sh @@ -22,26 +22,15 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh # Amount of physical memory in megabytes MEM=0 @@ -87,7 +76,7 @@ set -x cp ${TESTSRC}/Test7005594.java . cp ${TESTSRC}/Test7005594.sh . -${TESTJAVA}/bin/javac -d . Test7005594.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1 diff --git a/hotspot/test/compiler/6857159/Test6857159.sh b/hotspot/test/compiler/6857159/Test6857159.sh index 341130e773f..b73f1e2aafa 100644 --- a/hotspot/test/compiler/6857159/Test6857159.sh +++ b/hotspot/test/compiler/6857159/Test6857159.sh @@ -22,33 +22,22 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x cp ${TESTSRC}/Test6857159.java . cp ${TESTSRC}/Test6857159.sh . -${TESTJAVA}/bin/javac -d . Test6857159.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6857159.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xbatch -XX:+PrintCompilation -XX:CompileOnly=Test6857159\$ct.run Test6857159 > test.out 2>&1 diff --git a/hotspot/test/compiler/7068051/Test7068051.sh b/hotspot/test/compiler/7068051/Test7068051.sh index 3fc263b4e04..b1ecd453a6c 100644 --- a/hotspot/test/compiler/7068051/Test7068051.sh +++ b/hotspot/test/compiler/7068051/Test7068051.sh @@ -22,28 +22,24 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x -${TESTJAVA}/bin/jar xf ${TESTJAVA}/jre/lib/javaws.jar -${TESTJAVA}/bin/jar cf foo.jar * +${COMPILEJAVA}/bin/jar xf ${COMPILEJAVA}/jre/lib/javaws.jar +${COMPILEJAVA}/bin/jar cf foo.jar * cp ${TESTSRC}/Test7068051.java ./ -${TESTJAVA}/bin/jar -uf0 foo.jar Test7068051.java +${COMPILEJAVA}/bin/jar -uf0 foo.jar Test7068051.java -${TESTJAVA}/bin/javac -d . Test7068051.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7068051.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -showversion -Xbatch Test7068051 foo.jar diff --git a/hotspot/test/compiler/7070134/Test7070134.sh b/hotspot/test/compiler/7070134/Test7070134.sh index cbebfbab07e..f11be642f5b 100644 --- a/hotspot/test/compiler/7070134/Test7070134.sh +++ b/hotspot/test/compiler/7070134/Test7070134.sh @@ -22,33 +22,22 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x cp ${TESTSRC}/Stemmer.java . cp ${TESTSRC}/words . -${TESTJAVA}/bin/javac -d . Stemmer.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Stemmer.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xbatch Stemmer words > test.out 2>&1 diff --git a/hotspot/test/compiler/7200264/Test7200264.sh b/hotspot/test/compiler/7200264/Test7200264.sh index 4276a8f134b..1652bf3fbe6 100644 --- a/hotspot/test/compiler/7200264/Test7200264.sh +++ b/hotspot/test/compiler/7200264/Test7200264.sh @@ -23,50 +23,15 @@ # # +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug" @@ -88,7 +53,7 @@ else fi cp ${TESTSRC}${FS}TestIntVect.java . -${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java +${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} -d . TestIntVect.java ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1 diff --git a/hotspot/test/gc/6941923/test6941923.sh b/hotspot/test/gc/6941923/test6941923.sh index 0c751de12e0..9b33e32f449 100644 --- a/hotspot/test/gc/6941923/test6941923.sh +++ b/hotspot/test/gc/6941923/test6941923.sh @@ -5,38 +5,25 @@ ## @author yqi ## @run shell test6941923.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 ## skip on windows OS=`uname -s` case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; Windows_* | CYGWIN_* ) echo "Test skipped for Windows" exit 0 ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; esac -if [ "${JAVA_HOME}" = "" ] -then - echo "JAVA_HOME not set" - exit 0 -fi - -$JAVA_HOME/bin/java ${TESTVMOPTS} -version > $NULL 2>&1 - -if [ $? != 0 ]; then - echo "Wrong JAVA_HOME? JAVA_HOME: $JAVA_HOME" - exit $? -fi - # create a small test case testname="Test" if [ -e ${testname}.java ]; then @@ -96,10 +83,10 @@ msgsuccess="succeeded" msgfail="failed" gclogsize="16K" filesize=$((16*1024)) -$JAVA_HOME/bin/javac ${testname}.java > $NULL 2>&1 +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${testname}.java > $NULL 2>&1 if [ $? != 0 ]; then - echo "$JAVA_HOME/bin/javac ${testname}.java $fail" + echo "${COMPILEJAVA}/bin/javac ${testname}.java $fail" exit -1 fi @@ -119,7 +106,7 @@ fi options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=$gclogsize" echo "Test gc log rotation in same file, wait for $tts minutes ...." -$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts +${TESTJAVA}/bin/java $options $testname $tts if [ $? != 0 ]; then echo "$msgfail" exit -1 @@ -148,7 +135,7 @@ fi numoffiles=3 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=$numoffiles -XX:GCLogFileSize=$gclogsize" echo "Test gc log rotation in $numoffiles files, wait for $tts minutes ...." -$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts +${TESTJAVA}/bin/java $options $testname $tts if [ $? != 0 ]; then echo "$msgfail" exit -1 diff --git a/hotspot/test/runtime/6626217/Test6626217.sh b/hotspot/test/runtime/6626217/Test6626217.sh index a8c8a2395cf..ae340798054 100644 --- a/hotspot/test/runtime/6626217/Test6626217.sh +++ b/hotspot/test/runtime/6626217/Test6626217.sh @@ -27,78 +27,29 @@ # @summary Loader-constraint table allows arrays instead of only the base-classes # @run shell Test6626217.sh # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - RM=/bin/rm - CP=/bin/cp - MV=/bin/mv - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - RM=rm - CP=cp - MV=mv - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - RM=rm - CP=cp - MV=mv - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh JAVA=${TESTJAVA}${FS}bin${FS}java -JAVAC=${TESTJAVA}${FS}bin${FS}javac - -${JAVA} ${TESTVMOPTS} -version +JAVAC=${COMPILEJAVA}${FS}bin${FS}javac # Current directory is scratch directory, copy all the test source there # (for the subsequent moves to work). -${CP} ${TESTSRC}${FS}* ${THIS_DIR} +${CP} ${TESTSRC}${FS}* ${THIS_DIR} # A Clean Compile: this line will probably fail within jtreg as have a clean dir: ${RM} -f *.class *.impl many_loader.java # Compile all the usual suspects, including the default 'many_loader' ${CP} many_loader1.java.foo many_loader.java -${JAVAC} -source 1.4 -target 1.4 -Xlint *.java +${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint *.java # Rename the class files, so the custom loader (and not the system loader) will find it ${MV} from_loader2.class from_loader2.impl2 @@ -106,7 +57,7 @@ ${MV} from_loader2.class from_loader2.impl2 # Compile the next version of 'many_loader' ${MV} many_loader.class many_loader.impl1 ${CP} many_loader2.java.foo many_loader.java -${JAVAC} -source 1.4 -target 1.4 -Xlint many_loader.java +${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint many_loader.java # Rename the class file, so the custom loader (and not the system loader) will find it ${MV} many_loader.class many_loader.impl2 diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh index a452ad58fcd..47a18ad8fa0 100644 --- a/hotspot/test/runtime/6878713/Test6878713.sh +++ b/hotspot/test/runtime/6878713/Test6878713.sh @@ -6,57 +6,17 @@ ## @summary Verifier heap corruption, relating to backward jsrs ## @run shell/timeout=120 Test6878713.sh ## - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + 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 -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version - -${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar +${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass1960_2 > test.out 2>&1 diff --git a/hotspot/test/runtime/6929067/Test6929067.sh b/hotspot/test/runtime/6929067/Test6929067.sh index e4b649df82b..b707e096304 100644 --- a/hotspot/test/runtime/6929067/Test6929067.sh +++ b/hotspot/test/runtime/6929067/Test6929067.sh @@ -7,18 +7,15 @@ ## @compile T.java ## @run shell Test6929067.sh ## - +set -x if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + 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 platform-dependent variables OS=`uname -s` @@ -107,7 +104,7 @@ then fi -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH +LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH cp ${TESTSRC}${FS}invoke.c . @@ -115,15 +112,16 @@ cp ${TESTSRC}${FS}invoke.c . # Copy the result of our @compile action: cp ${TESTCLASSES}${FS}T.class . -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion - echo "Architecture: ${ARCH}" echo "Compilation flag: ${COMP_FLAG}" echo "VM type: ${VMTYPE}" +# Note pthread may not be found thus invoke creation will fail to be created. +# Check to ensure you have a /usr/lib/libpthread.so if you don't please look +# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. gcc -DLINUX ${COMP_FLAG} -o invoke \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - -L${TESTJAVA}/jre/lib/${ARCH}/${VMTYPE} \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ -ljvm -lpthread invoke.c ./invoke diff --git a/hotspot/test/runtime/7020373/Test7020373.sh b/hotspot/test/runtime/7020373/Test7020373.sh index 83e7f4c449d..83b7028c82f 100644 --- a/hotspot/test/runtime/7020373/Test7020373.sh +++ b/hotspot/test/runtime/7020373/Test7020373.sh @@ -10,55 +10,15 @@ ## if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + 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 -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version - -${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar +${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1 diff --git a/hotspot/test/runtime/7051189/Xchecksig.sh b/hotspot/test/runtime/7051189/Xchecksig.sh index f3eabce57d5..143e1445624 100644 --- a/hotspot/test/runtime/7051189/Xchecksig.sh +++ b/hotspot/test/runtime/7051189/Xchecksig.sh @@ -29,34 +29,22 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - printf "TESTJAVA not set, selecting " ${TESTJAVA} - printf " If this is incorrect, try setting the variable manually.\n" + 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 OS=`uname -s` case "$OS" in - SunOS | Linux | Darwin ) - FS="/" - ;; Windows_* | CYGWIN_* ) printf "Not testing libjsig.so on Windows. PASSED.\n " exit 0 ;; - * ) - printf "Not testing libjsig.so on unrecognised system. PASSED.\n " - exit 0 - ;; esac - JAVA=${TESTJAVA}${FS}bin${FS}java # LD_PRELOAD arch needs to match the binary we run, so run the java @@ -97,7 +85,7 @@ case $ARCH in ;; esac -LIBJSIG=${TESTJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so +LIBJSIG=${COMPILEJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so # If libjsig and binary do not match, skip test. diff --git a/hotspot/test/runtime/7107135/Test7107135.sh b/hotspot/test/runtime/7107135/Test7107135.sh index 6dc91a3039c..c283456438d 100644 --- a/hotspot/test/runtime/7107135/Test7107135.sh +++ b/hotspot/test/runtime/7107135/Test7107135.sh @@ -32,26 +32,19 @@ ## if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi - -BIT_FLAG="" +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh # set platform-dependent variables OS=`uname -s` case "$OS" in Linux) - NULL=/dev/null - PS=":" - FS="/" + echo "Testing on Linux" ;; *) NULL=NUL @@ -64,7 +57,7 @@ esac ARCH=`uname -m` -THIS_DIR=`pwd` +THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} ${TESTJAVA}${FS}bin${FS}javac *.java diff --git a/hotspot/test/runtime/7110720/Test7110720.sh b/hotspot/test/runtime/7110720/Test7110720.sh index 0788cb56a58..b051266fd2d 100644 --- a/hotspot/test/runtime/7110720/Test7110720.sh +++ b/hotspot/test/runtime/7110720/Test7110720.sh @@ -12,22 +12,13 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 + 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 # Jtreg sets TESTVMOPTS which may include -d64 which is # required to test a 64-bit JVM on some platforms. diff --git a/hotspot/test/runtime/7158804/Test7158804.sh b/hotspot/test/runtime/7158804/Test7158804.sh index e7f14238409..b5380ec8eb4 100644 --- a/hotspot/test/runtime/7158804/Test7158804.sh +++ b/hotspot/test/runtime/7158804/Test7158804.sh @@ -10,13 +10,14 @@ ## @summary Improve config file parsing ## @run shell Test7158804.sh ## - -if [ "${TESTJAVA}" = "" ] +if [ "${TESTSRC}" = "" ] then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi -echo "TESTJAVA=${TESTJAVA}" +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh rm -f .hotspotrc echo -XX:+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >.hotspotrc diff --git a/hotspot/test/runtime/7162488/Test7162488.sh b/hotspot/test/runtime/7162488/Test7162488.sh index bd70d027d46..0250f774c15 100644 --- a/hotspot/test/runtime/7162488/Test7162488.sh +++ b/hotspot/test/runtime/7162488/Test7162488.sh @@ -29,27 +29,13 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - printf "TESTJAVA not set, selecting " ${TESTJAVA} - printf " If this is incorrect, try setting the variable manually.\n" + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - ;; - * ) - FS="/" - ;; -esac +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh JAVA=${TESTJAVA}${FS}bin${FS}java diff --git a/hotspot/test/test_env.sh b/hotspot/test/test_env.sh new file mode 100644 index 00000000000..fa912dde237 --- /dev/null +++ b/hotspot/test/test_env.sh @@ -0,0 +1,193 @@ +#!/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. +# + +# +# This Environment script was written to capture typically used environment +# setup for a given shell test. +# + +# TESTJAVA can be a JDK or JRE. If JRE you need to set COMPILEJAVA +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi +echo "TESTJAVA=${TESTJAVA}" + +# COMPILEJAVA requires a JDK, some shell test use javac,jar,etc +if [ "${COMPILEJAVA}" = "" ] +then + echo "COMPILEJAVA not set. Using TESTJAVA as default" + COMPILEJAVA=${TESTJAVA} +fi +echo "COMPILEJAVA=${COMPILEJAVA}" + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASES not set. Using "." as default" + TESTCLASSES=. +fi +echo "TESTCLASSES=${TESTCLASSES}" + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + NULL=/dev/null + PS=":" + FS="/" + RM=/bin/rm + CP=/bin/cp + MV=/bin/mv + ;; + Windows_* ) + NULL=NUL + PS=";" + FS="\\" + RM=rm + CP=cp + MV=mv + ;; + CYGWIN_* ) + NULL=/dev/null + PS=";" + FS="/" + RM=rm + CP=cp + MV=mv + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +export NULL PS FS RM CP MV +echo "NULL =${NULL}" +echo "PS =${PS}" +echo "FS =${FS}" +echo "RM =${RM}" +echo "CP =${CP}" +echo "MV =${MV}" + +# jtreg -classpathappend: +JEMMYPATH=${CPAPPEND} +CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH +echo "CLASSPATH =${CLASSPATH}" + +# Current directory is scratch directory +THIS_DIR=. +echo "THIS_DIR=${THIS_DIR}" + +# Check to ensure the java defined actually works +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version +if [ $? != 0 ]; then + echo "Wrong TESTJAVA or TESTVMOPTS:" + echo $TESTJAVA TESTVMOPTS + exit 1 +fi + +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1 + +VM_TYPE="unknown" +grep "Server" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_TYPE="server" +fi +grep "Client" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_TYPE="client" +fi + +VM_BITS="32" +grep "64-Bit" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_BITS="64" +fi + +VM_OS="unknown" +grep "solaris" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="solaris" +fi +grep "linux" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="linux" +fi +grep "windows" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="windows" +fi +grep "bsd" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="bsd" +fi + +VM_CPU="unknown" +grep "sparc" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="sparc" + if [ $VM_BITS = "64" ] + then + VM_CPU="sparcv9" + fi +fi +grep "x86" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="i386" +fi +grep "amd64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="amd64" +fi +grep "arm" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="arm" +fi +grep "ppc" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="ppc" +fi +grep "ia64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="ia64" +fi +export VM_TYPE VM_BITS VM_OS VM_CPU +echo "VM_TYPE=${VM_TYPE}" +echo "VM_BITS=${VM_BITS}" +echo "VM_OS=${VM_OS}" +echo "VM_CPU=${VM_CPU}" From d81ec5b9f38e24aaaeb685ef3f89331dc558f604 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 28 Mar 2013 09:36:43 +0100 Subject: [PATCH 123/137] 8010908: Images target failes when configured with --disable-zip-debug-info Reviewed-by: tbell --- jdk/makefiles/Images.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk index 4a3a23525d1..70a816145b2 100644 --- a/jdk/makefiles/Images.gmk +++ b/jdk/makefiles/Images.gmk @@ -649,7 +649,7 @@ ifneq ($(POST_STRIP_CMD),) EXEC_LIST_BIN:=$(filter-out %$(notdir $(MSVCR_DLL)),$(filter %.exe %.dll,$(ALL_BIN_LIST))) else # Find all executables in JDK_OUTPUTDIR since they exist when this makefile is parsed - EXEC_LIST_BIN:=$(shell $(FILE) `$(FIND) $(JDK_OUTPUTDIR)/bin -type f -name \*$(EXE_SUFFIX)` \ + EXEC_LIST_BIN:=$(shell $(FILE) `$(FIND) $(JDK_OUTPUTDIR)/bin -type f -name \*$(EXE_SUFFIX) ! -name \*.debuginfo` \ | $(EGREP) 'ELF' | $(CUT) -d':' -f1) # On mac, the old build searches for static libraries for stripping instead of shared. # Not clear if it's intentional. From 361893b41ad5d49f4f1abfdc577a3225b8fd4840 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:53:50 -0700 Subject: [PATCH 124/137] Added tag jdk8-b83 for changeset 64247ba55872 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 7b38704aae9..db8b4550f1e 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -204,3 +204,4 @@ fd1a5574cf68af24bfd52decc37ac6361afb278a jdk8-b78 907a926d3c96472f357617b48b6b968ea855c23c jdk8-b80 145dbc56f931c134e837b675b9e6e7bf08902e93 jdk8-b81 29153d0df68f84162ffe8c2cf4f402a3f2245e85 jdk8-b82 +466685ba01bfb7bc1e1ac61490fd8c0f3cc18763 jdk8-b83 From 91473e6924d39dd60d3803340e19a61f3085a2a4 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:53:52 -0700 Subject: [PATCH 125/137] Added tag jdk8-b83 for changeset d2d074c62b67 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 92bf938663c..5a2a5cfc102 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -204,3 +204,4 @@ e41fb1aa0329767b2737303c994e38bede1baa07 jdk8-b79 5f3d4a6bdd027a1631d97e2dfff63fd5e46987a4 jdk8-b80 2a00aeeb466b9dee22508f6261f63b70f9c696fe jdk8-b81 48e1bc77004d9af575b733c04637b98fd17603c2 jdk8-b82 +a45bb25a67c7517b45f00c9682e317f46fecbba9 jdk8-b83 From afd676cdb3468ebc1d6573e59820de9c0597454d Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:54:00 -0700 Subject: [PATCH 126/137] Added tag jdk8-b83 for changeset 395a7c20e300 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index bfb3baa2ed0..d2b3a33d041 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -326,3 +326,4 @@ dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22 0631ebcc45f05c73b09a56c2586685af1f781c1d hs25-b23 3db4ab0e12f437fe374817de346b2b0c6b4a5b31 jdk8-b82 e3a41fc0234895eba4f272b984f7dacff495f8eb hs25-b24 +1c8db54ee9f315e20d6d5d9bf0b5c10349e9d301 jdk8-b83 From 65616fa742e2ad4b07ea2e550371a21db453126b Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:54:36 -0700 Subject: [PATCH 127/137] Added tag jdk8-b83 for changeset 8ca744a5d6f4 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 0c78beb6716..21b40f387ac 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -204,3 +204,4 @@ ff0b73a6b3f6cea644d37d56d746a37743419fa7 jdk8-b75 4873a0499bc3bd263b7dd3b551a2b4e275ab5a0b jdk8-b80 ef3495555a4c6e706a3058c18aa229b14220de0b jdk8-b81 d5a58291f09a5081eaf22c2a6ab2f9ced4b78882 jdk8-b82 +a46d69a1a8ec9652a48114823535372e1c980799 jdk8-b83 From ff17e3e399c49f7b47d2cc887c1b8a124b730166 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:54:47 -0700 Subject: [PATCH 128/137] Added tag jdk8-b83 for changeset 74e3fc2986f0 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index e02bdee2151..7bfa0ebd9f6 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -204,3 +204,4 @@ c4853f3f0e89ac60aa5b517f5f224f0f60e08577 jdk8-b76 b0224010e2f0c2474055ac592c8d3f37b9264690 jdk8-b80 c88bb21560ccf1a9e6d2a2ba08ed2045a002676f jdk8-b81 d8d8032d02d77fbf5f9b3bb8df73663f42fd4dd0 jdk8-b82 +a1dcc0d83da1e07f3ada60ef110dd105d95d3554 jdk8-b83 From 194b6327bc9e00d6728ff09128fdba4296d087d7 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:55:03 -0700 Subject: [PATCH 129/137] Added tag jdk8-b83 for changeset a93e7eb6663c --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 607d2df6b05..787670c7d60 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -204,3 +204,4 @@ c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79 dfb40f066c6ce129822f0f5dc2ac89173808781a jdk8-b80 c0f8022eba536dcdc8aae659005b33f3982b9368 jdk8-b81 624bcb4800065c6656171948e31ebb2925f25c7a jdk8-b82 +ac519af51769e92c51b597a730974e8607357709 jdk8-b83 From e4d9e1a5e7c9b833bea612d73814c4f9adaf73e4 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:55:14 -0700 Subject: [PATCH 130/137] Added tag jdk8-b83 for changeset fd242a461861 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 4f56fa54e99..359cd5e1440 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -204,3 +204,4 @@ af8417e590f4e76e0dfed09e71239fb102ef0d43 jdk8-b78 a8227c61768499dac847ea718af6719027c949f2 jdk8-b80 ed69d087fdfd394491657a28ba9bc58e7849b7db jdk8-b81 825da6847791994a8f405ee397df9e7fa638a458 jdk8-b82 +22ba3f92d4ae43bbc19793e854171cae2586f644 jdk8-b83 From ea13857a216630e87272b563813ebe23982e8fbf Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 28 Mar 2013 10:55:17 -0700 Subject: [PATCH 131/137] Added tag jdk8-b83 for changeset 4f4788d62566 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index ef0d7251625..d182815a343 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -192,3 +192,4 @@ b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b67 b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b68 b8a1b238c77c7c00024daaa2cb7d10838e017b5f jdk8-b69 5759f600fcf7b51ccc6cc8229be980e2153f8675 jdk8-b82 +053d7c55dc8272b58b8bb870dc92a4acf896d52a jdk8-b83 From 142f171fb666bff6c9f759b7f929e39bb0b2e11c Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Thu, 28 Mar 2013 19:02:00 -0700 Subject: [PATCH 132/137] Added tag hs25-b25 for changeset 4c619ad74be5 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index d2b3a33d041..40fd36ae97f 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -327,3 +327,4 @@ dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22 3db4ab0e12f437fe374817de346b2b0c6b4a5b31 jdk8-b82 e3a41fc0234895eba4f272b984f7dacff495f8eb hs25-b24 1c8db54ee9f315e20d6d5d9bf0b5c10349e9d301 jdk8-b83 +8d0f263a370c5f3e61791bb06054560804117288 hs25-b25 From c6ab956b21d94db40fe0abc040ab30bbe702dea4 Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Tue, 2 Apr 2013 13:59:30 +0100 Subject: [PATCH 133/137] 8009988: build-infra: Fix configure output for zip debuginfo check No output from zip debuginfo option when default is used. Reviewed-by: tbell --- common/autoconf/autogen.sh | 18 +- common/autoconf/generated-configure.sh | 456 ++++++++++++------------- common/autoconf/jdk-options.m4 | 6 +- 3 files changed, 234 insertions(+), 246 deletions(-) diff --git a/common/autoconf/autogen.sh b/common/autoconf/autogen.sh index 64f11204678..6df1f557552 100644 --- a/common/autoconf/autogen.sh +++ b/common/autoconf/autogen.sh @@ -43,14 +43,24 @@ fi custom_hook=$custom_script_dir/custom-hook.m4 -if test "x`which autoconf 2> /dev/null`" = x; then +AUTOCONF=$(which autoconf 2> /dev/null); +AUTOCONF_267=$(which autoconf-2.67 2> /dev/null); + +echo "Autoconf found: ${AUTOCONF}" +echo "Autoconf-2.67 found: ${AUTOCONF_267}" + +if test "x${AUTOCONF}" = x; then echo You need autoconf installed to be able to regenerate the configure script echo Error: Cannot find autoconf 1>&2 exit 1 fi -echo Generating generated-configure.sh -cat $script_dir/configure.ac | sed -e "s|@DATE_WHEN_GENERATED@|$TIMESTAMP|" | autoconf -W all -I$script_dir - > $script_dir/generated-configure.sh +if test "x${AUTOCONF_267}" != x; then + AUTOCONF=${AUTOCONF_267}; +fi + +echo Generating generated-configure.sh with ${AUTOCONF} +cat $script_dir/configure.ac | sed -e "s|@DATE_WHEN_GENERATED@|$TIMESTAMP|" | ${AUTOCONF} -W all -I$script_dir - > $script_dir/generated-configure.sh rm -rf autom4te.cache if test -e $custom_hook; then @@ -58,7 +68,7 @@ if test -e $custom_hook; then # We have custom sources available; also generate configure script # with custom hooks compiled in. cat $script_dir/configure.ac | sed -e "s|@DATE_WHEN_GENERATED@|$TIMESTAMP|" | \ - sed -e "s|#CUSTOM_AUTOCONF_INCLUDE|m4_include([$custom_hook])|" | autoconf -W all -I$script_dir - > $custom_script_dir/generated-configure.sh + sed -e "s|#CUSTOM_AUTOCONF_INCLUDE|m4_include([$custom_hook])|" | ${AUTOCONF} -W all -I$script_dir - > $custom_script_dir/generated-configure.sh rm -rf autom4te.cache else echo No custom hook found: $custom_hook diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 4d9ec980421..394b541bbd2 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. # # Report bugs to . # @@ -91,7 +91,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -217,18 +216,11 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -1450,7 +1442,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac @@ -1882,7 +1874,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1928,7 +1920,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1966,7 +1958,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -2004,7 +1996,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2041,7 +2033,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2078,7 +2070,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2091,10 +2083,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2161,7 +2153,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2170,7 +2162,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_mongrel @@ -2211,7 +2203,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2225,7 +2217,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2243,7 +2235,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_compile @@ -2420,7 +2412,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2466,7 +2458,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2479,7 +2471,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2534,7 +2526,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_func @@ -2547,7 +2539,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2565,7 +2557,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2573,7 +2565,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -3753,7 +3745,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1363706268 +DATE_WHEN_GENERATED=1364562324 ############################################################################### # @@ -3791,7 +3783,7 @@ do 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_BASENAME+:} false; then : +if test "${ac_cv_path_BASENAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3850,7 +3842,7 @@ do 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_BASH+:} false; then : +if test "${ac_cv_path_BASH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3909,7 +3901,7 @@ do 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_CAT+:} false; then : +if test "${ac_cv_path_CAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -3968,7 +3960,7 @@ do 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_CHMOD+:} false; then : +if test "${ac_cv_path_CHMOD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -4027,7 +4019,7 @@ do 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_CMP+:} false; then : +if test "${ac_cv_path_CMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4086,7 +4078,7 @@ do 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_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4145,7 +4137,7 @@ do 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_CP+:} false; then : +if test "${ac_cv_path_CP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4204,7 +4196,7 @@ do 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_CPIO+:} false; then : +if test "${ac_cv_path_CPIO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4263,7 +4255,7 @@ do 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_CUT+:} false; then : +if test "${ac_cv_path_CUT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4322,7 +4314,7 @@ do 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_DATE+:} false; then : +if test "${ac_cv_path_DATE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4381,7 +4373,7 @@ do 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_DIFF+:} false; then : +if test "${ac_cv_path_DIFF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4440,7 +4432,7 @@ do 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_DIRNAME+:} false; then : +if test "${ac_cv_path_DIRNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4499,7 +4491,7 @@ do 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_ECHO+:} false; then : +if test "${ac_cv_path_ECHO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4558,7 +4550,7 @@ do 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_EXPR+:} false; then : +if test "${ac_cv_path_EXPR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4617,7 +4609,7 @@ do 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_FILE+:} false; then : +if test "${ac_cv_path_FILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4676,7 +4668,7 @@ do 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_FIND+:} false; then : +if test "${ac_cv_path_FIND+set}" = set; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4735,7 +4727,7 @@ do 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_HEAD+:} false; then : +if test "${ac_cv_path_HEAD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4794,7 +4786,7 @@ do 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_LN+:} false; then : +if test "${ac_cv_path_LN+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4853,7 +4845,7 @@ do 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_LS+:} false; then : +if test "${ac_cv_path_LS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4912,7 +4904,7 @@ do 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_MKDIR+:} false; then : +if test "${ac_cv_path_MKDIR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -4971,7 +4963,7 @@ do 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_MKTEMP+:} false; then : +if test "${ac_cv_path_MKTEMP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -5030,7 +5022,7 @@ do 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_MV+:} false; then : +if test "${ac_cv_path_MV+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5089,7 +5081,7 @@ do 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_PRINTF+:} false; then : +if test "${ac_cv_path_PRINTF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5148,7 +5140,7 @@ do 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_THEPWDCMD+:} false; then : +if test "${ac_cv_path_THEPWDCMD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $THEPWDCMD in @@ -5207,7 +5199,7 @@ do 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_RM+:} false; then : +if test "${ac_cv_path_RM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5266,7 +5258,7 @@ do 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_SH+:} false; then : +if test "${ac_cv_path_SH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5325,7 +5317,7 @@ do 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_SORT+:} false; then : +if test "${ac_cv_path_SORT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5384,7 +5376,7 @@ do 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_TAIL+:} false; then : +if test "${ac_cv_path_TAIL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5443,7 +5435,7 @@ do 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_TAR+:} false; then : +if test "${ac_cv_path_TAR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5502,7 +5494,7 @@ do 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_TEE+:} false; then : +if test "${ac_cv_path_TEE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5561,7 +5553,7 @@ do 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_TOUCH+:} false; then : +if test "${ac_cv_path_TOUCH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5620,7 +5612,7 @@ do 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_TR+:} false; then : +if test "${ac_cv_path_TR+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5679,7 +5671,7 @@ do 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_UNAME+:} false; then : +if test "${ac_cv_path_UNAME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5738,7 +5730,7 @@ do 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_UNIQ+:} false; then : +if test "${ac_cv_path_UNIQ+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5797,7 +5789,7 @@ do 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_WC+:} false; then : +if test "${ac_cv_path_WC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5856,7 +5848,7 @@ do 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_WHICH+:} false; then : +if test "${ac_cv_path_WHICH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5915,7 +5907,7 @@ do 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_XARGS+:} false; then : +if test "${ac_cv_path_XARGS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5975,7 +5967,7 @@ do 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_prog_AWK+:} false; then : +if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -6025,7 +6017,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : +if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6100,7 +6092,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : +if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6179,7 +6171,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : +if test "${ac_cv_path_FGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6258,7 +6250,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : +if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6344,7 +6336,7 @@ do 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_NAWK+:} false; then : +if test "${ac_cv_path_NAWK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6404,7 +6396,7 @@ RM="$RM -f" set dummy cygpath; 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_CYGPATH+:} false; then : +if test "${ac_cv_path_CYGPATH+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6444,7 +6436,7 @@ fi set dummy readlink; 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_READLINK+:} false; then : +if test "${ac_cv_path_READLINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6484,7 +6476,7 @@ fi set dummy df; 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_DF+:} false; then : +if test "${ac_cv_path_DF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6524,7 +6516,7 @@ fi set dummy SetFile; 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_SETFILE+:} false; then : +if test "${ac_cv_path_SETFILE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6570,7 +6562,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : +if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6604,7 +6596,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : +if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6637,7 +6629,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : +if test "${ac_cv_target+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -8118,7 +8110,7 @@ do 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_prog_PKGHANDLER+:} false; then : +if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8483,7 +8475,7 @@ do 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_CHECK_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8837,7 +8829,7 @@ do 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_CHECK_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9196,7 +9188,7 @@ do 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_CHECK_TOOLSDIR_GMAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9549,7 +9541,7 @@ do 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_CHECK_TOOLSDIR_MAKE+:} false; then : +if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9945,7 +9937,7 @@ do 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_UNZIP+:} false; then : +if test "${ac_cv_path_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -10004,7 +9996,7 @@ do 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_ZIP+:} false; then : +if test "${ac_cv_path_ZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -10063,7 +10055,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; 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_LDD+:} false; then : +if test "${ac_cv_path_LDD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -10109,7 +10101,7 @@ fi set dummy otool; 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_OTOOL+:} false; then : +if test "${ac_cv_path_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10154,7 +10146,7 @@ do 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_READELF+:} false; then : +if test "${ac_cv_path_READELF+set}" = set; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10197,7 +10189,7 @@ done set dummy hg; 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_HG+:} false; then : +if test "${ac_cv_path_HG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10237,7 +10229,7 @@ fi set dummy stat; 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_STAT+:} false; then : +if test "${ac_cv_path_STAT+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10277,7 +10269,7 @@ fi set dummy time; 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_TIME+:} false; then : +if test "${ac_cv_path_TIME+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10322,7 +10314,7 @@ do 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_COMM+:} false; then : +if test "${ac_cv_path_COMM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10386,7 +10378,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; 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_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10429,7 +10421,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; 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_ac_pt_PKG_CONFIG+:} false; then : +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10602,7 +10594,7 @@ do 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_prog_BDEPS_UNZIP+:} false; then : +if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10648,7 +10640,7 @@ do 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_prog_BDEPS_FTP+:} false; then : +if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -11921,7 +11913,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; 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_JAVAC_CHECK+:} false; then : +if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -11961,7 +11953,7 @@ fi set dummy java; 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_JAVA_CHECK+:} false; then : +if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -16035,7 +16027,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; 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_CYGWIN_LINK+:} false; then : +if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -17450,7 +17442,7 @@ do 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_BUILD_CC+:} false; then : +if test "${ac_cv_path_BUILD_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -17761,7 +17753,7 @@ do 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_BUILD_CXX+:} false; then : +if test "${ac_cv_path_BUILD_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -18070,7 +18062,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; 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_BUILD_LD+:} false; then : +if test "${ac_cv_path_BUILD_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -18586,7 +18578,7 @@ do 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_TOOLS_DIR_CC+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -18638,7 +18630,7 @@ do 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_POTENTIAL_CC+:} false; then : +if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -19051,7 +19043,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$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_prog_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -19095,7 +19087,7 @@ do 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_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -19545,7 +19537,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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_prog_CC+:} false; then : +if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -19589,7 +19581,7 @@ do 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_prog_ac_ct_CC+:} false; then : +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -19870,7 +19862,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : +if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19921,7 +19913,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : +if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19958,7 +19950,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : +if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -20036,7 +20028,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : +if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -20159,7 +20151,7 @@ do 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_TOOLS_DIR_CXX+:} false; then : +if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -20211,7 +20203,7 @@ do 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_POTENTIAL_CXX+:} false; then : +if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -20624,7 +20616,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$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_prog_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -20668,7 +20660,7 @@ do 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_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -21122,7 +21114,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$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_prog_CXX+:} false; then : +if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -21166,7 +21158,7 @@ do 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_prog_ac_ct_CXX+:} false; then : +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -21244,7 +21236,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21281,7 +21273,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : +if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -21379,7 +21371,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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_prog_OBJC+:} false; then : +if test "${ac_cv_prog_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -21423,7 +21415,7 @@ do 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_prog_ac_ct_OBJC+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -21499,7 +21491,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if ${ac_cv_objc_compiler_gnu+:} false; then : +if test "${ac_cv_objc_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21536,7 +21528,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if ${ac_cv_prog_objc_g+:} false; then : +if test "${ac_cv_prog_objc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -21912,7 +21904,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; 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_prog_AR+:} false; then : +if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -21952,7 +21944,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; 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_prog_ac_ct_AR+:} false; then : +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -22294,7 +22286,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; 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_prog_WINLD+:} false; then : +if test "${ac_cv_prog_WINLD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -22633,7 +22625,7 @@ $as_echo "yes" >&6; } set dummy mt; 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_prog_MT+:} false; then : +if test "${ac_cv_prog_MT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -22954,7 +22946,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; 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_prog_RC+:} false; then : +if test "${ac_cv_prog_RC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -23345,7 +23337,7 @@ fi set dummy lib; 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_prog_WINAR+:} false; then : +if test "${ac_cv_prog_WINAR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -23651,7 +23643,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; 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_prog_DUMPBIN+:} false; then : +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -23970,7 +23962,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : + if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -24370,7 +24362,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : + if test "${ac_cv_prog_CXXCPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -24788,7 +24780,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; 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_AS+:} false; then : +if test "${ac_cv_path_AS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -25102,7 +25094,7 @@ do 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_NM+:} false; then : +if test "${ac_cv_path_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -25411,7 +25403,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy strip; 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_STRIP+:} false; then : +if test "${ac_cv_path_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -25717,7 +25709,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; 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_MCS+:} false; then : +if test "${ac_cv_path_MCS+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -26025,7 +26017,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; 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_prog_NM+:} false; then : +if test "${ac_cv_prog_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -26065,7 +26057,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; 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_prog_ac_ct_NM+:} false; then : +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -26383,7 +26375,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; 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_prog_STRIP+:} false; then : +if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -26423,7 +26415,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; 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_prog_ac_ct_STRIP+:} false; then : +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -26748,7 +26740,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$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_prog_OBJCOPY+:} false; then : +if test "${ac_cv_prog_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -26792,7 +26784,7 @@ do 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_prog_ac_ct_OBJCOPY+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -27119,7 +27111,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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_prog_OBJDUMP+:} false; then : +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -27163,7 +27155,7 @@ do 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_prog_ac_ct_OBJDUMP+:} false; then : +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -27487,7 +27479,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; 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_LIPO+:} false; then : +if test "${ac_cv_path_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -27802,7 +27794,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : +if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -27978,7 +27970,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = xyes; then : +if test "x$ac_cv_header_stdio_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -28007,7 +27999,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if ${ac_cv_sizeof_int_p+:} false; then : +if test "${ac_cv_sizeof_int_p+set}" = set; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -28064,7 +28056,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : +if test "${ac_cv_c_bigendian+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -28903,14 +28895,15 @@ $as_echo "$ENABLE_DEBUG_SYMBOLS" >&6; } # # ZIP_DEBUGINFO_FILES # -# Check whether --enable-zip-debug-info was given. -if test "${enable_zip_debug_info+set}" = set; then : - enableval=$enable_zip_debug_info; -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should zip debug-info files" >&5 $as_echo_n "checking if we should zip debug-info files... " >&6; } +# Check whether --enable-zip-debug-info was given. +if test "${enable_zip_debug_info+set}" = set; then : + enableval=$enable_zip_debug_info; enable_zip_debug_info="${enableval}" +else + enable_zip_debug_info="yes" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_zip_debug_info}" >&5 $as_echo "${enable_zip_debug_info}" >&6; } @@ -29076,7 +29069,7 @@ if test "x$with_x" = xno; then else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -29353,7 +29346,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29387,14 +29380,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29428,7 +29421,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -29447,14 +29440,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "x$ac_cv_func_gethostbyname" = x""yes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29488,14 +29481,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29529,7 +29522,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -29544,14 +29537,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +if test "x$ac_cv_func_connect" = x""yes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : +if test "${ac_cv_lib_socket_connect+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29585,7 +29578,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : +if test "x$ac_cv_lib_socket_connect" = x""yes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -29593,14 +29586,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : +if test "x$ac_cv_func_remove" = x""yes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : +if test "${ac_cv_lib_posix_remove+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29634,7 +29627,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : +if test "x$ac_cv_lib_posix_remove" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -29642,14 +29635,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +if test "x$ac_cv_func_shmat" = x""yes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : +if test "${ac_cv_lib_ipc_shmat+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29683,7 +29676,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -29701,7 +29694,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29735,7 +29728,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -30748,7 +30741,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : +if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30782,7 +30775,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -31070,7 +31063,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -31129,7 +31122,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if ${ac_cv_lib_jpeg_main+:} false; then : +if test "${ac_cv_lib_jpeg_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31157,7 +31150,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = xyes; then : +if test "x$ac_cv_lib_jpeg_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -31181,7 +31174,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5 $as_echo_n "checking for main in -lgif... " >&6; } -if ${ac_cv_lib_gif_main+:} false; then : +if test "${ac_cv_lib_gif_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31209,7 +31202,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5 $as_echo "$ac_cv_lib_gif_main" >&6; } -if test "x$ac_cv_lib_gif_main" = xyes; then : +if test "x$ac_cv_lib_gif_main" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -31239,7 +31232,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if ${ac_cv_lib_z_compress+:} false; then : +if test "${ac_cv_lib_z_compress+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31273,7 +31266,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = xyes; then : +if test "x$ac_cv_lib_z_compress" = x""yes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -31366,7 +31359,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : +if test "${ac_cv_lib_m_cos+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31400,7 +31393,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : +if test "x$ac_cv_lib_m_cos" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -31424,7 +31417,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31458,7 +31451,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -32148,7 +32141,7 @@ fi set dummy ccache; 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_CCACHE+:} false; then : +if test "${ac_cv_path_CCACHE+set}" = set; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -32409,21 +32402,10 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then + test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi + cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -32455,7 +32437,7 @@ LTLIBOBJS=$ac_ltlibobjs -: "${CONFIG_STATUS=./config.status}" +: ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -32556,7 +32538,6 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. -as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -32864,7 +32845,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -32927,7 +32908,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -33078,10 +33059,9 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= ac_tmp= + tmp= trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -33089,13 +33069,12 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" + test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -33117,7 +33096,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF @@ -33145,7 +33124,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -33193,7 +33172,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -33225,7 +33204,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -33259,7 +33238,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || +cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -33271,8 +33250,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -33392,7 +33371,7 @@ do for ac_f do case $ac_f in - -) ac_f="$ac_tmp/stdin";; + -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -33427,7 +33406,7 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ + *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; @@ -33553,22 +33532,21 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$ac_tmp/stdin" + rm -f "$tmp/stdin" case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -33579,20 +33557,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ + mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index d3d55e52952..7e286036c51 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -519,10 +519,10 @@ AC_MSG_RESULT([$ENABLE_DEBUG_SYMBOLS]) # # ZIP_DEBUGINFO_FILES # -AC_ARG_ENABLE([zip-debug-info], - [AS_HELP_STRING([--disable-zip-debug-info],[disable zipping of debug-info files @<:@enabled@:>@])]) - AC_MSG_CHECKING([if we should zip debug-info files]) +AC_ARG_ENABLE([zip-debug-info], + [AS_HELP_STRING([--disable-zip-debug-info],[disable zipping of debug-info files @<:@enabled@:>@])], + [enable_zip_debug_info="${enableval}"], [enable_zip_debug_info="yes"]) AC_MSG_RESULT([${enable_zip_debug_info}]) if test "x${enable_zip_debug_info}" = "xno"; then From b34573420a884ee78549bef2f08eabe5c0b2efab Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Tue, 2 Apr 2013 14:13:06 -0400 Subject: [PATCH 134/137] 8011278: Allow using a system-installed giflib Reviewed-by: andrew, prr --- common/autoconf/generated-configure.sh | 514 ++++++++++++++----------- common/autoconf/libraries.m4 | 35 +- 2 files changed, 321 insertions(+), 228 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 394b541bbd2..2293c92d133 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. # # Report bugs to . # @@ -91,6 +91,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -216,11 +217,18 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -1005,6 +1013,7 @@ with_freetype with_alsa with_alsa_include with_alsa_lib +with_giflib with_zlib with_stdc__lib with_num_cores @@ -1442,7 +1451,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1763,6 +1772,8 @@ Optional Packages: headers under PATH/include) --with-alsa-include specify directory for the alsa include files --with-alsa-lib specify directory for the alsa library + --with-giflib use giflib from build system or OpenJDK source + (system, bundled) [bundled] --with-zlib use zlib from build system or OpenJDK source (system, bundled) [bundled] --with-stdc++lib=,, @@ -1874,7 +1885,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.67 +generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1920,7 +1931,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1958,7 +1969,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -1996,7 +2007,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2033,7 +2044,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2070,7 +2081,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2083,10 +2094,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2153,7 +2164,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2162,7 +2173,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel @@ -2203,7 +2214,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2217,7 +2228,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2235,7 +2246,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile @@ -2412,7 +2423,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2458,7 +2469,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2471,7 +2482,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2526,7 +2537,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func @@ -2539,7 +2550,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2557,7 +2568,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2565,7 +2576,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3745,7 +3756,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1364562324 +DATE_WHEN_GENERATED=1364922883 ############################################################################### # @@ -3783,7 +3794,7 @@ do 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 test "${ac_cv_path_BASENAME+set}" = set; then : +if ${ac_cv_path_BASENAME+:} false; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3842,7 +3853,7 @@ do 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 test "${ac_cv_path_BASH+set}" = set; then : +if ${ac_cv_path_BASH+:} false; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3901,7 +3912,7 @@ do 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 test "${ac_cv_path_CAT+set}" = set; then : +if ${ac_cv_path_CAT+:} false; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -3960,7 +3971,7 @@ do 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 test "${ac_cv_path_CHMOD+set}" = set; then : +if ${ac_cv_path_CHMOD+:} false; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -4019,7 +4030,7 @@ do 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 test "${ac_cv_path_CMP+set}" = set; then : +if ${ac_cv_path_CMP+:} false; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4078,7 +4089,7 @@ do 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 test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4137,7 +4148,7 @@ do 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 test "${ac_cv_path_CP+set}" = set; then : +if ${ac_cv_path_CP+:} false; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4196,7 +4207,7 @@ do 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 test "${ac_cv_path_CPIO+set}" = set; then : +if ${ac_cv_path_CPIO+:} false; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4255,7 +4266,7 @@ do 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 test "${ac_cv_path_CUT+set}" = set; then : +if ${ac_cv_path_CUT+:} false; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4314,7 +4325,7 @@ do 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 test "${ac_cv_path_DATE+set}" = set; then : +if ${ac_cv_path_DATE+:} false; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4373,7 +4384,7 @@ do 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 test "${ac_cv_path_DIFF+set}" = set; then : +if ${ac_cv_path_DIFF+:} false; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4432,7 +4443,7 @@ do 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 test "${ac_cv_path_DIRNAME+set}" = set; then : +if ${ac_cv_path_DIRNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4491,7 +4502,7 @@ do 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 test "${ac_cv_path_ECHO+set}" = set; then : +if ${ac_cv_path_ECHO+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4550,7 +4561,7 @@ do 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 test "${ac_cv_path_EXPR+set}" = set; then : +if ${ac_cv_path_EXPR+:} false; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4609,7 +4620,7 @@ do 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 test "${ac_cv_path_FILE+set}" = set; then : +if ${ac_cv_path_FILE+:} false; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4668,7 +4679,7 @@ do 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 test "${ac_cv_path_FIND+set}" = set; then : +if ${ac_cv_path_FIND+:} false; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4727,7 +4738,7 @@ do 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 test "${ac_cv_path_HEAD+set}" = set; then : +if ${ac_cv_path_HEAD+:} false; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4786,7 +4797,7 @@ do 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 test "${ac_cv_path_LN+set}" = set; then : +if ${ac_cv_path_LN+:} false; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4845,7 +4856,7 @@ do 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 test "${ac_cv_path_LS+set}" = set; then : +if ${ac_cv_path_LS+:} false; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4904,7 +4915,7 @@ do 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 test "${ac_cv_path_MKDIR+set}" = set; then : +if ${ac_cv_path_MKDIR+:} false; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -4963,7 +4974,7 @@ do 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 test "${ac_cv_path_MKTEMP+set}" = set; then : +if ${ac_cv_path_MKTEMP+:} false; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -5022,7 +5033,7 @@ do 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 test "${ac_cv_path_MV+set}" = set; then : +if ${ac_cv_path_MV+:} false; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5081,7 +5092,7 @@ do 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 test "${ac_cv_path_PRINTF+set}" = set; then : +if ${ac_cv_path_PRINTF+:} false; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5140,7 +5151,7 @@ do 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 test "${ac_cv_path_THEPWDCMD+set}" = set; then : +if ${ac_cv_path_THEPWDCMD+:} false; then : $as_echo_n "(cached) " >&6 else case $THEPWDCMD in @@ -5199,7 +5210,7 @@ do 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 test "${ac_cv_path_RM+set}" = set; then : +if ${ac_cv_path_RM+:} false; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5258,7 +5269,7 @@ do 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 test "${ac_cv_path_SH+set}" = set; then : +if ${ac_cv_path_SH+:} false; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5317,7 +5328,7 @@ do 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 test "${ac_cv_path_SORT+set}" = set; then : +if ${ac_cv_path_SORT+:} false; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5376,7 +5387,7 @@ do 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 test "${ac_cv_path_TAIL+set}" = set; then : +if ${ac_cv_path_TAIL+:} false; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5435,7 +5446,7 @@ do 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 test "${ac_cv_path_TAR+set}" = set; then : +if ${ac_cv_path_TAR+:} false; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5494,7 +5505,7 @@ do 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 test "${ac_cv_path_TEE+set}" = set; then : +if ${ac_cv_path_TEE+:} false; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5553,7 +5564,7 @@ do 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 test "${ac_cv_path_TOUCH+set}" = set; then : +if ${ac_cv_path_TOUCH+:} false; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5612,7 +5623,7 @@ do 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 test "${ac_cv_path_TR+set}" = set; then : +if ${ac_cv_path_TR+:} false; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5671,7 +5682,7 @@ do 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 test "${ac_cv_path_UNAME+set}" = set; then : +if ${ac_cv_path_UNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5730,7 +5741,7 @@ do 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 test "${ac_cv_path_UNIQ+set}" = set; then : +if ${ac_cv_path_UNIQ+:} false; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5789,7 +5800,7 @@ do 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 test "${ac_cv_path_WC+set}" = set; then : +if ${ac_cv_path_WC+:} false; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5848,7 +5859,7 @@ do 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 test "${ac_cv_path_WHICH+set}" = set; then : +if ${ac_cv_path_WHICH+:} false; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5907,7 +5918,7 @@ do 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 test "${ac_cv_path_XARGS+set}" = set; then : +if ${ac_cv_path_XARGS+:} false; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5967,7 +5978,7 @@ do 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 test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -6017,7 +6028,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6092,7 +6103,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6171,7 +6182,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6250,7 +6261,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6336,7 +6347,7 @@ do 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 test "${ac_cv_path_NAWK+set}" = set; then : +if ${ac_cv_path_NAWK+:} false; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6396,7 +6407,7 @@ RM="$RM -f" set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGPATH+set}" = set; then : +if ${ac_cv_path_CYGPATH+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6436,7 +6447,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_READLINK+set}" = set; then : +if ${ac_cv_path_READLINK+:} false; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6476,7 +6487,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DF+set}" = set; then : +if ${ac_cv_path_DF+:} false; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6516,7 +6527,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SETFILE+set}" = set; then : +if ${ac_cv_path_SETFILE+:} false; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6562,7 +6573,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6596,7 +6607,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6629,7 +6640,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if test "${ac_cv_target+set}" = set; then : +if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -8110,7 +8121,7 @@ do 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 test "${ac_cv_prog_PKGHANDLER+set}" = set; then : +if ${ac_cv_prog_PKGHANDLER+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8475,7 +8486,7 @@ do 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 test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8829,7 +8840,7 @@ do 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 test "${ac_cv_path_CHECK_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9188,7 +9199,7 @@ do 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 test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9541,7 +9552,7 @@ do 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 test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9937,7 +9948,7 @@ do 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 test "${ac_cv_path_UNZIP+set}" = set; then : +if ${ac_cv_path_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -9996,7 +10007,7 @@ do 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 test "${ac_cv_path_ZIP+set}" = set; then : +if ${ac_cv_path_ZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -10055,7 +10066,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LDD+set}" = set; then : +if ${ac_cv_path_LDD+:} false; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -10101,7 +10112,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_OTOOL+set}" = set; then : +if ${ac_cv_path_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10146,7 +10157,7 @@ do 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 test "${ac_cv_path_READELF+set}" = set; then : +if ${ac_cv_path_READELF+:} false; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10189,7 +10200,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_HG+set}" = set; then : +if ${ac_cv_path_HG+:} false; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10229,7 +10240,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STAT+set}" = set; then : +if ${ac_cv_path_STAT+:} false; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10269,7 +10280,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TIME+set}" = set; then : +if ${ac_cv_path_TIME+:} false; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10314,7 +10325,7 @@ do 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 test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10378,7 +10389,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10421,7 +10432,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10594,7 +10605,7 @@ do 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 test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : +if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10640,7 +10651,7 @@ do 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 test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : +if ${ac_cv_prog_BDEPS_FTP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -11913,7 +11924,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : +if ${ac_cv_path_JAVAC_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -11953,7 +11964,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : +if ${ac_cv_path_JAVA_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -16027,7 +16038,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : +if ${ac_cv_path_CYGWIN_LINK+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -17442,7 +17453,7 @@ do 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 test "${ac_cv_path_BUILD_CC+set}" = set; then : +if ${ac_cv_path_BUILD_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -17753,7 +17764,7 @@ do 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 test "${ac_cv_path_BUILD_CXX+set}" = set; then : +if ${ac_cv_path_BUILD_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -18062,7 +18073,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_LD+set}" = set; then : +if ${ac_cv_path_BUILD_LD+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -18578,7 +18589,7 @@ do 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 test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -18630,7 +18641,7 @@ do 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 test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -19043,7 +19054,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$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 test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -19087,7 +19098,7 @@ do 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 test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -19537,7 +19548,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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 test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -19581,7 +19592,7 @@ do 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 test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -19862,7 +19873,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19913,7 +19924,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19950,7 +19961,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -20028,7 +20039,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -20151,7 +20162,7 @@ do 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 test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -20203,7 +20214,7 @@ do 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 test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -20616,7 +20627,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$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 test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -20660,7 +20671,7 @@ do 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 test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -21114,7 +21125,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$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 test "${ac_cv_prog_CXX+set}" = set; then : +if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -21158,7 +21169,7 @@ do 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 test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -21236,7 +21247,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21273,7 +21284,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then : +if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -21371,7 +21382,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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 test "${ac_cv_prog_OBJC+set}" = set; then : +if ${ac_cv_prog_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -21415,7 +21426,7 @@ do 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 test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -21491,7 +21502,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if test "${ac_cv_objc_compiler_gnu+set}" = set; then : +if ${ac_cv_objc_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21528,7 +21539,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if test "${ac_cv_prog_objc_g+set}" = set; then : +if ${ac_cv_prog_objc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -21904,7 +21915,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -21944,7 +21955,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -22286,7 +22297,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINLD+set}" = set; then : +if ${ac_cv_prog_WINLD+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -22625,7 +22636,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_MT+set}" = set; then : +if ${ac_cv_prog_MT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -22946,7 +22957,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RC+set}" = set; then : +if ${ac_cv_prog_RC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -23337,7 +23348,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINAR+set}" = set; then : +if ${ac_cv_prog_WINAR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -23643,7 +23654,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -23962,7 +23973,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -24362,7 +24373,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then : + if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -24780,7 +24791,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_AS+set}" = set; then : +if ${ac_cv_path_AS+:} false; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -25094,7 +25105,7 @@ do 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 test "${ac_cv_path_NM+set}" = set; then : +if ${ac_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -25403,7 +25414,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STRIP+set}" = set; then : +if ${ac_cv_path_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -25709,7 +25720,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MCS+set}" = set; then : +if ${ac_cv_path_MCS+:} false; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -26017,7 +26028,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NM+set}" = set; then : +if ${ac_cv_prog_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -26057,7 +26068,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : +if ${ac_cv_prog_ac_ct_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -26375,7 +26386,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -26415,7 +26426,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -26740,7 +26751,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$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 test "${ac_cv_prog_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -26784,7 +26795,7 @@ do 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 test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -27111,7 +27122,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$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 test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -27155,7 +27166,7 @@ do 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 test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -27479,7 +27490,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LIPO+set}" = set; then : +if ${ac_cv_path_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -27794,7 +27805,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -27970,7 +27981,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = x""yes; then : +if test "x$ac_cv_header_stdio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -27999,7 +28010,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if test "${ac_cv_sizeof_int_p+set}" = set; then : +if ${ac_cv_sizeof_int_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -28056,7 +28067,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if test "${ac_cv_c_bigendian+set}" = set; then : +if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -29069,7 +29080,7 @@ if test "x$with_x" = xno; then else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -29346,7 +29357,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29380,14 +29391,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29421,7 +29432,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -29440,14 +29451,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = x""yes; then : +if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29481,14 +29492,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : +if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29522,7 +29533,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -29537,14 +29548,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = x""yes; then : +if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if test "${ac_cv_lib_socket_connect+set}" = set; then : +if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29578,7 +29589,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = x""yes; then : +if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -29586,14 +29597,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = x""yes; then : +if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if test "${ac_cv_lib_posix_remove+set}" = set; then : +if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29627,7 +29638,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = x""yes; then : +if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -29635,14 +29646,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = x""yes; then : +if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if test "${ac_cv_lib_ipc_shmat+set}" = set; then : +if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29676,7 +29687,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : +if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -29694,7 +29705,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : +if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -29728,7 +29739,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -30741,7 +30752,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : +if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30775,7 +30786,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -31063,7 +31074,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -31122,7 +31133,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if test "${ac_cv_lib_jpeg_main+set}" = set; then : +if ${ac_cv_lib_jpeg_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31150,7 +31161,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = x""yes; then : +if test "x$ac_cv_lib_jpeg_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -31171,10 +31182,44 @@ fi # Check for the gif library # -USE_EXTERNAL_LIBJPEG=true -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgif" >&5 -$as_echo_n "checking for main in -lgif... " >&6; } -if test "${ac_cv_lib_gif_main+set}" = set; then : + +# Check whether --with-giflib was given. +if test "${with_giflib+set}" = set; then : + withval=$with_giflib; +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for which giflib to use" >&5 +$as_echo_n "checking for which giflib to use... " >&6; } + +# default is bundled +DEFAULT_GIFLIB=bundled + +# +# if user didn't specify, use DEFAULT_GIFLIB +# +if test "x${with_giflib}" = "x"; then + with_giflib=${DEFAULT_GIFLIB} +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_giflib}" >&5 +$as_echo "${with_giflib}" >&6; } + +if test "x${with_giflib}" = "xbundled"; then + USE_EXTERNAL_LIBGIF=false +elif test "x${with_giflib}" = "xsystem"; then + ac_fn_cxx_check_header_mongrel "$LINENO" "gif_lib.h" "ac_cv_header_gif_lib_h" "$ac_includes_default" +if test "x$ac_cv_header_gif_lib_h" = xyes; then : + +else + as_fn_error $? "--with-giflib=system specified, but gif_lib.h not found!" "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DGifGetCode in -lgif" >&5 +$as_echo_n "checking for DGifGetCode in -lgif... " >&6; } +if ${ac_cv_lib_gif_DGifGetCode+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31182,27 +31227,33 @@ LIBS="-lgif $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char DGifGetCode (); int main () { -return main (); +return DGifGetCode (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_gif_main=yes + ac_cv_lib_gif_DGifGetCode=yes else - ac_cv_lib_gif_main=no + ac_cv_lib_gif_DGifGetCode=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_main" >&5 -$as_echo "$ac_cv_lib_gif_main" >&6; } -if test "x$ac_cv_lib_gif_main" = x""yes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_DGifGetCode" >&5 +$as_echo "$ac_cv_lib_gif_DGifGetCode" >&6; } +if test "x$ac_cv_lib_gif_DGifGetCode" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -31210,13 +31261,15 @@ _ACEOF LIBS="-lgif $LIBS" else - USE_EXTERNAL_LIBGIF=false - { $as_echo "$as_me:${as_lineno-$LINENO}: Will use gif decoder bundled with the OpenJDK source" >&5 -$as_echo "$as_me: Will use gif decoder bundled with the OpenJDK source" >&6;} - + as_fn_error $? "--with-giflib=system specified, but no giflib found!" "$LINENO" 5 fi + USE_EXTERNAL_LIBGIF=true +else + as_fn_error $? "Invalid value of --with-giflib: ${with_giflib}, use 'system' or 'bundled'" "$LINENO" 5 +fi + ############################################################################### # @@ -31232,7 +31285,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if test "${ac_cv_lib_z_compress+set}" = set; then : +if ${ac_cv_lib_z_compress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31266,7 +31319,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = x""yes; then : +if test "x$ac_cv_lib_z_compress" = xyes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -31359,7 +31412,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if test "${ac_cv_lib_m_cos+set}" = set; then : +if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31393,7 +31446,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = x""yes; then : +if test "x$ac_cv_lib_m_cos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -31417,7 +31470,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31451,7 +31504,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -32141,7 +32194,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CCACHE+set}" = set; then : +if ${ac_cv_path_CCACHE+:} false; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -32402,10 +32455,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -32437,7 +32501,7 @@ LTLIBOBJS=$ac_ltlibobjs -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -32538,6 +32602,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -32845,7 +32910,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -32908,7 +32973,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -33059,9 +33124,10 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -33069,12 +33135,13 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -33096,7 +33163,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -33124,7 +33191,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -33172,7 +33239,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -33204,7 +33271,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -33238,7 +33305,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -33250,8 +33317,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -33371,7 +33438,7 @@ do for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -33406,7 +33473,7 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ + *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; @@ -33532,21 +33599,22 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -33557,20 +33625,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ + mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4 index 6cc9d634b60..21c5a96f292 100644 --- a/common/autoconf/libraries.m4 +++ b/common/autoconf/libraries.m4 @@ -499,11 +499,36 @@ AC_SUBST(USE_EXTERNAL_LIBJPEG) # Check for the gif library # -USE_EXTERNAL_LIBJPEG=true -AC_CHECK_LIB(gif, main, [], - [ USE_EXTERNAL_LIBGIF=false - AC_MSG_NOTICE([Will use gif decoder bundled with the OpenJDK source]) - ]) +AC_ARG_WITH(giflib, [AS_HELP_STRING([--with-giflib], + [use giflib from build system or OpenJDK source (system, bundled) @<:@bundled@:>@])]) + + +AC_MSG_CHECKING([for which giflib to use]) + +# default is bundled +DEFAULT_GIFLIB=bundled + +# +# if user didn't specify, use DEFAULT_GIFLIB +# +if test "x${with_giflib}" = "x"; then + with_giflib=${DEFAULT_GIFLIB} +fi + +AC_MSG_RESULT(${with_giflib}) + +if test "x${with_giflib}" = "xbundled"; then + USE_EXTERNAL_LIBGIF=false +elif test "x${with_giflib}" = "xsystem"; then + AC_CHECK_HEADER(gif_lib.h, [], + [ AC_MSG_ERROR([--with-giflib=system specified, but gif_lib.h not found!])]) + AC_CHECK_LIB(gif, DGifGetCode, [], + [ AC_MSG_ERROR([--with-giflib=system specified, but no giflib found!])]) + + USE_EXTERNAL_LIBGIF=true +else + AC_MSG_ERROR([Invalid value of --with-giflib: ${with_giflib}, use 'system' or 'bundled']) +fi AC_SUBST(USE_EXTERNAL_LIBGIF) ############################################################################### From 934072f7742f90f1a6fe0eb0fd7877fbac06d51f Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Tue, 2 Apr 2013 14:13:13 -0400 Subject: [PATCH 135/137] 8011278: Allow using a system-installed giflib Reviewed-by: andrew, prr --- jdk/makefiles/CompileNativeLibraries.gmk | 13 +++++++++---- .../native/sun/awt/splashscreen/splashscreen_gif.c | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 4c5d8dab855..e8b8e1cbbe3 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -2387,18 +2387,23 @@ endif ifndef BUILD_HEADLESS_ONLY LIBSPLASHSCREEN_DIRS:=\ - $(JDK_TOPDIR)/src/share/native/sun/awt/giflib \ $(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)) @@ -2450,11 +2455,11 @@ $(eval $(call SetupNativeCompilation,LIBSPLASHSCREEN,\ EXCLUDE_FILES:=imageioJPEG.c jpegdecoder.c pngtest.c,\ LANG:=C,\ OPTIMIZATION:=LOW, \ - CFLAGS:=$(LIBSPLASHSCREEN_CFLAGS) $(CFLAGS_JDKLIB),\ + 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),\ + 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)\ diff --git a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gif.c b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gif.c index 3c2d0fac23e..1fc081e6d72 100644 --- a/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gif.c +++ b/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gif.c @@ -26,7 +26,7 @@ #include "splashscreen_impl.h" #include "splashscreen_gfx.h" -#include "../giflib/gif_lib.h" +#include #define GIF_TRANSPARENT 0x01 #define GIF_USER_INPUT 0x02 From 5bfab7cabf8d06dbc1f0629f6834ca400537155e Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 18:46:03 +0200 Subject: [PATCH 136/137] Added tag jdk8-b82 for changeset 5e8c55025644 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 8660489ff05..aee5d6a2d78 100644 --- a/.hgtags +++ b/.hgtags @@ -203,3 +203,4 @@ d17eb2e13e362085e866d46235314c50cc4661cc jdk8-b77 a1313a8d90d17d363a3b2a645dc4030ec204b168 jdk8-b79 3fa21fbf9be7e6b482af43aacb6a09acfa30bdb6 jdk8-b80 e41d716405b209d3eddef8bd4240cec2bd34dcca jdk8-b81 +5e8c55025644730385a6f8fa029ecdb2d2c98a07 jdk8-b82 From 916bf9b7c96766bfdb3aba67804e96d260709dc8 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 18:46:58 +0200 Subject: [PATCH 137/137] Added tag jdk8-b83 for changeset bcebd3fdefc9 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index aee5d6a2d78..95524f5c8df 100644 --- a/.hgtags +++ b/.hgtags @@ -204,3 +204,4 @@ a1313a8d90d17d363a3b2a645dc4030ec204b168 jdk8-b79 3fa21fbf9be7e6b482af43aacb6a09acfa30bdb6 jdk8-b80 e41d716405b209d3eddef8bd4240cec2bd34dcca jdk8-b81 5e8c55025644730385a6f8fa029ecdb2d2c98a07 jdk8-b82 +bcebd3fdefc91abb9d7fa0c5af6211b3f8720da6 jdk8-b83