# HG changeset patch # User Thomas Wuerthinger # Date 1433517128 -7200 # Node ID f60f7994c5a54ee8e247fe6aeb48073f5d8b75e3 # Parent 30b4de402a5881b177d8d0abb4c1140d67a6e4b8# Parent 2e850dbf82ae1b0bbd3719e2656135a5683bf9d4 Merge. diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/BitOpsTest.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCInstructionCounter.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java --- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Fri Jun 05 17:12:08 2015 +0200 @@ -26,6 +26,7 @@ import org.junit.*; +import com.oracle.graal.code.*; import com.oracle.graal.test.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.debug.*; @@ -67,8 +68,10 @@ InstalledCode code = codeCache.addMethod(method, compResult, null, null); for (DisassemblerProvider dis : Services.load(DisassemblerProvider.class)) { - String disasm = dis.disassemble(code); - Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0); + String disasm1 = dis.disassembleCompiledCode(codeCache, compResult); + Assert.assertTrue(compResult.toString(), disasm1 == null || disasm1.length() > 0); + String disasm2 = dis.disassembleInstalledCode(codeCache, compResult, code); + Assert.assertTrue(code.toString(), disasm2 == null || disasm2.length() > 0); } return code; } catch (Throwable e) { diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/overview.html diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AsmOptions.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.asm/src/com/oracle/graal/asm/NumUtil.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/overview.html diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java Fri Jun 05 17:12:08 2015 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.code; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.service.*; + +/** + * Interface providing capability for disassembling machine code. + */ +public interface DisassemblerProvider extends Service { + + /** + * Gets a textual disassembly of a given compilation result. + * + * @param codeCache the object used for code {@link CodeCacheProvider#addMethod code + * installation} + * @param compResult a compilation result + * @return a non-zero length string containing a disassembly of {@code compResult} or null it + * could not be disassembled + */ + default String disassembleCompiledCode(CodeCacheProvider codeCache, CompilationResult compResult) { + return null; + } + + /** + * Gets a textual disassembly of a given installed code. + * + * @param codeCache the object used for code {@link CodeCacheProvider#addMethod code + * installation} + * @param compResult a compiled code that was installed to produce {@code installedCode}. This + * will be null if not available. + * @param installedCode + * @return a non-zero length string containing a disassembly of {@code code} or null if + * {@code code} is {@link InstalledCode#isValid() invalid} or it could not be + * disassembled for some other reason + */ + default String disassembleInstalledCode(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) { + return null; + } + + /** + * Gets the name denoting the format of the disassmembly return by this object. + */ + String getName(); +} diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFile.java Fri Jun 05 17:12:08 2015 +0200 @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2009, 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. + * + * 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.oracle.graal.code; + +import java.io.*; +import java.util.*; +import java.util.regex.*; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.code.CompilationResult.CodeAnnotation; +import com.oracle.jvmci.code.CompilationResult.CodeComment; +import com.oracle.jvmci.code.CompilationResult.JumpTable; + +/** + * A HexCodeFile is a textual format for representing a chunk of machine code along with extra + * information that can be used to enhance a disassembly of the code. + * + * A pseudo grammar for a HexCodeFile is given below. + * + *
+ *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
+ *
+ *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
+ *
+ *     Platform ::= "Platform" ISA WordWidth
+ *
+ *     HexCode ::= "HexCode" StartAddress HexDigits
+ *
+ *     Comment ::= "Comment" Position String
+ *
+ *     OperandComment ::= "OperandComment" Position String
+ *
+ *     JumpTable ::= "JumpTable" Position EntrySize Low High
+ *
+ *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
+ *
+ *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
+ *
+ *     Delim := "<||@"
+ * 
+ * + * There must be exactly one HexCode and Platform part in a HexCodeFile. The length of HexDigits + * must be even as each pair of digits represents a single byte. + *

+ * Below is an example of a valid Code input: + * + *

+ *
+ *  Platform AMD64 64  <||@
+ *  HexCode 0 e8000000009090904883ec084889842410d0ffff48893c24e800000000488b3c24488bf0e8000000004883c408c3  <||@
+ *  Comment 24 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 1]
+ *              |0
+ *     locals:  |stack:0:a
+ *     stack:   |stack:0:a
+ *    <||@
+ *  OperandComment 24 {java.util.Locale.getDefault()}  <||@
+ *  Comment 36 frame-ref-map: +0 {0}
+ *  at java.lang.String.toLowerCase(String.java:2496) [bci: 4]
+ *              |0
+ *     locals:  |stack:0:a
+ *    <||@
+ *  OperandComment 36 {java.lang.String.toLowerCase(Locale)}  lt;||@
+ *
+ * 
+ */ +public class HexCodeFile { + + public static final String NEW_LINE = CodeUtil.NEW_LINE; + public static final String SECTION_DELIM = " <||@"; + public static final String COLUMN_END = " <|@"; + public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL); + public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL); + public static final Pattern OPERAND_COMMENT = COMMENT; + public static final Pattern JUMP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(-{0,1}\\d+)\\s+(-{0,1}\\d+)\\s*"); + public static final Pattern LOOKUP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"); + public static final Pattern HEX_CODE = Pattern.compile("(\\p{XDigit}+)(?:\\s+(\\p{XDigit}*))?"); + public static final Pattern PLATFORM = Pattern.compile("(\\S+)\\s+(\\S+)", Pattern.DOTALL); + + /** + * Delimiter placed before a HexCodeFile when embedded in a string/stream. + */ + public static final String EMBEDDED_HCF_OPEN = "<<> comments = new TreeMap<>(); + + /** + * Map from a machine code position to a comment for the operands of the instruction at the + * position. + */ + public final Map operandComments = new TreeMap<>(); + + public final byte[] code; + + public final ArrayList jumpTables = new ArrayList<>(); + + public final String isa; + + public final int wordWidth; + + public final long startAddress; + + public HexCodeFile(byte[] code, long startAddress, String isa, int wordWidth) { + this.code = code; + this.startAddress = startAddress; + this.isa = isa; + this.wordWidth = wordWidth; + } + + /** + * Parses a string in the format produced by {@link #toString()} to produce a + * {@link HexCodeFile} object. + */ + public static HexCodeFile parse(String input, int sourceOffset, String source, String sourceName) { + return new Parser(input, sourceOffset, source, sourceName).hcf; + } + + /** + * Formats this HexCodeFile as a string that can be parsed with + * {@link #parse(String, int, String, String)}. + */ + @Override + public String toString() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeTo(baos); + return baos.toString(); + } + + public String toEmbeddedString() { + return EMBEDDED_HCF_OPEN + NEW_LINE + toString() + EMBEDDED_HCF_CLOSE; + } + + public void writeTo(OutputStream out) { + PrintStream ps = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out); + ps.printf("Platform %s %d %s%n", isa, wordWidth, SECTION_DELIM); + ps.printf("HexCode %x %s %s%n", startAddress, HexCodeFile.hexCodeString(code), SECTION_DELIM); + + for (JumpTable table : jumpTables) { + ps.printf("JumpTable %d %d %d %d %s%n", table.position, table.entrySize, table.low, table.high, SECTION_DELIM); + } + + for (Map.Entry> e : comments.entrySet()) { + int pos = e.getKey(); + for (String comment : e.getValue()) { + ps.printf("Comment %d %s %s%n", pos, comment, SECTION_DELIM); + } + } + + for (Map.Entry e : operandComments.entrySet()) { + ps.printf("OperandComment %d %s %s%n", e.getKey(), e.getValue(), SECTION_DELIM); + } + ps.flush(); + } + + /** + * Formats a byte array as a string of hex digits. + */ + public static String hexCodeString(byte[] code) { + if (code == null) { + return ""; + } else { + StringBuilder sb = new StringBuilder(code.length * 2); + for (int b : code) { + String hex = Integer.toHexString(b & 0xff); + if (hex.length() == 1) { + sb.append('0'); + } + sb.append(hex); + } + return sb.toString(); + } + } + + /** + * Adds a comment to the list of comments for a given position. + */ + public void addComment(int pos, String comment) { + List list = comments.get(pos); + if (list == null) { + list = new ArrayList<>(); + comments.put(pos, list); + } + list.add(encodeString(comment)); + } + + /** + * Sets an operand comment for a given position. + * + * @return the previous operand comment for {@code pos} + */ + public String addOperandComment(int pos, String comment) { + return operandComments.put(pos, encodeString(comment)); + } + + /** + * Adds any jump tables, lookup tables or code comments from a list of code annotations. + */ + public static void addAnnotations(HexCodeFile hcf, List annotations) { + if (annotations == null || annotations.isEmpty()) { + return; + } + for (CodeAnnotation a : annotations) { + if (a instanceof JumpTable) { + JumpTable table = (JumpTable) a; + hcf.jumpTables.add(table); + } else if (a instanceof CodeComment) { + CodeComment comment = (CodeComment) a; + hcf.addComment(comment.position, comment.value); + } + } + } + + /** + * Modifies a string to mangle any substrings matching {@link #SECTION_DELIM} and + * {@link #COLUMN_END}. + */ + public static String encodeString(String input) { + int index; + String s = input; + while ((index = s.indexOf(SECTION_DELIM)) != -1) { + s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length()); + } + while ((index = s.indexOf(COLUMN_END)) != -1) { + s = s.substring(0, index) + " < @" + s.substring(index + COLUMN_END.length()); + } + return s; + } + + /** + * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()} and + * produce a {@link HexCodeFile} object. + */ + static class Parser { + + final String input; + final String inputSource; + String isa; + int wordWidth; + byte[] code; + long startAddress; + HexCodeFile hcf; + + Parser(String input, int sourceOffset, String source, String sourceName) { + this.input = input; + this.inputSource = sourceName; + parseSections(sourceOffset, source); + } + + void makeHCF() { + if (hcf == null) { + if (isa != null && wordWidth != 0 && code != null) { + hcf = new HexCodeFile(code, startAddress, isa, wordWidth); + } + } + } + + void checkHCF(String section, int offset) { + check(hcf != null, offset, section + " section must be after Platform and HexCode section"); + } + + void check(boolean condition, int offset, String message) { + if (!condition) { + error(offset, message); + } + } + + Error error(int offset, String message) { + throw new Error(errorMessage(offset, message)); + } + + void warning(int offset, String message) { + PrintStream err = System.err; + err.println("Warning: " + errorMessage(offset, message)); + } + + String errorMessage(int offset, String message) { + assert offset < input.length(); + InputPos inputPos = filePos(offset); + int lineEnd = input.indexOf(HexCodeFile.NEW_LINE, offset); + int lineStart = offset - inputPos.col; + String line = lineEnd == -1 ? input.substring(lineStart) : input.substring(lineStart, lineEnd); + return String.format("%s:%d: %s%n%s%n%" + (inputPos.col + 1) + "s", inputSource, inputPos.line, message, line, "^"); + } + + static class InputPos { + + final int line; + final int col; + + public InputPos(int line, int col) { + this.line = line; + this.col = col; + } + } + + InputPos filePos(int index) { + assert input != null; + int lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1; + + String l = input.substring(lineStart, lineStart + 10); + PrintStream out = System.out; + out.println("YYY" + input.substring(index, index + 10) + "..."); + out.println("XXX" + l + "..."); + + int pos = input.indexOf(HexCodeFile.NEW_LINE, 0); + int line = 1; + while (pos > 0 && pos < index) { + line++; + pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1); + } + return new InputPos(line, index - lineStart); + } + + void parseSections(int offset, String source) { + assert input.startsWith(source, offset); + int index = 0; + int endIndex = source.indexOf(SECTION_DELIM); + while (endIndex != -1) { + while (source.charAt(index) <= ' ') { + index++; + } + String section = source.substring(index, endIndex).trim(); + parseSection(offset + index, section); + index = endIndex + SECTION_DELIM.length(); + endIndex = source.indexOf(SECTION_DELIM, index); + } + } + + int parseInt(int offset, String value) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + throw error(offset, "Not a valid integer: " + value); + } + } + + void parseSection(int offset, String section) { + if (section.isEmpty()) { + return; + } + assert input.startsWith(section, offset); + Matcher m = HexCodeFile.SECTION.matcher(section); + check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION); + + String header = m.group(1); + String body = m.group(2); + int headerOffset = offset + m.start(1); + int bodyOffset = offset + m.start(2); + + if (header.equals("Platform")) { + check(isa == null, bodyOffset, "Duplicate Platform section found"); + m = HexCodeFile.PLATFORM.matcher(body); + check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM); + isa = m.group(1); + wordWidth = parseInt(bodyOffset + m.start(2), m.group(2)); + makeHCF(); + } else if (header.equals("HexCode")) { + check(code == null, bodyOffset, "Duplicate Code section found"); + m = HexCodeFile.HEX_CODE.matcher(body); + check(m.matches(), bodyOffset, "Code does not match pattern " + HexCodeFile.HEX_CODE); + String hexAddress = m.group(1); + startAddress = Long.valueOf(hexAddress, 16); + String hexCode = m.group(2); + if (hexCode == null) { + code = new byte[0]; + } else { + check((hexCode.length() % 2) == 0, bodyOffset, "Hex code length must be even"); + code = new byte[hexCode.length() / 2]; + for (int i = 0; i < code.length; i++) { + String hexByte = hexCode.substring(i * 2, (i + 1) * 2); + code[i] = (byte) Integer.parseInt(hexByte, 16); + } + } + makeHCF(); + } else if (header.equals("Comment")) { + checkHCF("Comment", headerOffset); + m = HexCodeFile.COMMENT.matcher(body); + check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + String comment = m.group(2); + hcf.addComment(pos, comment); + } else if (header.equals("OperandComment")) { + checkHCF("OperandComment", headerOffset); + m = HexCodeFile.OPERAND_COMMENT.matcher(body); + check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + String comment = m.group(2); + hcf.addOperandComment(pos, comment); + } else if (header.equals("JumpTable")) { + checkHCF("JumpTable", headerOffset); + m = HexCodeFile.JUMP_TABLE.matcher(body); + check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE); + int pos = parseInt(bodyOffset + m.start(1), m.group(1)); + int entrySize = parseInt(bodyOffset + m.start(2), m.group(2)); + int low = parseInt(bodyOffset + m.start(3), m.group(3)); + int high = parseInt(bodyOffset + m.start(4), m.group(4)); + hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize)); + } else { + error(offset, "Unknown section header: " + header); + } + } + } +} diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFileDisassemblerProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/HexCodeFileDisassemblerProvider.java Fri Jun 05 17:12:08 2015 +0200 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.oracle.graal.code; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.code.CodeUtil.DefaultRefMapFormatter; +import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; +import com.oracle.jvmci.code.CompilationResult.Call; +import com.oracle.jvmci.code.CompilationResult.DataPatch; +import com.oracle.jvmci.code.CompilationResult.Infopoint; +import com.oracle.jvmci.code.CompilationResult.Mark; +import com.oracle.jvmci.service.*; + +/** + * {@link HexCodeFile} based implementation of {@link DisassemblerProvider}. + */ +@ServiceProvider(DisassemblerProvider.class) +public class HexCodeFileDisassemblerProvider implements DisassemblerProvider { + + @Override + public String disassembleCompiledCode(CodeCacheProvider codeCache, CompilationResult compResult) { + assert compResult != null; + return disassemble(codeCache, compResult, null); + } + + public String getName() { + return "hcf"; + } + + @Override + public String disassembleInstalledCode(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) { + assert installedCode != null; + return installedCode.isValid() ? disassemble(codeCache, compResult, installedCode) : null; + } + + private static String disassemble(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) { + TargetDescription target = codeCache.getTarget(); + RegisterConfig regConfig = codeCache.getRegisterConfig(); + byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); + if (code == null) { + // Method was deoptimized/invalidated + return ""; + } + long start = installedCode == null ? 0L : installedCode.getStart(); + HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8); + if (compResult != null) { + HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); + addExceptionHandlersComment(compResult, hcf); + Register fp = regConfig.getFrameRegister(); + RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.arch, target.wordSize, fp, 0); + for (Infopoint infopoint : compResult.getInfopoints()) { + if (infopoint instanceof Call) { + Call call = (Call) infopoint; + if (call.debugInfo != null) { + hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString()); + } + addOperandComment(hcf, call.pcOffset, "{" + codeCache.getTargetName(call) + "}"); + } else { + if (infopoint.debugInfo != null) { + hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString()); + } + addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}"); + } + } + for (DataPatch site : compResult.getDataPatches()) { + hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}"); + } + for (Mark mark : compResult.getMarks()) { + hcf.addComment(mark.pcOffset, codeCache.getMarkName(mark)); + } + } + String hcfEmbeddedString = hcf.toEmbeddedString(); + return HexCodeFileDisTool.tryDisassemble(hcfEmbeddedString); + } + + private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) { + if (!compResult.getExceptionHandlers().isEmpty()) { + String nl = HexCodeFile.NEW_LINE; + StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl); + for (CompilationResult.ExceptionHandler e : compResult.getExceptionHandlers()) { + buf.append(" ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl); + hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]"); + hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]"); + } + hcf.addComment(0, buf.toString()); + } + } + + private static void addOperandComment(HexCodeFile hcf, int pos, String comment) { + String oldValue = hcf.addOperandComment(pos, comment); + assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue; + } + + /** + * Interface to the tool for disassembling an {@link HexCodeFile#toEmbeddedString() embedded} + * {@link HexCodeFile}. + */ + static class HexCodeFileDisTool { + static final Method processMethod; + static { + Method toolMethod = null; + try { + Class toolClass = Class.forName("com.oracle.max.hcfdis.HexCodeFileDis", true, ClassLoader.getSystemClassLoader()); + toolMethod = toolClass.getDeclaredMethod("processEmbeddedString", String.class); + } catch (Exception e) { + // Tool not available on the class path + } + processMethod = toolMethod; + } + + public static String tryDisassemble(String hcfEmbeddedString) { + if (processMethod != null) { + try { + return (String) processMethod.invoke(null, hcfEmbeddedString); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // If the tool is available, for now let's be noisy when it fails + throw new InternalError(e); + } + } + return hcfEmbeddedString; + } + } + +} diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java Fri Jun 05 17:12:08 2015 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import com.oracle.graal.code.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; import com.oracle.jvmci.service.*; @@ -34,11 +35,20 @@ @ServiceProvider(DisassemblerProvider.class) public class HotSpotDisassemblerProvider implements DisassemblerProvider { - public String disassemble(InstalledCode code) { + public String disassembleCompiledCode(CodeCacheProvider codeCache, CompilationResult compResult) { + return null; + } + + @Override + public String disassembleInstalledCode(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode code) { if (code.isValid()) { long codeBlob = ((HotSpotInstalledCode) code).getAddress(); return runtime().getCompilerToVM().disassembleCodeBlob(codeBlob); } return null; } + + public String getName() { + return "hsdis"; + } } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Jun 05 17:12:08 2015 +0200 @@ -33,6 +33,8 @@ import com.oracle.jvmci.meta.ResolvedJavaMethod; import com.oracle.jvmci.meta.DeoptimizationAction; import com.oracle.jvmci.meta.ForeignCallDescriptor; + +import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.nodes.BeginLockScopeNode.*; import static com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode.*; import static com.oracle.graal.hotspot.nodes.EndLockScopeNode.*; @@ -135,6 +137,7 @@ // First check to see whether biasing is enabled for this object if (probability(NOT_FREQUENT_PROBABILITY, biasableLockBits.notEqual(Word.unsigned(biasedLockPattern())))) { // Biasing not enabled -> fall through to lightweight locking + unbiasable.inc(); } else { // The bias pattern is present in the object's mark word. Need to check // whether the bias owner and the epoch are both still current. @@ -148,6 +151,7 @@ if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) { // Object is already biased to current thread -> done traceObject(trace, "+lock{bias:existing}", object, true); + lockBiasExisting.inc(); return; } @@ -184,12 +188,14 @@ if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:acquired}", object, true); + lockBiasAcquired.inc(); return; } // If the biasing toward our thread failed, this means that another thread // owns the bias and we need to revoke that bias. The revocation will occur // in the interpreter runtime. traceObject(trace, "+lock{stub:revoke}", object, true); + lockStubRevoke.inc(); } else { // At this point we know the epoch has expired, meaning that the // current bias owner, if any, is actually invalid. Under these @@ -202,12 +208,14 @@ if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:transfer}", object, true); + lockBiasTransfer.inc(); return; } // If the biasing toward our thread failed, then another thread // succeeded in biasing it toward itself and we need to revoke that // bias. The revocation will occur in the runtime in the slow case. traceObject(trace, "+lock{stub:epoch-expired}", object, true); + lockStubEpochExpired.inc(); } monitorenterStubC(MONITORENTER, object, lock); return; @@ -229,6 +237,7 @@ if (ENABLE_BREAKPOINT) { bkpt(object, mark, tmp, result); } + revokeBias.inc(); } } } @@ -265,15 +274,18 @@ if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) { // Most likely not a recursive lock, go into a slow runtime call traceObject(trace, "+lock{stub:failed-cas}", object, true); + lockStubFailedCas.inc(); monitorenterStubC(MONITORENTER, object, lock); return; } else { // Recursively locked => write 0 to the lock slot lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION); - traceObject(trace, "+lock{recursive}", object, true); + traceObject(trace, "+lock{cas:recursive}", object, true); + lockCasRecursive.inc(); } } else { traceObject(trace, "+lock{cas}", object, true); + lockCas.inc(); } } @@ -310,6 +322,7 @@ endLockScope(); decCounter(); traceObject(trace, "-lock{bias}", object, false); + unlockBias.inc(); return; } } @@ -323,6 +336,7 @@ if (displacedMark.equal(0)) { // Recursive locking => done traceObject(trace, "-lock{recursive}", object, false); + unlockCasRecursive.inc(); } else { verifyOop(object); // Test if object's mark word is pointing to the displaced mark word, and if so, restore @@ -332,9 +346,11 @@ // The object's mark word was not pointing to the displaced header, // we do unlocking via runtime call. traceObject(trace, "-lock{stub}", object, false); + unlockStub.inc(); monitorexitStubC(MONITOREXIT, object, lock); } else { traceObject(trace, "-lock{cas}", object, false); + unlockCas.inc(); } } endLockScope(); @@ -543,4 +559,31 @@ @NodeIntrinsic(ForeignCallNode.class) private static native void monitorexitStubC(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object, Word lock); + /** + * Counters for the various paths for acquiring a lock. The counters whose names start with + * {@code "lock"} are mutually exclusive. The other counters are for paths that may be shared. + */ + private static final SnippetCounter.Group lockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorEnters") : null; + static final SnippetCounter lockBiasExisting = new SnippetCounter(lockCounters, "lock{bias:existing}", "bias-locked previously biased object"); + static final SnippetCounter lockBiasAcquired = new SnippetCounter(lockCounters, "lock{bias:acquired}", "bias-locked newly biased object"); + static final SnippetCounter lockBiasTransfer = new SnippetCounter(lockCounters, "lock{bias:transfer}", "bias-locked, biased transferred"); + static final SnippetCounter lockCas = new SnippetCounter(lockCounters, "lock{cas}", "cas-locked an object"); + static final SnippetCounter lockCasRecursive = new SnippetCounter(lockCounters, "lock{cas:recursive}", "cas-locked, recursive"); + static final SnippetCounter lockStubEpochExpired = new SnippetCounter(lockCounters, "lock{stub:epoch-expired}", "stub-locked, epoch expired"); + static final SnippetCounter lockStubRevoke = new SnippetCounter(lockCounters, "lock{stub:revoke}", "stub-locked, biased revoked"); + static final SnippetCounter lockStubFailedCas = new SnippetCounter(lockCounters, "lock{stub:failed-cas}", "stub-locked, failed cas"); + + static final SnippetCounter unbiasable = new SnippetCounter(lockCounters, "unbiasable", "object with unbiasable type"); + static final SnippetCounter revokeBias = new SnippetCounter(lockCounters, "revokeBias", "object had bias revoked"); + + /** + * Counters for the various paths for releasing a lock. The counters whose names start with + * {@code "unlock"} are mutually exclusive. The other counters are for paths that may be shared. + */ + private static final SnippetCounter.Group unlockCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("MonitorExits") : null; + static final SnippetCounter unlockBias = new SnippetCounter(unlockCounters, "unlock{bias}", "bias-unlocked an object"); + static final SnippetCounter unlockCas = new SnippetCounter(unlockCounters, "unlock{cas}", "cas-unlocked an object"); + static final SnippetCounter unlockCasRecursive = new SnippetCounter(unlockCounters, "unlock{cas:recursive}", "cas-unlocked an object, recursive"); + static final SnippetCounter unlockStub = new SnippetCounter(unlockCounters, "unlock{stub}", "stub-unlocked an object"); + } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Jun 05 17:12:08 2015 +0200 @@ -64,8 +64,6 @@ public static final class LabelOp extends LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LabelOp.class); - private static final Value[] NO_VALUES = new Value[0]; - /** * In the LIR, every register and variable must be defined before it is used. For method * parameters that are passed in fixed registers, exception objects passed to the exception @@ -83,7 +81,7 @@ super(TYPE); this.label = label; this.align = align; - this.incomingValues = NO_VALUES; + this.incomingValues = Value.NO_VALUES; } public void setIncomingValues(Value[] values) { @@ -101,7 +99,7 @@ } public void clearIncomingValues() { - incomingValues = NO_VALUES; + incomingValues = Value.NO_VALUES; } @Override @@ -130,8 +128,6 @@ public static class JumpOp extends LIRInstruction implements BlockEndOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(JumpOp.class); - private static final Value[] NO_VALUES = new Value[0]; - @Alive({REG, STACK, CONST}) private Value[] outgoingValues; private final LabelRef destination; @@ -143,7 +139,7 @@ protected JumpOp(LIRInstructionClass c, LabelRef destination) { super(c); this.destination = destination; - this.outgoingValues = NO_VALUES; + this.outgoingValues = Value.NO_VALUES; } public void setOutgoingValues(Value[] values) { @@ -161,7 +157,7 @@ } public void clearOutgoingValues() { - outgoingValues = NO_VALUES; + outgoingValues = Value.NO_VALUES; } @Override diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Jun 05 17:12:08 2015 +0200 @@ -25,6 +25,7 @@ import static com.oracle.jvmci.code.ValueUtil.*; import java.util.*; +import java.util.function.*; import com.oracle.graal.compiler.common.alloc.*; import com.oracle.graal.compiler.common.cfg.*; @@ -104,51 +105,203 @@ } } - private static final class LiveValueSet implements Iterable { - private static final Object MARKER = new Object(); + private static final class ValueSet { + private Value[] values; - private final HashMap map; - - public LiveValueSet() { - map = new HashMap<>(); + ValueSet() { + values = Value.NO_VALUES; } - public LiveValueSet(LiveValueSet s) { - map = new HashMap<>(s.map); + ValueSet(ValueSet other) { + int limit = other.values.length; + while (limit > 0) { + if (other.values[limit - 1] == null) { + limit--; + continue; + } + break; + } + values = new Value[limit]; + System.arraycopy(other.values, 0, values, 0, values.length); } - public void put(Value v) { - map.put(v, MARKER); + void put(int index, Value value) { + if (value != null && value.getLIRKind().isValue()) { + return; + } + if (values.length <= index) { + if (value == null) { + return; + } + Value[] newValues = new Value[index + 1]; + System.arraycopy(values, 0, newValues, 0, values.length); + values = newValues; + values[index] = value; + } else { + values[index] = value; + } } - public void putAll(LiveValueSet v) { - map.putAll(v.map); - } - - public void remove(Value v) { - map.remove(v); - } - - public Iterator iterator() { - return map.keySet().iterator(); + public void putAll(ValueSet stack) { + Value[] otherValues = stack.values; + int limit = otherValues.length; + if (limit > values.length) { + while (limit > 0) { + if (otherValues[limit - 1] == null) { + limit--; + continue; + } + break; + } + if (limit > values.length) { + Value[] newValues = new Value[limit]; + System.arraycopy(values, 0, newValues, 0, values.length); + values = newValues; + } + } + for (int i = 0; i < limit; i++) { + Value value = otherValues[i]; + if (value != null) { + values[i] = value; + } + } } @Override - public boolean equals(Object obj) { - if (obj instanceof LiveValueSet) { - return map.equals(((LiveValueSet) obj).map); - } else { - return false; + public boolean equals(Object other) { + if (other instanceof ValueSet) { + ValueSet that = (ValueSet) other; + int limit = Math.min(values.length, that.values.length); + for (int i = 0; i < limit; i++) { + if (!Objects.equals(values[i], that.values[i])) { + return false; + } + } + for (int i = limit; i < values.length; i++) { + if (values[i] != null) { + return false; + } + } + for (int i = limit; i < that.values.length; i++) { + if (that.values[i] != null) { + return false; + } + } + return true; + } + return false; + } + + public void addLiveValues(ReferenceMap refMap) { + for (Value v : values) { + if (v != null) { + refMap.addLiveValue(v); + } } } @Override public int hashCode() { - return map.hashCode(); + throw new UnsupportedOperationException(); } } private static final class Marker> { + + private final class LiveValueSet implements Consumer> { + + public void accept(AbstractBlockBase succ) { + putAll(liveInMap.get(succ)); + } + + private final ValueSet registers; + private final ValueSet stack; + private Set extraStack; + + public LiveValueSet() { + registers = new ValueSet(); + stack = new ValueSet(); + } + + public LiveValueSet(LiveValueSet s) { + registers = new ValueSet(s.registers); + stack = new ValueSet(s.stack); + if (s.extraStack != null) { + extraStack = new HashSet<>(s.extraStack); + } + } + + public void put(Value v) { + if (isRegister(v)) { + int index = asRegister(v).getReferenceMapIndex(); + registers.put(index, v); + } else if (isStackSlot(v)) { + int index = frameMap.offsetForStackSlot(asStackSlot(v)); + assert index >= 0; + if (index % 4 == 0) { + stack.put(index / 4, v); + } else { + if (extraStack == null) { + extraStack = new HashSet<>(); + } + extraStack.add(v); + } + } + } + + public void putAll(LiveValueSet v) { + registers.putAll(v.registers); + stack.putAll(v.stack); + if (v.extraStack != null) { + if (extraStack == null) { + extraStack = new HashSet<>(); + } + extraStack.addAll(v.extraStack); + } + } + + public void remove(Value v) { + if (isRegister(v)) { + int index = asRegister(v).getReferenceMapIndex(); + registers.put(index, null); + } else if (isStackSlot(v)) { + int index = frameMap.offsetForStackSlot(asStackSlot(v)); + assert index >= 0; + if (index % 4 == 0) { + stack.put(index / 4, null); + } else if (extraStack != null) { + extraStack.remove(v); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (obj instanceof Marker.LiveValueSet) { + LiveValueSet other = (LiveValueSet) obj; + return registers.equals(other.registers) && stack.equals(other.stack) && Objects.equals(extraStack, other.extraStack); + } else { + return false; + } + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } + + public void addLiveValues(ReferenceMap refMap) { + registers.addLiveValues(refMap); + stack.addLiveValues(refMap); + if (extraStack != null) { + for (Value v : extraStack) { + refMap.addLiveValue(v); + } + } + } + } + private final LIR lir; private final FrameMap frameMap; private final RegisterAttributes[] registerAttributes; @@ -181,9 +334,9 @@ /** * Merge outSet with in-set of successors. */ - private boolean updateOutBlock(AbstractBlockBase block) { + private boolean updateOutBlock(AbstractBlockBase block) { LiveValueSet union = new LiveValueSet(); - block.getSuccessors().forEach(succ -> union.putAll(liveInMap.get(succ))); + block.getSuccessors().forEach(union); LiveValueSet outSet = liveOutMap.get(block); // check if changed if (outSet == null || !union.equals(outSet)) { @@ -196,13 +349,14 @@ private void processBlock(AbstractBlockBase block, UniqueWorkList worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { - BlockClosure closure = new BlockClosure(new LiveValueSet(liveOutMap.get(block))); + currentSet = new LiveValueSet(liveOutMap.get(block)); List instructions = lir.getLIRforBlock(block); for (int i = instructions.size() - 1; i >= 0; i--) { LIRInstruction inst = instructions.get(i); - closure.processInstructionBottomUp(inst); + processInstructionBottomUp(inst); } - liveInMap.put(block, closure.getCurrentSet()); + liveInMap.put(block, currentSet); + currentSet = null; worklist.addAll(block.getPredecessors()); } } @@ -211,78 +365,68 @@ private static final EnumSet REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG); private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); - private final class BlockClosure { - private final LiveValueSet currentSet; + private LiveValueSet currentSet; - private BlockClosure(LiveValueSet set) { - currentSet = set; - } + /** + * Process all values of an instruction bottom-up, i.e. definitions before usages. Values + * that start or end at the current operation are not included. + */ + private void processInstructionBottomUp(LIRInstruction op) { + try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { + // kills - private LiveValueSet getCurrentSet() { - return currentSet; - } + op.visitEachTemp(defConsumer); + op.visitEachOutput(defConsumer); + if (op.destroysCallerSavedRegisters()) { + for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { + defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); + } + } - /** - * Process all values of an instruction bottom-up, i.e. definitions before usages. - * Values that start or end at the current operation are not included. - */ - private void processInstructionBottomUp(LIRInstruction op) { - try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { - // kills + // gen - values that are considered alive for this state + op.visitEachAlive(useConsumer); + op.visitEachState(useConsumer); + // mark locations + op.forEachState(stateConsumer); + // gen + op.visitEachInput(useConsumer); + } + } - op.visitEachTemp(defConsumer); - op.visitEachOutput(defConsumer); - if (op.destroysCallerSavedRegisters()) { - for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { - defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); - } - } + InstructionStateProcedure stateConsumer = new InstructionStateProcedure() { + public void doState(LIRInstruction inst, LIRFrameState info) { + markLocation(inst, info, currentSet); + } + }; - // gen - values that are considered alive for this state - op.visitEachAlive(useConsumer); - op.visitEachState(useConsumer); - // mark locations - op.forEachState(stateConsumer); - // gen - op.visitEachInput(useConsumer); + ValueConsumer useConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet flags) { + if (shouldProcessValue(operand)) { + // no need to insert values and derived reference + if (Debug.isLogEnabled()) { + Debug.log("set operand: %s", operand); + } + currentSet.put(operand); } } - - InstructionStateProcedure stateConsumer = new InstructionStateProcedure() { - public void doState(LIRInstruction inst, LIRFrameState info) { - markLocation(inst, info, getCurrentSet()); - } - }; + }; - ValueConsumer useConsumer = new ValueConsumer() { - public void visitValue(Value operand, OperandMode mode, EnumSet flags) { - if (shouldProcessValue(operand)) { - // no need to insert values and derived reference - if (Debug.isLogEnabled()) { - Debug.log("set operand: %s", operand); - } - currentSet.put(operand); + ValueConsumer defConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet flags) { + if (shouldProcessValue(operand)) { + if (Debug.isLogEnabled()) { + Debug.log("clear operand: %s", operand); } + currentSet.remove(operand); + } else { + assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s", + operand, mode); } - }; + } + }; - ValueConsumer defConsumer = new ValueConsumer() { - public void visitValue(Value operand, OperandMode mode, EnumSet flags) { - if (shouldProcessValue(operand)) { - if (Debug.isLogEnabled()) { - Debug.log("clear operand: %s", operand); - } - currentSet.remove(operand); - } else { - assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format( - "Illegal PlatformKind is only allowed for TEMP mode: %s, %s", operand, mode); - } - } - }; - - protected boolean shouldProcessValue(Value operand) { - return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; - } + protected boolean shouldProcessValue(Value operand) { + return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; } /** @@ -294,9 +438,10 @@ } ReferenceMap refMap = info.debugInfo().getReferenceMap(); - for (Value v : values) { - frameMap.setReference(v, refMap); - } + refMap.reset(); + frameMap.addLiveValues(refMap); + values.addLiveValues(refMap); + refMap.finish(); } /** diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Fri Jun 05 17:12:08 2015 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.lir.framemap; -import static com.oracle.jvmci.code.ValueUtil.*; - import java.util.*; import com.oracle.graal.asm.*; @@ -103,6 +101,12 @@ return target; } + public void addLiveValues(ReferenceMap refMap) { + for (Value value : objectStackSlots) { + refMap.addLiveValue(value); + } + } + protected int returnAddressSize() { return getTarget().arch.getReturnAddressSize(); } @@ -322,29 +326,6 @@ public ReferenceMap initReferenceMap(boolean hasRegisters) { ReferenceMap refMap = getTarget().createReferenceMap(hasRegisters, frameSize() / getTarget().wordSize); - for (StackSlot slot : objectStackSlots) { - setReference(slot, refMap); - } return refMap; } - - /** - * Marks the specified location as a reference in the reference map of the debug information. - * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a - * {@link JavaConstant} is automatically tracked. - * - * @param location The location to be added to the reference map. - * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. - */ - public void setReference(Value location, ReferenceMap refMap) { - LIRKind kind = location.getLIRKind(); - if (isRegister(location)) { - refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind); - } else if (isStackSlot(location)) { - int offset = offsetForStackSlot(asStackSlot(location)); - refMap.setStackSlot(offset, kind); - } else { - assert isConstant(location); - } - } } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Jun 05 17:12:08 2015 +0200 @@ -459,9 +459,9 @@ inst.forEachState(state -> { if (state.hasDebugInfo()) { DebugInfo di = state.debugInfo(); - stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch)); + stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo())); } else { - stateString.append(debugInfoToString(state.topFrame, null, null, target.arch)); + stateString.append(debugInfoToString(state.topFrame, null, null)); } }); if (stateString.length() > 0) { diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Jun 05 17:12:08 2015 +0200 @@ -23,10 +23,10 @@ package com.oracle.graal.printer; import java.io.*; -import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.*; +import com.oracle.graal.code.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; @@ -37,15 +37,10 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.schedule.*; import com.oracle.jvmci.code.*; -import com.oracle.jvmci.code.CodeUtil.DefaultRefMapFormatter; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; -import com.oracle.jvmci.code.CompilationResult.Call; -import com.oracle.jvmci.code.CompilationResult.DataPatch; -import com.oracle.jvmci.code.CompilationResult.Infopoint; -import com.oracle.jvmci.code.CompilationResult.Mark; import com.oracle.jvmci.common.*; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.service.*; /** * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the @@ -201,99 +196,35 @@ } - /** - * Returns a disassembly of some compiled code. - * - * @param compResult some compiled code - * @param installedCode the result of installing the code in {@code compResult} or null if the - * code has not yet been installed - */ - private static String disassemble(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) { - TargetDescription target = codeCache.getTarget(); - RegisterConfig regConfig = codeCache.getRegisterConfig(); - byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); - if (code == null) { - // Method was deoptimized/invalidated - return ""; + private static DisassemblerProvider disassembler; + + private static final DisassemblerProvider NOP_DISASSEMBLER = new DisassemblerProvider() { + public String getName() { + return null; } - long start = installedCode == null ? 0L : installedCode.getStart(); - HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8); - if (compResult != null) { - HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); - addExceptionHandlersComment(compResult, hcf); - Register fp = regConfig.getFrameRegister(); - RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.arch, target.wordSize, fp, 0); - for (Infopoint infopoint : compResult.getInfopoints()) { - if (infopoint instanceof Call) { - Call call = (Call) infopoint; - if (call.debugInfo != null) { - hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString()); - } - addOperandComment(hcf, call.pcOffset, "{" + codeCache.getTargetName(call) + "}"); - } else { - if (infopoint.debugInfo != null) { - hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString()); - } - addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}"); + }; + + private static DisassemblerProvider getDisassembler() { + if (disassembler == null) { + DisassemblerProvider selected = NOP_DISASSEMBLER; + for (DisassemblerProvider d : Services.load(DisassemblerProvider.class)) { + String name = d.getName().toLowerCase(); + if (name.contains("hcf") || name.contains("hexcodefile")) { + selected = d; + break; } } - for (DataPatch site : compResult.getDataPatches()) { - hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}"); - } - for (Mark mark : compResult.getMarks()) { - hcf.addComment(mark.pcOffset, codeCache.getMarkName(mark)); - } + disassembler = selected; } - String hcfEmbeddedString = hcf.toEmbeddedString(); - return HexCodeFileDisTool.tryDisassemble(hcfEmbeddedString); + return disassembler; } - /** - * Interface to the tool for disassembling an {@link HexCodeFile#toEmbeddedString() embedded} - * {@link HexCodeFile}. - */ - static class HexCodeFileDisTool { - static final Method processMethod; - static { - Method toolMethod = null; - try { - Class toolClass = Class.forName("com.oracle.max.hcfdis.HexCodeFileDis", true, ClassLoader.getSystemClassLoader()); - toolMethod = toolClass.getDeclaredMethod("processEmbeddedString", String.class); - } catch (Exception e) { - // Tool not available on the class path - } - processMethod = toolMethod; + private static String disassemble(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) { + DisassemblerProvider dis = getDisassembler(); + if (installedCode != null) { + return dis.disassembleInstalledCode(codeCache, compResult, installedCode); } - - public static String tryDisassemble(String hcfEmbeddedString) { - if (processMethod != null) { - try { - return (String) processMethod.invoke(null, hcfEmbeddedString); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - // If the tool is available, for now let's be noisy when it fails - throw new JVMCIError(e); - } - } - return hcfEmbeddedString; - } - } - - private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) { - if (!compResult.getExceptionHandlers().isEmpty()) { - String nl = HexCodeFile.NEW_LINE; - StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl); - for (CompilationResult.ExceptionHandler e : compResult.getExceptionHandlers()) { - buf.append(" ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl); - hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]"); - hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]"); - } - hcf.addComment(0, buf.toString()); - } - } - - private static void addOperandComment(HexCodeFile hcf, int pos, String comment) { - String oldValue = hcf.addOperandComment(pos, comment); - assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue; + return dis.disassembleCompiledCode(codeCache, compResult); } private static boolean isCompilationResultAndInstalledCode(Object object) { diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Fri Jun 05 17:12:08 2015 +0200 @@ -22,22 +22,12 @@ */ package com.oracle.graal.printer; -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.code.VirtualObject; -import com.oracle.jvmci.code.BytecodePosition; -import com.oracle.jvmci.code.BytecodeFrame; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.code.CodeUtil; -import com.oracle.jvmci.code.RegisterSaveLayout; -import com.oracle.jvmci.code.ReferenceMap; -import com.oracle.jvmci.meta.MetaUtil; -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.JavaMethod; import java.io.*; import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.meta.*; /** * Utility for printing compilation related data structures at various compilation phases. The @@ -122,19 +112,10 @@ /** * Formats given debug info as a multi line string. */ - protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) { + protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo) { StringBuilder sb = new StringBuilder(); - RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); - - if (refMap != null && refMap.hasRegisterRefMap()) { - sb.append("reg-ref-map:"); - refMap.appendRegisterMap(sb, arch != null ? new CodeUtil.DefaultRegFormatter(arch) : formatter); - sb.append("\n"); - } - - if (refMap != null && refMap.hasFrameRefMap()) { - sb.append("frame-ref-map:"); - refMap.appendFrameMap(sb, formatter); + if (refMap != null) { + sb.append(refMap.toString()); sb.append("\n"); } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Fri Jun 05 17:11:50 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2009, 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. - * - * 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.oracle.graal.printer; - -import java.io.*; -import java.util.*; -import java.util.regex.*; - -import com.oracle.jvmci.code.*; -import com.oracle.jvmci.code.CompilationResult.CodeAnnotation; -import com.oracle.jvmci.code.CompilationResult.CodeComment; -import com.oracle.jvmci.code.CompilationResult.JumpTable; - -/** - * A HexCodeFile is a textual format for representing a chunk of machine code along with extra - * information that can be used to enhance a disassembly of the code. - * - * A pseudo grammar for a HexCodeFile is given below. - * - *
- *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
- *
- *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
- *
- *     Platform ::= "Platform" ISA WordWidth
- *
- *     HexCode ::= "HexCode" StartAddress HexDigits
- *
- *     Comment ::= "Comment" Position String
- *
- *     OperandComment ::= "OperandComment" Position String
- *
- *     JumpTable ::= "JumpTable" Position EntrySize Low High
- *
- *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
- *
- *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
- *
- *     Delim := "<||@"
- * 
- * - * There must be exactly one HexCode and Platform part in a HexCodeFile. The length of HexDigits - * must be even as each pair of digits represents a single byte. - *

- * Below is an example of a valid Code input: - * - *

- *
- *  Platform AMD64 64  <||@
- *  HexCode 0 e8000000009090904883ec084889842410d0ffff48893c24e800000000488b3c24488bf0e8000000004883c408c3  <||@
- *  Comment 24 frame-ref-map: +0 {0}
- *  at java.lang.String.toLowerCase(String.java:2496) [bci: 1]
- *              |0
- *     locals:  |stack:0:a
- *     stack:   |stack:0:a
- *    <||@
- *  OperandComment 24 {java.util.Locale.getDefault()}  <||@
- *  Comment 36 frame-ref-map: +0 {0}
- *  at java.lang.String.toLowerCase(String.java:2496) [bci: 4]
- *              |0
- *     locals:  |stack:0:a
- *    <||@
- *  OperandComment 36 {java.lang.String.toLowerCase(Locale)}  lt;||@
- *
- * 
- */ -public class HexCodeFile { - - public static final String NEW_LINE = CodeUtil.NEW_LINE; - public static final String SECTION_DELIM = " <||@"; - public static final String COLUMN_END = " <|@"; - public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL); - public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL); - public static final Pattern OPERAND_COMMENT = COMMENT; - public static final Pattern JUMP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(-{0,1}\\d+)\\s+(-{0,1}\\d+)\\s*"); - public static final Pattern LOOKUP_TABLE = Pattern.compile("(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s*"); - public static final Pattern HEX_CODE = Pattern.compile("(\\p{XDigit}+)(?:\\s+(\\p{XDigit}*))?"); - public static final Pattern PLATFORM = Pattern.compile("(\\S+)\\s+(\\S+)", Pattern.DOTALL); - - /** - * Delimiter placed before a HexCodeFile when embedded in a string/stream. - */ - public static final String EMBEDDED_HCF_OPEN = "<<> comments = new TreeMap<>(); - - /** - * Map from a machine code position to a comment for the operands of the instruction at the - * position. - */ - public final Map operandComments = new TreeMap<>(); - - public final byte[] code; - - public final ArrayList jumpTables = new ArrayList<>(); - - public final String isa; - - public final int wordWidth; - - public final long startAddress; - - public HexCodeFile(byte[] code, long startAddress, String isa, int wordWidth) { - this.code = code; - this.startAddress = startAddress; - this.isa = isa; - this.wordWidth = wordWidth; - } - - /** - * Parses a string in the format produced by {@link #toString()} to produce a - * {@link HexCodeFile} object. - */ - public static HexCodeFile parse(String input, int sourceOffset, String source, String sourceName) { - return new Parser(input, sourceOffset, source, sourceName).hcf; - } - - /** - * Formats this HexCodeFile as a string that can be parsed with - * {@link #parse(String, int, String, String)}. - */ - @Override - public String toString() { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeTo(baos); - return baos.toString(); - } - - public String toEmbeddedString() { - return EMBEDDED_HCF_OPEN + NEW_LINE + toString() + EMBEDDED_HCF_CLOSE; - } - - public void writeTo(OutputStream out) { - PrintStream ps = out instanceof PrintStream ? (PrintStream) out : new PrintStream(out); - ps.printf("Platform %s %d %s%n", isa, wordWidth, SECTION_DELIM); - ps.printf("HexCode %x %s %s%n", startAddress, HexCodeFile.hexCodeString(code), SECTION_DELIM); - - for (JumpTable table : jumpTables) { - ps.printf("JumpTable %d %d %d %d %s%n", table.position, table.entrySize, table.low, table.high, SECTION_DELIM); - } - - for (Map.Entry> e : comments.entrySet()) { - int pos = e.getKey(); - for (String comment : e.getValue()) { - ps.printf("Comment %d %s %s%n", pos, comment, SECTION_DELIM); - } - } - - for (Map.Entry e : operandComments.entrySet()) { - ps.printf("OperandComment %d %s %s%n", e.getKey(), e.getValue(), SECTION_DELIM); - } - ps.flush(); - } - - /** - * Formats a byte array as a string of hex digits. - */ - public static String hexCodeString(byte[] code) { - if (code == null) { - return ""; - } else { - StringBuilder sb = new StringBuilder(code.length * 2); - for (int b : code) { - String hex = Integer.toHexString(b & 0xff); - if (hex.length() == 1) { - sb.append('0'); - } - sb.append(hex); - } - return sb.toString(); - } - } - - /** - * Adds a comment to the list of comments for a given position. - */ - public void addComment(int pos, String comment) { - List list = comments.get(pos); - if (list == null) { - list = new ArrayList<>(); - comments.put(pos, list); - } - list.add(encodeString(comment)); - } - - /** - * Sets an operand comment for a given position. - * - * @return the previous operand comment for {@code pos} - */ - public String addOperandComment(int pos, String comment) { - return operandComments.put(pos, encodeString(comment)); - } - - /** - * Adds any jump tables, lookup tables or code comments from a list of code annotations. - */ - public static void addAnnotations(HexCodeFile hcf, List annotations) { - if (annotations == null || annotations.isEmpty()) { - return; - } - for (CodeAnnotation a : annotations) { - if (a instanceof JumpTable) { - JumpTable table = (JumpTable) a; - hcf.jumpTables.add(table); - } else if (a instanceof CodeComment) { - CodeComment comment = (CodeComment) a; - hcf.addComment(comment.position, comment.value); - } - } - } - - /** - * Modifies a string to mangle any substrings matching {@link #SECTION_DELIM} and - * {@link #COLUMN_END}. - */ - public static String encodeString(String input) { - int index; - String s = input; - while ((index = s.indexOf(SECTION_DELIM)) != -1) { - s = s.substring(0, index) + " < |@" + s.substring(index + SECTION_DELIM.length()); - } - while ((index = s.indexOf(COLUMN_END)) != -1) { - s = s.substring(0, index) + " < @" + s.substring(index + COLUMN_END.length()); - } - return s; - } - - /** - * Helper class to parse a string in the format produced by {@link HexCodeFile#toString()} and - * produce a {@link HexCodeFile} object. - */ - static class Parser { - - final String input; - final String inputSource; - String isa; - int wordWidth; - byte[] code; - long startAddress; - HexCodeFile hcf; - - Parser(String input, int sourceOffset, String source, String sourceName) { - this.input = input; - this.inputSource = sourceName; - parseSections(sourceOffset, source); - } - - void makeHCF() { - if (hcf == null) { - if (isa != null && wordWidth != 0 && code != null) { - hcf = new HexCodeFile(code, startAddress, isa, wordWidth); - } - } - } - - void checkHCF(String section, int offset) { - check(hcf != null, offset, section + " section must be after Platform and HexCode section"); - } - - void check(boolean condition, int offset, String message) { - if (!condition) { - error(offset, message); - } - } - - Error error(int offset, String message) { - throw new Error(errorMessage(offset, message)); - } - - void warning(int offset, String message) { - PrintStream err = System.err; - err.println("Warning: " + errorMessage(offset, message)); - } - - String errorMessage(int offset, String message) { - assert offset < input.length(); - InputPos inputPos = filePos(offset); - int lineEnd = input.indexOf(HexCodeFile.NEW_LINE, offset); - int lineStart = offset - inputPos.col; - String line = lineEnd == -1 ? input.substring(lineStart) : input.substring(lineStart, lineEnd); - return String.format("%s:%d: %s%n%s%n%" + (inputPos.col + 1) + "s", inputSource, inputPos.line, message, line, "^"); - } - - static class InputPos { - - final int line; - final int col; - - public InputPos(int line, int col) { - this.line = line; - this.col = col; - } - } - - InputPos filePos(int index) { - assert input != null; - int lineStart = input.lastIndexOf(HexCodeFile.NEW_LINE, index) + 1; - - String l = input.substring(lineStart, lineStart + 10); - PrintStream out = System.out; - out.println("YYY" + input.substring(index, index + 10) + "..."); - out.println("XXX" + l + "..."); - - int pos = input.indexOf(HexCodeFile.NEW_LINE, 0); - int line = 1; - while (pos > 0 && pos < index) { - line++; - pos = input.indexOf(HexCodeFile.NEW_LINE, pos + 1); - } - return new InputPos(line, index - lineStart); - } - - void parseSections(int offset, String source) { - assert input.startsWith(source, offset); - int index = 0; - int endIndex = source.indexOf(SECTION_DELIM); - while (endIndex != -1) { - while (source.charAt(index) <= ' ') { - index++; - } - String section = source.substring(index, endIndex).trim(); - parseSection(offset + index, section); - index = endIndex + SECTION_DELIM.length(); - endIndex = source.indexOf(SECTION_DELIM, index); - } - } - - int parseInt(int offset, String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - throw error(offset, "Not a valid integer: " + value); - } - } - - void parseSection(int offset, String section) { - if (section.isEmpty()) { - return; - } - assert input.startsWith(section, offset); - Matcher m = HexCodeFile.SECTION.matcher(section); - check(m.matches(), offset, "Section does not match pattern " + HexCodeFile.SECTION); - - String header = m.group(1); - String body = m.group(2); - int headerOffset = offset + m.start(1); - int bodyOffset = offset + m.start(2); - - if (header.equals("Platform")) { - check(isa == null, bodyOffset, "Duplicate Platform section found"); - m = HexCodeFile.PLATFORM.matcher(body); - check(m.matches(), bodyOffset, "Platform does not match pattern " + HexCodeFile.PLATFORM); - isa = m.group(1); - wordWidth = parseInt(bodyOffset + m.start(2), m.group(2)); - makeHCF(); - } else if (header.equals("HexCode")) { - check(code == null, bodyOffset, "Duplicate Code section found"); - m = HexCodeFile.HEX_CODE.matcher(body); - check(m.matches(), bodyOffset, "Code does not match pattern " + HexCodeFile.HEX_CODE); - String hexAddress = m.group(1); - startAddress = Long.valueOf(hexAddress, 16); - String hexCode = m.group(2); - if (hexCode == null) { - code = new byte[0]; - } else { - check((hexCode.length() % 2) == 0, bodyOffset, "Hex code length must be even"); - code = new byte[hexCode.length() / 2]; - for (int i = 0; i < code.length; i++) { - String hexByte = hexCode.substring(i * 2, (i + 1) * 2); - code[i] = (byte) Integer.parseInt(hexByte, 16); - } - } - makeHCF(); - } else if (header.equals("Comment")) { - checkHCF("Comment", headerOffset); - m = HexCodeFile.COMMENT.matcher(body); - check(m.matches(), bodyOffset, "Comment does not match pattern " + HexCodeFile.COMMENT); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - String comment = m.group(2); - hcf.addComment(pos, comment); - } else if (header.equals("OperandComment")) { - checkHCF("OperandComment", headerOffset); - m = HexCodeFile.OPERAND_COMMENT.matcher(body); - check(m.matches(), bodyOffset, "OperandComment does not match pattern " + HexCodeFile.OPERAND_COMMENT); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - String comment = m.group(2); - hcf.addOperandComment(pos, comment); - } else if (header.equals("JumpTable")) { - checkHCF("JumpTable", headerOffset); - m = HexCodeFile.JUMP_TABLE.matcher(body); - check(m.matches(), bodyOffset, "JumpTable does not match pattern " + HexCodeFile.JUMP_TABLE); - int pos = parseInt(bodyOffset + m.start(1), m.group(1)); - int entrySize = parseInt(bodyOffset + m.start(2), m.group(2)); - int low = parseInt(bodyOffset + m.start(3), m.group(3)); - int high = parseInt(bodyOffset + m.start(4), m.group(4)); - hcf.jumpTables.add(new JumpTable(pos, low, high, entrySize)); - } else { - error(offset, "Unknown section header: " + header); - } - } - } -} diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java Fri Jun 05 17:12:08 2015 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.truffle; +import com.oracle.jvmci.service.*; import com.oracle.truffle.api.nodes.*; -public interface LoopNodeFactory extends PrioritizedServiceProvider { +public interface LoopNodeFactory extends PrioritizedServiceProvider, Service { LoopNode create(RepeatingNode repeatingNode); diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java --- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CodeUtil.java Fri Jun 05 17:12:08 2015 +0200 @@ -429,15 +429,8 @@ } String nl = NEW_LINE; ReferenceMap refMap = info.getReferenceMap(); - if (refMap != null && refMap.hasRegisterRefMap()) { - sb.append(" reg-ref-map:"); - refMap.appendRegisterMap(sb, formatter); - sb.append(nl); - } - if (refMap != null && refMap.hasFrameRefMap()) { - sb.append("frame-ref-map:"); - refMap.appendFrameMap(sb, formatter); - sb.append(nl); + if (refMap != null) { + sb.append(refMap.toString()); } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) { diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java --- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Fri Jun 05 17:12:08 2015 +0200 @@ -27,7 +27,6 @@ import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; import com.oracle.jvmci.meta.Assumptions.Assumption; import com.oracle.jvmci.meta.*; @@ -858,17 +857,8 @@ if (info != null) { ReferenceMap refMap = info.getReferenceMap(); if (refMap != null) { - RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); - if (refMap.hasFrameRefMap()) { - sb.append(" stackMap["); - refMap.appendFrameMap(sb, formatter); - sb.append(']'); - } - if (refMap.hasRegisterRefMap()) { - sb.append(" registerMap["); - refMap.appendRegisterMap(sb, formatter); - sb.append(']'); - } + sb.append(refMap.toString()); + sb.append(']'); } RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); if (calleeSaveInfo != null) { diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/DisassemblerProvider.java --- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/DisassemblerProvider.java Fri Jun 05 17:11:50 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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. - */ -package com.oracle.jvmci.code; - -/** - * Interface providing capability for disassembling machine code. - */ -public interface DisassemblerProvider { - - /** - * Gets a textual disassembly of some given installed code. - * - * @return a non-zero length string containing a disassembly of {@code code} or null if - * {@code code} is {@link InstalledCode#isValid() invalid} or it could not be - * disassembled for some other reason - */ - String disassemble(InstalledCode code); -} diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java --- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/ReferenceMap.java Fri Jun 05 17:12:08 2015 +0200 @@ -22,20 +22,24 @@ */ package com.oracle.jvmci.code; -import com.oracle.jvmci.meta.LIRKind; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; +import com.oracle.jvmci.meta.*; + +public abstract class ReferenceMap { -public abstract class ReferenceMap implements Cloneable { - - public abstract void setRegister(int idx, LIRKind kind); - - public abstract void setStackSlot(int offset, LIRKind kind); + /** + * Empty out the reference map. + */ + public abstract void reset(); - public abstract boolean hasRegisterRefMap(); - - public abstract boolean hasFrameRefMap(); + /** + * Add {@code value} to the current set of reference values. + * + * @param v + */ + public abstract void addLiveValue(Value v); - public abstract void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); - - public abstract void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); + /** + * Perform any final encoding needed before use. + */ + public abstract void finish(); } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java --- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotReferenceMap.java Fri Jun 05 17:12:08 2015 +0200 @@ -22,351 +22,60 @@ */ package com.oracle.jvmci.hotspot; +import static com.oracle.jvmci.code.ValueUtil.*; + import java.util.*; -import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; import com.oracle.jvmci.code.*; -import com.oracle.jvmci.common.*; import com.oracle.jvmci.meta.*; public final class HotSpotReferenceMap extends ReferenceMap { - static final int OOP64 = 0b1010; - static final int OOP32 = 0b01; - static final int NARROW_LOW = OOP32; - static final int NARROW_HIGH = OOP32 << 2; - static final int NARROW_BOTH = NARROW_LOW | NARROW_HIGH; + private Value[] objects; + private int[] bytesPerElement; + private int maxRegisterSize; + private ArrayList objectValues; - private enum MapEntry { - NoReference(0), - WideOop(OOP64), - NarrowOopLowerHalf(NARROW_LOW), - NarrowOopUpperHalf(NARROW_HIGH), - TwoNarrowOops(NARROW_BOTH), - Illegal(-1); + private final TargetDescription target; - MapEntry(int pattern) { - this.pattern = pattern; - } - - final int pattern; + public HotSpotReferenceMap(TargetDescription target) { + this.target = target; + this.objects = Value.NO_VALUES; + } - /** - * Create enum values from OopMap. - *

- * These bits can have the following values (MSB first): - * - *

-         * 0000 - contains no references
-         * 1010 - contains a wide oop
-         * 0001 - contains a narrow oop in the lower half
-         * 0101 - contains a narrow oop in the upper half
-         * 0101 - contains two narrow oops
-         * 
- * - * @see HotSpotReferenceMap#registerRefMap - * @see HotSpotReferenceMap#frameRefMap - */ - static MapEntry getFromBits(int idx, HotSpotOopMap set) { - int n = set.get(idx); - switch (n) { - case 0: - return NoReference; - case OOP64: - return WideOop; - case NARROW_LOW: - return NarrowOopLowerHalf; - case NARROW_HIGH: - return NarrowOopUpperHalf; - case NARROW_BOTH: - return TwoNarrowOops; - default: - return Illegal; + @Override + public void reset() { + objectValues = new ArrayList<>(); + objects = Value.NO_VALUES; + bytesPerElement = null; + maxRegisterSize = 0; + } + + @Override + public void addLiveValue(Value v) { + if (isConstant(v)) { + return; + } + LIRKind lirKind = v.getLIRKind(); + if (!lirKind.isValue()) { + objectValues.add(v); + } + if (isRegister(v)) { + int size = target.getSizeInBytes(lirKind.getPlatformKind()); + if (size > maxRegisterSize) { + maxRegisterSize = size; } } - - String toBitString() { - int bits = toBit(this); - if (bits == -1) { - return "---"; - } - return String.format("%3s", Integer.toBinaryString(bits)).replace(' ', '0'); - } - - static int toBit(MapEntry type) { - return type.pattern; - } } - /** - * A specialized bit set that represents both wide and narrow oops in an efficient manner. The - * map consists of 4 bit entries that represent 8 bytes of memory. - * - */ - class HotSpotOopMap implements Cloneable { - - /** - * Each entry is 4 bits long and covers 8 bytes of memory. - */ - private static final int BITS_PER_ENTRY = 4; - private static final int BITS_PER_ELEMENT = 64; - - public HotSpotOopMap(int i) { - words = new long[(i * BITS_PER_ENTRY + BITS_PER_ELEMENT) / BITS_PER_ELEMENT]; - } - - public HotSpotOopMap(HotSpotOopMap other) { - words = other.words.clone(); - } - - private long[] words; - - private int get(int i) { - return getEntry(i); - } - - public void or(HotSpotOopMap src) { - if (words.length < src.words.length) { - long[] newWords = new long[src.words.length]; - System.arraycopy(src.words, 0, newWords, 0, src.words.length); - for (int i = 0; i < words.length; i++) { - newWords[i] |= words[i]; - } - words = newWords; - } else { - for (int i = 0; i < src.words.length; i++) { - words[i] |= src.words[i]; - } - } - } - - private void setOop(int regIdx) { - setEntry(regIdx, OOP64); - } - - public int size() { - return words.length * BITS_PER_ELEMENT / BITS_PER_ENTRY; - } - - @Override - public HotSpotOopMap clone() { - return new HotSpotOopMap(this); - } - - private void setNarrowOop(int offset) { - setNarrowEntry(offset, OOP32); - } - - private void setEntry(int regIdx, int value) { - assert regIdx % 2 == 0 : "must be alinged"; - int bitIndex = (regIdx >> 1) * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - if (wordIndex >= words.length) { - if (value == 0) { - // Nothing to do since bits are clear - return; - } - words = Arrays.copyOf(words, wordIndex + 1); - } - assert verifyUpdate(this, this); - long orig = words[wordIndex]; - words[wordIndex] = (orig & (~(0b1111L << shift))) | ((long) value << shift); - assert get(regIdx / 2) == value; - assert verifyUpdate(this, this); - } - - private void setNarrowEntry(int offset, int value) { - int regIdx = offset >> 1; - boolean low = offset % 2 == 0; - int bitIndex = regIdx * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - if (wordIndex >= words.length) { - if (value == 0) { - // Nothing to do since bits are clear - return; - } - words = Arrays.copyOf(words, wordIndex + 1); - } - long originalValue = words[wordIndex]; - int current = ((int) (originalValue >> shift)) & 0b1111; - if (current == OOP64) { - current = 0; - } - long newValue; - if (value != 0) { - newValue = current | (low ? value : (value << 2)); - } else { - newValue = current & (low ? 0b1100 : 0b0011); - } - long masked = originalValue & (~(0b1111L << shift)); - words[wordIndex] = masked | (newValue << shift); - assert verifyUpdate(this, this); - } - - private int getEntry(int regIdx) { - int bitIndex = regIdx * BITS_PER_ENTRY; - int wordIndex = bitIndex / BITS_PER_ELEMENT; - int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; - return ((int) (words[wordIndex] >>> shift)) & 0b1111; + @Override + public void finish() { + objects = objectValues.toArray(new Value[objectValues.size()]); + this.bytesPerElement = new int[objects.length]; + for (int i = 0; i < objects.length; i++) { + bytesPerElement[i] = bytesPerElement(objects[i].getLIRKind()); } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - - if (other instanceof HotSpotOopMap) { - HotSpotOopMap otherMap = (HotSpotOopMap) other; - int limit = Math.min(words.length, otherMap.words.length); - for (int i = 0; i < limit; i++) { - if (words[i] != otherMap.words[i]) { - return false; - } - } - for (int i = limit; i < words.length; i++) { - if (words[i] != 0) { - return false; - } - } - for (int i = limit; i < otherMap.words.length; i++) { - if (otherMap.words[i] != 0) { - return false; - } - } - return true; - } - return false; - } - - @Override - public int hashCode() { - long h = 1234; - for (int i = words.length; --i >= 0;) { - h ^= words[i] * (i + 1); - } - return (int) ((h >> 32) ^ h); - } - - @Override - public String toString() { - int count = 0; - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (int idx = 0; idx < size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, this); - if (dstType == MapEntry.NoReference) { - continue; - } - if (count > 0) { - sb.append(", "); - } - if (dstType == MapEntry.Illegal) { - int value = get(idx); - sb.append("0x"); - sb.append(Integer.toHexString(value)); - } else { - sb.append(idx); - sb.append(':'); - sb.append(dstType); - } - count++; - } - sb.append("]"); - return sb.toString(); - } - } - - /** - * Contains 3 bits per scalar register, and n*3 bits per n-word vector register (e.g., on a - * 64-bit system, a 256-bit vector register requires 12 reference map bits). - *

- * These bits can have the following values (LSB first): - * - *

-     * 000 - contains no references
-     * 100 - contains a wide oop
-     * 110 - contains a narrow oop in the lower half
-     * 101 - contains a narrow oop in the upper half
-     * 111 - contains two narrow oops
-     * 
- */ - private final HotSpotOopMap registerRefMap; - - /** - * Contains 3 bits per stack word. - *

- * These bits can have the following values (LSB first): - * - *

-     * 000 - contains no references
-     * 100 - contains a wide oop
-     * 110 - contains a narrow oop in the lower half
-     * 101 - contains a narrow oop in the upper half
-     * 111 - contains two narrow oops
-     * 
- */ - private final HotSpotOopMap frameRefMap; - - private final TargetDescription target; - - public HotSpotReferenceMap(int registerCount, int frameSlotCount, TargetDescription target) { - if (registerCount > 0) { - this.registerRefMap = new HotSpotOopMap(registerCount); - } else { - this.registerRefMap = null; - } - this.frameRefMap = new HotSpotOopMap(frameSlotCount); - this.target = target; - } - - private HotSpotReferenceMap(HotSpotReferenceMap other) { - this.registerRefMap = other.registerRefMap.clone(); - this.frameRefMap = other.frameRefMap.clone(); - this.target = other.target; - } - - @Override - public ReferenceMap clone() { - return new HotSpotReferenceMap(this); - } - - // setters - @Override - public void setRegister(int idx, LIRKind kind) { - set(registerRefMap, idx * 2, kind); - } - - @Override - public void setStackSlot(int offset, LIRKind kind) { - assert offset % bytesPerElement(kind) == 0 : "unaligned value in ReferenceMap"; - set(frameRefMap, offset / 4, kind); - } - - private void set(HotSpotOopMap refMap, int index, LIRKind kind) { - if (kind.isDerivedReference()) { - throw new JVMCIError("derived reference cannot be inserted in ReferenceMap"); - } - - int bytesPerElement = bytesPerElement(kind); - int length = kind.getPlatformKind().getVectorLength(); - if (bytesPerElement == 8) { - for (int i = 0; i < length; i++) { - if (kind.isReference(i)) { - refMap.setOop(index + i * 2); - } - } - } else if (bytesPerElement == 4) { - for (int i = 0; i < length; i++) { - if (kind.isReference(i)) { - refMap.setNarrowOop(index + i); - } - } - } else { - assert kind.isValue() : "unknown reference kind " + kind; - } + objectValues = null; } private int bytesPerElement(LIRKind kind) { @@ -374,74 +83,6 @@ return target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); } - public HotSpotOopMap getFrameMap() { - return frameRefMap == null ? null : (HotSpotOopMap) frameRefMap.clone(); - } - - public HotSpotOopMap getRegisterMap() { - return registerRefMap == null ? null : (HotSpotOopMap) registerRefMap.clone(); - } - - static MapEntry[] entries(HotSpotOopMap fixedMap) { - MapEntry[] result = new MapEntry[fixedMap.size()]; - for (int idx = 0; idx < fixedMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, fixedMap); - result[idx] = dstType; - } - return result; - } - - private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src) { - return verifyUpdate(dst, src, true); - } - - private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { - for (int idx = 0; idx < Math.min(src.size(), dst.size()); idx++) { - if (!verifyUpdateEntry(idx, dst, src, doAssert)) { - return false; - } - } - return true; - } - - private static boolean verifyUpdateEntry(int idx, HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { - MapEntry dstType = MapEntry.getFromBits(idx, dst); - MapEntry srcType = MapEntry.getFromBits(idx, src); - - if (dstType == MapEntry.Illegal || srcType == MapEntry.Illegal) { - assert !doAssert : String.format("Illegal RefMap bit pattern: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - switch (dstType) { - case NoReference: - return true; - case WideOop: - switch (srcType) { - case NoReference: - case WideOop: - return true; - default: - assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - case TwoNarrowOops: - case NarrowOopLowerHalf: - case NarrowOopUpperHalf: - switch (srcType) { - case TwoNarrowOops: - case NarrowOopLowerHalf: - case NarrowOopUpperHalf: - case NoReference: - return true; - default: - assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - default: - return false; - } - } - @Override public int hashCode() { throw new UnsupportedOperationException(); @@ -454,7 +95,7 @@ } if (obj instanceof HotSpotReferenceMap) { HotSpotReferenceMap that = (HotSpotReferenceMap) obj; - if (this.frameRefMap.equals(that.frameRefMap) && Objects.equals(this.registerRefMap, that.registerRefMap) && this.target.equals(that.target)) { + if (Arrays.equals(objects, that.objects) && this.target.equals(that.target)) { return true; } } @@ -462,49 +103,7 @@ } @Override - public boolean hasRegisterRefMap() { - return registerRefMap != null && registerRefMap.size() > 0; - } - - @Override - public boolean hasFrameRefMap() { - return frameRefMap != null && frameRefMap.size() > 0; - } - - @Override - public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) { - for (int idx = 0; idx < registerRefMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, registerRefMap); - if (dstType != MapEntry.NoReference) { - sb.append(' ').append(formatter.formatRegister(idx)).append(':').append(dstType); - } - } - } - - @Override - public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) { - for (int idx = 0; idx < frameRefMap.size(); idx++) { - MapEntry dstType = MapEntry.getFromBits(idx, frameRefMap); - if (dstType != MapEntry.NoReference) { - sb.append(' ').append(formatter.formatStackSlot(idx)).append(':').append(dstType); - } - } - } - - @Override public String toString() { - StringBuilder sb = new StringBuilder(); - if (registerRefMap != null) { - sb.append("Registers = "); - sb.append(registerRefMap); - } - sb.append("Stack = "); - sb.append(frameRefMap); - return sb.toString(); - } - - public void verify() { - assert verifyUpdate(frameRefMap, frameRefMap); - assert registerRefMap == null || verifyUpdate(registerRefMap, registerRefMap); + return Arrays.toString(objects); } } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java --- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotTargetDescription.java Fri Jun 05 17:12:08 2015 +0200 @@ -32,6 +32,6 @@ @Override public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { - return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this); + return new HotSpotReferenceMap(this); } } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java --- a/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.meta/src/com/oracle/jvmci/meta/Value.java Fri Jun 05 17:12:08 2015 +0200 @@ -28,7 +28,14 @@ */ public interface Value extends KindProvider, TrustedInterface { - AllocatableValue ILLEGAL = new AllocatableValue(LIRKind.Illegal) { + Value[] NO_VALUES = new Value[0]; + + AllocatableValue ILLEGAL = new IllegalValue(); + + public final class IllegalValue extends AllocatableValue { + private IllegalValue() { + super(LIRKind.Illegal); + } @Override public String toString() { @@ -39,9 +46,9 @@ public boolean equals(Object other) { // Due to de-serialization this object may exist multiple times. So we compare classes // instead of the individual objects. (This anonymous class has always the same meaning) - return other != null && this.getClass() == other.getClass(); + return other instanceof IllegalValue; } - }; + } LIRKind getLIRKind(); diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java --- a/graal/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java Fri Jun 05 17:12:08 2015 +0200 @@ -38,6 +38,7 @@ public class ServiceProviderProcessor extends AbstractProcessor { private final Set processed = new HashSet<>(); + private TypeElement baseJVMCIServiceInterface; @Override public SourceVersion getSupportedSourceVersion() { @@ -45,6 +46,11 @@ } private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) { + if (!processingEnv.getTypeUtils().isSubtype(serviceInterface, baseJVMCIServiceInterface.asType())) { + String msg = String.format("Service interface class %s doesn't extend JVMCI service interface %s", serviceInterface, baseJVMCIServiceInterface); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider); + return false; + } if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) { String msg = String.format("Service provider class %s doesn't implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider); @@ -101,6 +107,8 @@ return true; } + baseJVMCIServiceInterface = processingEnv.getElementUtils().getTypeElement("com.oracle.jvmci.service.Service"); + for (Element element : roundEnv.getElementsAnnotatedWith(ServiceProvider.class)) { assert element.getKind().isClass(); processElement((TypeElement) element); diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java Fri Jun 05 17:12:08 2015 +0200 @@ -29,6 +29,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.DoubleChildNodeFactory; +import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.ShortCircuitWithImplicitCastNodeFactory; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.SingleChildNodeFactory; import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.VarArgsNodeFactory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; @@ -160,4 +161,38 @@ } + @Test + public void testShortCircuitWithImplicitCastNode() { + ArgumentNode arg0 = new ArgumentNode(0); + ArgumentNode arg1 = new ArgumentNode(1); + CallTarget callTarget = TestHelper.createCallTarget(ShortCircuitWithImplicitCastNodeFactory.create(new ValueNode[]{arg0, arg1})); + assertEquals(42, callTarget.call(new Object[]{42, 41})); + } + + @TypeSystem(int.class) + abstract static class ShortCircuitWithImplicitCastTypes { + + @ImplicitCast + public static int doAnImplicitCast(String foo) { + return Integer.parseInt(foo); + } + + } + + @NodeChild(value = "children", type = ValueNode[].class) + @TypeSystemReference(ShortCircuitWithImplicitCastTypes.class) + abstract static class ShortCircuitWithImplicitCastNode extends ValueNode { + + @ShortCircuit("children[1]") + public boolean needsRightNode(Object left) { + return (int) left == 41; + } + + @Specialization + public int doInteger(int left, boolean needsRight, int right) { + return needsRight ? right : left; + } + + } + } diff -r 30b4de402a58 -r f60f7994c5a5 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java Fri Jun 05 17:11:50 2015 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java Fri Jun 05 17:12:08 2015 +0200 @@ -410,6 +410,11 @@ builder.end(); } + builder.startElseIf().string(LOCAL_VALUE).string(" == ").nullLiteral().end(); + builder.startBlock(); + builder.startReturn().typeLiteral(context.getType(Object.class)).end(); + builder.end(); + builder.startElseBlock(); builder.tree(createTransferToInterpreterAndInvalidate()); builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); diff -r 30b4de402a58 -r f60f7994c5a5 make/Makefile --- a/make/Makefile Fri Jun 05 17:11:50 2015 +0200 +++ b/make/Makefile Fri Jun 05 17:12:08 2015 +0200 @@ -309,21 +309,25 @@ $(MAKE_ARGS) $(VM_TARGET) - -ifeq (, $(shell python2.7 --version 2>/dev/null && echo ok)) - ifeq (, $(shell python2.6 --version 2>/dev/null && echo ok)) - PYTHON=python +ifeq ($(JVMCI_USE_MAKE),) + ifeq (, $(shell python2.7 --version 2>/dev/null && echo ok)) + ifeq (, $(shell python2.6 --version 2>/dev/null && echo ok)) + PYTHON=python + else + PYTHON=python2.6 + endif else - PYTHON=python2.6 + PYTHON=python2.7 endif + + # Builds code that can be shared among different build flavors +buildshared: + $(PYTHON) -u $(GAMMADIR)/mxtool/mx.py build --no-native --export-dir $(SHARED_DIR) else - PYTHON=python2.7 +buildshared: + cd .. && $(MAKE) -f make/jvmci.make TARGET=build/make MX_TARGET=. HS_COMMON_SRC=$(HS_COMMON_SRC) JDK=$(ABS_BOOTDIR) EXPORT_DIR=$(SHARED_DIR) export endif -# Builds code that can be shared among different build flavors -buildshared: - $(PYTHON) -u $(GAMMADIR)/mxtool/mx.py build --no-native --export-dir $(SHARED_DIR) - #cd .. && $(MAKE) -f make/jvmci.make TARGET=build/make MX_TARGET=. HS_COMMON_SRC=$(HS_COMMON_SRC) JDK=$(ABS_BOOTDIR) EXPORT_DIR=$(SHARED_DIR) VERBOSE=0 export # Export file rule generic_export: $(EXPORT_LIST) diff -r 30b4de402a58 -r f60f7994c5a5 make/defs.make --- a/make/defs.make Fri Jun 05 17:11:50 2015 +0200 +++ b/make/defs.make Fri Jun 05 17:12:08 2015 +0200 @@ -360,36 +360,42 @@ EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/jvmci-service.jar -EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/truffle.jar -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/graal.jar -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/graal-truffle.jar EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/jvmci-api.jar EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/jvmci-hotspot.jar EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.HotSpotJVMCIBackendFactory -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.HotSpotVMEventListener -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugInitializationPropertyProvider ifneq ("$(wildcard $(SHARED_DIR)/services/com.oracle.jvmci.hotspot.events.EventProvider)","") EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.events.EventProvider endif +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotConstantReflectionProvider +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaFieldImpl +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaMethodImpl + +ifeq ($(JVMCI_USE_MAKE),) +EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/truffle.jar +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/graal.jar +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/graal-truffle.jar + +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.HotSpotVMEventListener + +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugInitializationPropertyProvider + EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.api.runtime.GraalRuntimeAccess +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.code.DisassemblerProvider EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.compiler.match.MatchStatementSet EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.hotspot.HotSpotBackendFactory EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.nodes.spi.ReplacementsProvider EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.phases.tiers.CompilerConfiguration EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.truffle.hotspot.nfi.RawNativeCallNodeFactory EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.truffle.OptimizedCallTargetInstrumentationFactory +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.truffle.LoopNodeFactory EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.truffle.api.TruffleRuntimeAccess EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.nfi.api.NativeFunctionInterfaceAccess -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotConstantReflectionProvider -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaFieldImpl -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaMethodImpl - EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.compiler.common.GraalOptions EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.compiler.GraalCompiler EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.compiler.GraalDebugConfig @@ -423,6 +429,7 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.virtual.phases.ea.PartialEscapePhase EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.lir.asm.CompilationResultBuilder EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.graal.java.BytecodeParser +endif .PHONY: $(HS_ALT_MAKE)/defs.make diff -r 30b4de402a58 -r f60f7994c5a5 make/jvmci.make --- a/make/jvmci.make Fri Jun 05 17:11:50 2015 +0200 +++ b/make/jvmci.make Fri Jun 05 17:12:08 2015 +0200 @@ -1,4 +1,4 @@ -[?1034hVERBOSE= +VERBOSE= TARGET=. JDK= @@ -27,7 +27,7 @@ $(eval services=$(1)/$(SERVICES_INF)) $(eval options=$(1)/$(OPTIONS_INF)) test -d $(services) || mkdir -p $(services) - test ! -d $(providers) || (cd $(providers) && for i in $$(ls $(providers)); do c=$$(cat $$i); echo $$i >> $(services)$$c; rm $$i; done) + test ! -d $(providers) || (cd $(providers) && for i in $$(ls); do c=$$(cat $$i); echo $$i >> $(abspath $(services))/$$c; rm $$i; done) # We're building all projects together with one javac call; thus we cannot determine, from which project the generated file is thus we hardcode it for now $(eval vmconfig=$(1)/hotspot/HotSpotVMConfig.inline.hpp) @@ -36,8 +36,8 @@ endef define extract = - $(eval TMP := $(shell mktemp -d)) - mkdir -p $(2); + $(eval TMP := $(shell mktemp -d $(1)_XXXXX)) + mkdir -p $(2) cd $(TMP) && $(JAR) xf $(abspath $(1)) && ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2)))) rm -r $(TMP) cp $(1) $(2) @@ -53,12 +53,6 @@ -EXPORTED_FILES += $(MX_TARGET)/build/truffle.jar - -EXPORTED_FILES += $(MX_TARGET)/build/graal.jar - -EXPORTED_FILES += $(MX_TARGET)/build/graal-truffle.jar - JDK_BOOTCLASSPATH = $(JDK)/jre/lib/resources.jar:$(JDK)/jre/lib/rt.jar:$(JDK)/jre/lib/jsse.jar:$(JDK)/jre/lib/jce.jar:$(JDK)/jre/lib/charsets.jar:$(JDK)/jre/lib/jfr.jar COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_SRC = $(shell find graal/com.oracle.jvmci.hotspotvmconfig/src -type f -name *.java 2> /dev/null) @@ -78,18 +72,26 @@ COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR = $(TARGET)/graal/com.oracle.jvmci.options.processor/ap/com.oracle.jvmci.options.processor.jar -JVMCI_UTIL_SRC = $(shell find graal/com.oracle.jvmci.bytecode/src -type f -name *.java 2> /dev/null) -JVMCI_UTIL_SRC += $(shell find graal/com.oracle.jvmci.asm/src -type f -name *.java 2> /dev/null) -JVMCI_UTIL_SRC += $(shell find graal/com.oracle.jvmci.amd64/src -type f -name *.java 2> /dev/null) -JVMCI_UTIL_SRC += $(shell find graal/com.oracle.jvmci.asm.amd64/src -type f -name *.java 2> /dev/null) -JVMCI_UTIL_SRC += $(shell find graal/com.oracle.jvmci.sparc/src -type f -name *.java 2> /dev/null) -JVMCI_UTIL_SRC += $(shell find graal/com.oracle.jvmci.asm.sparc/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC = $(shell find graal/com.oracle.jvmci.hotspotvmconfig/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspotvmconfig/graal/com.oracle.jvmci.hotspotvmconfig/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.amd64/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.amd64/graal/com.oracle.jvmci.amd64/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot/graal/com.oracle.jvmci.hotspot/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.amd64/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.amd64/graal/com.oracle.jvmci.hotspot.amd64/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.sparc/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.sparc/graal/com.oracle.jvmci.sparc/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.sparc/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.sparc/graal/com.oracle.jvmci.hotspot.sparc/src_gen -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.jfr/src -type f -name *.java 2> /dev/null) +JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.jfr/graal/com.oracle.jvmci.hotspot.jfr/src_gen -type f -name *.java 2> /dev/null) -JVMCI_UTIL_JAR = $(TARGET)/build/jvmci-util.jar +JVMCI_HOTSPOT_JAR = $(TARGET)/build/jvmci-hotspot.jar -JVMCI_UTIL_DEP_JARS = $(TARGET)/build/jvmci-service.jar $(TARGET)/build/jvmci-api.jar +JVMCI_HOTSPOT_DEP_JARS = $(TARGET)/build/jvmci-service.jar $(TARGET)/build/jvmci-api.jar graal/findbugs-SuppressFBWarnings.jar -EXPORTED_FILES += $(JVMCI_UTIL_JAR) +EXPORTED_FILES += $(JVMCI_HOTSPOT_JAR) JVMCI_SERVICE_SRC = $(shell find graal/com.oracle.jvmci.service/src -type f -name *.java 2> /dev/null) @@ -99,23 +101,6 @@ EXPORTED_FILES += $(JVMCI_SERVICE_JAR) -JVMCI_HOTSPOT_SRC = $(shell find graal/com.oracle.jvmci.hotspotvmconfig/src -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspotvmconfig/graal/com.oracle.jvmci.hotspotvmconfig/src_gen -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot/src -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot/graal/com.oracle.jvmci.hotspot/src_gen -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.amd64/src -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.amd64/graal/com.oracle.jvmci.hotspot.amd64/src_gen -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.sparc/src -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.sparc/graal/com.oracle.jvmci.hotspot.sparc/src_gen -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.jfr/src -type f -name *.java 2> /dev/null) -JVMCI_HOTSPOT_SRC += $(shell find graal/com.oracle.jvmci.hotspot.jfr/graal/com.oracle.jvmci.hotspot.jfr/src_gen -type f -name *.java 2> /dev/null) - -JVMCI_HOTSPOT_JAR = $(TARGET)/build/jvmci-hotspot.jar - -JVMCI_HOTSPOT_DEP_JARS = $(TARGET)/build/jvmci-util.jar $(TARGET)/build/jvmci-service.jar $(TARGET)/build/jvmci-api.jar graal/findbugs-SuppressFBWarnings.jar - -EXPORTED_FILES += $(JVMCI_HOTSPOT_JAR) - JVMCI_API_SRC = $(shell find graal/com.oracle.jvmci.meta/src -type f -name *.java 2> /dev/null) JVMCI_API_SRC += $(shell find graal/com.oracle.jvmci.code/src -type f -name *.java 2> /dev/null) JVMCI_API_SRC += $(shell find graal/com.oracle.jvmci.runtime/src -type f -name *.java 2> /dev/null) @@ -130,7 +115,7 @@ EXPORTED_FILES += $(JVMCI_API_JAR) $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_JAR): $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_SRC) - $(eval TMP := $(shell mktemp -d)) + $(eval TMP := $(shell mktemp -d COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_XXXXX)) $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_SRC) cp -r graal/com.oracle.jvmci.hotspotvmconfig.processor/src/META-INF $(TMP) $(call process_options,$(TMP),False) @@ -139,7 +124,7 @@ rm -r $(TMP) $(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_JAR): $(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_SRC) - $(eval TMP := $(shell mktemp -d)) + $(eval TMP := $(shell mktemp -d COM_ORACLE_JVMCI_SERVICE_PROCESSOR_XXXXX)) $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) $(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_SRC) cp -r graal/com.oracle.jvmci.service.processor/src/META-INF $(TMP) $(call process_options,$(TMP),False) @@ -148,7 +133,7 @@ rm -r $(TMP) $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR): $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_SRC) - $(eval TMP := $(shell mktemp -d)) + $(eval TMP := $(shell mktemp -d COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_XXXXX)) $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_SRC) cp -r graal/com.oracle.jvmci.options.processor/src/META-INF $(TMP) $(call process_options,$(TMP),False) @@ -156,17 +141,17 @@ $(JAR) cf $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR) -C $(TMP) . rm -r $(TMP) -$(JVMCI_UTIL_JAR): $(JVMCI_UTIL_SRC) $(JVMCI_UTIL_DEP_JARS) - $(eval TMP := $(shell mktemp -d)) - $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) -cp $(TARGET)/build/jvmci-service.jar:$(TARGET)/build/jvmci-api.jar $(JVMCI_UTIL_SRC) +$(JVMCI_HOTSPOT_JAR): $(JVMCI_HOTSPOT_SRC) $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_JAR) $(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_JAR) $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR) $(JVMCI_HOTSPOT_DEP_JARS) + $(eval TMP := $(shell mktemp -d JVMCI_HOTSPOT_XXXXX)) + $(JAVAC) -d $(TMP) -processorpath $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_JAR):$(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_JAR):$(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR) -bootclasspath $(JDK_BOOTCLASSPATH) -cp $(TARGET)/build/jvmci-service.jar:$(TARGET)/build/jvmci-api.jar:graal/findbugs-SuppressFBWarnings.jar $(JVMCI_HOTSPOT_SRC) $(call process_options,$(TMP),True) - mkdir -p $$(dirname $(JVMCI_UTIL_JAR)) - $(JAR) cf $(JVMCI_UTIL_JAR) -C $(TMP) . + mkdir -p $$(dirname $(JVMCI_HOTSPOT_JAR)) + $(JAR) cf $(JVMCI_HOTSPOT_JAR) -C $(TMP) . rm -r $(TMP) $(JVMCI_SERVICE_JAR): $(JVMCI_SERVICE_SRC) $(JVMCI_SERVICE_DEP_JARS) - $(eval TMP := $(shell mktemp -d)) + $(eval TMP := $(shell mktemp -d JVMCI_SERVICE_XXXXX)) $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) -cp graal/findbugs-SuppressFBWarnings.jar $(JVMCI_SERVICE_SRC) $(call process_options,$(TMP),True) @@ -174,17 +159,8 @@ $(JAR) cf $(JVMCI_SERVICE_JAR) -C $(TMP) . rm -r $(TMP) -$(JVMCI_HOTSPOT_JAR): $(JVMCI_HOTSPOT_SRC) $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_JAR) $(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_JAR) $(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR) $(JVMCI_HOTSPOT_DEP_JARS) - $(eval TMP := $(shell mktemp -d)) - $(JAVAC) -d $(TMP) -processorpath $(COM_ORACLE_JVMCI_HOTSPOTVMCONFIG_PROCESSOR_JAR):$(COM_ORACLE_JVMCI_SERVICE_PROCESSOR_JAR):$(COM_ORACLE_JVMCI_OPTIONS_PROCESSOR_JAR) -bootclasspath $(JDK_BOOTCLASSPATH) -cp $(TARGET)/build/jvmci-util.jar:$(TARGET)/build/jvmci-service.jar:$(TARGET)/build/jvmci-api.jar:graal/findbugs-SuppressFBWarnings.jar $(JVMCI_HOTSPOT_SRC) - - $(call process_options,$(TMP),True) - mkdir -p $$(dirname $(JVMCI_HOTSPOT_JAR)) - $(JAR) cf $(JVMCI_HOTSPOT_JAR) -C $(TMP) . - rm -r $(TMP) - $(JVMCI_API_JAR): $(JVMCI_API_SRC) $(JVMCI_API_DEP_JARS) - $(eval TMP := $(shell mktemp -d)) + $(eval TMP := $(shell mktemp -d JVMCI_API_XXXXX)) $(JAVAC) -d $(TMP) -bootclasspath $(JDK_BOOTCLASSPATH) -cp $(TARGET)/build/jvmci-service.jar:graal/findbugs-SuppressFBWarnings.jar $(JVMCI_API_SRC) $(call process_options,$(TMP),True) @@ -192,5 +168,5 @@ $(JAR) cf $(JVMCI_API_JAR) -C $(TMP) . rm -r $(TMP) -default: $(JVMCI_UTIL_JAR) $(JVMCI_SERVICE_JAR) $(JVMCI_HOTSPOT_JAR) $(JVMCI_API_JAR) -.PHONY: default +default: $(JVMCI_HOTSPOT_JAR) $(JVMCI_SERVICE_JAR) $(JVMCI_API_JAR) +.PHONY: default \ No newline at end of file diff -r 30b4de402a58 -r f60f7994c5a5 make/solaris/makefiles/defs.make --- a/make/solaris/makefiles/defs.make Fri Jun 05 17:11:50 2015 +0200 +++ b/make/solaris/makefiles/defs.make Fri Jun 05 17:12:08 2015 +0200 @@ -304,4 +304,3 @@ endif endif EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar -EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugInitializationPropertyProvider diff -r 30b4de402a58 -r f60f7994c5a5 mx/mx_graal.py --- a/mx/mx_graal.py Fri Jun 05 17:11:50 2015 +0200 +++ b/mx/mx_graal.py Fri Jun 05 17:12:08 2015 +0200 @@ -90,16 +90,17 @@ _untilVersion = None class JDKDeployedDist: - def __init__(self, name, isExtension=False, usesJVMCIClassLoader=False): + def __init__(self, name, isExtension=False, usesJVMCIClassLoader=False, partOfHotSpot=False): self.name = name self.isExtension = isExtension self.usesJVMCIClassLoader = usesJVMCIClassLoader + self.partOfHotSpot = partOfHotSpot # true when this distribution is delivered with HotSpot _jdkDeployedDists = [ JDKDeployedDist('TRUFFLE'), - JDKDeployedDist('JVMCI_SERVICE'), - JDKDeployedDist('JVMCI_API', usesJVMCIClassLoader=True), - JDKDeployedDist('JVMCI_HOTSPOT', usesJVMCIClassLoader=True), + JDKDeployedDist('JVMCI_SERVICE', partOfHotSpot=True), + JDKDeployedDist('JVMCI_API', usesJVMCIClassLoader=True, partOfHotSpot=True), + JDKDeployedDist('JVMCI_HOTSPOT', usesJVMCIClassLoader=True, partOfHotSpot=True), JDKDeployedDist('GRAAL', usesJVMCIClassLoader=True), JDKDeployedDist('GRAAL_TRUFFLE', usesJVMCIClassLoader=True) ] @@ -494,7 +495,7 @@ if installJars: for jdkDist in _jdkDeployedDists: dist = mx.distribution(jdkDist.name) - if exists(dist.path): + if exists(dist.path) and jdkDist.partOfHotSpot: _installDistInJdks(jdkDist) if vmToCheck is not None: @@ -665,7 +666,6 @@ """ Installs the jar(s) for a given Distribution into all existing JVMCI JDKs """ - dist = mx.distribution(deployableDist.name) if dist.name == 'GRAAL': _patchGraalVersionConstant(dist) @@ -838,6 +838,12 @@ The global '--vm' and '--vmbuild' options select which VM type and build target to build.""" + # Turn all jdk distributions into non HotSpot; this is only necessary as long we support building/exporting JVMCI with make and mx + if not ("-m" in args or "--use-make" in args): + for jdkDist in _jdkDeployedDists: + if jdkDist.partOfHotSpot: + jdkDist.partOfHotSpot = False + # Override to fail quickly if extra arguments are given # at the end of the command line. This allows for a more # helpful error message. @@ -856,6 +862,7 @@ parser = AP() parser.add_argument('--export-dir', help='directory to which JVMCI and Graal jars and jvmci.options will be copied', metavar='') parser.add_argument('-D', action='append', help='set a HotSpot build variable (run \'mx buildvars\' to list variables)', metavar='name=value') + parser.add_argument('-m', '--use-make', action='store_true', help='Use the jvmci.make file to build and export JVMCI') opts2 = mx.build(['--source', '1.7'] + args, parser=parser) assert len(opts2.remainder) == 0 @@ -883,16 +890,18 @@ defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path) if defLine not in defs: mx.abort('Missing following line in ' + defsPath + '\n' + defLine) - shutil.copy(dist.path, opts2.export_dir) + shutil.copy(dist.path, opts2.export_dir) + services, optionsFiles = _extractJVMCIFiles(jdkJars, jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options')) - for service in services: - defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service - if defLine not in defs: - mx.abort('Missing following line in ' + defsPath + ' for service from ' + dist.name + '\n' + defLine) - for optionsFile in optionsFiles: - defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/' + optionsFile - if defLine not in defs: - mx.abort('Missing following line in ' + defsPath + ' for options from ' + dist.name + '\n' + defLine) + if not opts2.use_make: + for service in services: + defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service + if defLine not in defs: + mx.abort('Missing following line in ' + defsPath + ' for service from ' + dist.name + '\n' + defLine) + for optionsFile in optionsFiles: + defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/' + optionsFile + if defLine not in defs: + mx.abort('Missing following line in ' + defsPath + ' for options from ' + dist.name + '\n' + defLine) jvmciOptions = join(_graal_home, 'jvmci.options') if exists(jvmciOptions): shutil.copy(jvmciOptions, opts2.export_dir) @@ -1019,6 +1028,7 @@ setMakeVar('ARCH_DATA_MODEL', '64', env=env) setMakeVar('HOTSPOT_BUILD_JOBS', str(cpus), env=env) setMakeVar('ALT_BOOTDIR', mx.java().jdk, env=env) + setMakeVar("EXPORT_PATH", jdk) setMakeVar('MAKE_VERBOSE', 'y' if mx._opts.verbose else '') if vm.endswith('nojvmci'): @@ -1044,7 +1054,8 @@ setMakeVar('STRIP_POLICY', 'no_strip') # This removes the need to unzip the *.diz files before debugging in gdb setMakeVar('ZIP_DEBUGINFO_FILES', '0', env=env) - + if opts2.use_make: + setMakeVar('JVMCI_USE_MAKE', '1') # Clear this variable as having it set can cause very confusing build problems env.pop('CLASSPATH', None) @@ -1055,8 +1066,8 @@ envPrefix = ' '.join([key + '=' + env[key] for key in env.iterkeys() if not os.environ.has_key(key) or env[key] != os.environ[key]]) if len(envPrefix): mx.log('env ' + envPrefix + ' \\') - - runCmd.append(build + buildSuffix) + makeTarget = "all_" + build + buildSuffix if opts2.use_make else build + buildSuffix + runCmd.append(makeTarget) if not mx._opts.verbose: mx.log(' '.join(runCmd)) @@ -1093,6 +1104,9 @@ # Legacy support f.write('-graal ALIASED_TO -jvmci\n') + for jdkDist in _jdkDeployedDists: # Install non HotSpot distribution + if not jdkDist.partOfHotSpot: + _installDistInJdks(jdkDist) if exists(timestampFile): os.utime(timestampFile, None) else: @@ -2698,6 +2712,7 @@ def _close(jdkDeployable): def _install(dist): assert dist.name == jdkDeployable.name, dist.name + "!=" + jdkDeployable.name - _installDistInJdks(jdkDeployable) + if not jdkDist.partOfHotSpot: + _installDistInJdks(jdkDeployable) return _install mx.distribution(jdkDist.name).add_update_listener(_close(jdkDist)) diff -r 30b4de402a58 -r f60f7994c5a5 mx/mx_graal_makefile.py --- a/mx/mx_graal_makefile.py Fri Jun 05 17:11:50 2015 +0200 +++ b/mx/mx_graal_makefile.py Fri Jun 05 17:12:08 2015 +0200 @@ -51,8 +51,7 @@ args = parser.parse_args(args) if args.selectedDists == None or len(args.selectedDists) == 0: - parser.print_help() - return + args.selectedDists = [d.name for d in mx_graal._jdkDeployedDists if d.partOfHotSpot] mf = Makefile() if do_build_makefile(mf, args.selectedDists): contents = mf.generate() @@ -144,7 +143,7 @@ if len(classPath) > 0: mf.add_definition("{depJarsVariable} = {jarDeps}".format(**props)) if shouldExport: mf.add_definition("EXPORTED_FILES += $({name}_JAR)".format(**props)) mf.add_rule("""$({name}_JAR): $({sourcesVariableName}) {annotationProcessors} {depJarsVariableAccess} -\t$(eval TMP := $(shell mktemp -d)) +\t$(eval TMP := $(shell mktemp -d {name}_XXXXX)) \t$(JAVAC) -d $(TMP) {cpAnnotationProcessors} {bootCp} {cpDeps} $({sourcesVariableName}) \t{copyResources} \t$(call process_options,$(TMP),{shouldExport}) @@ -190,7 +189,7 @@ $(eval services=$(1)/$(SERVICES_INF)) $(eval options=$(1)/$(OPTIONS_INF)) test -d $(services) || mkdir -p $(services) - test ! -d $(providers) || (cd $(providers) && for i in $$(ls $(providers)); do c=$$(cat $$i); echo $$i >> $(services)$$c; rm $$i; done) + test ! -d $(providers) || (cd $(providers) && for i in $$(ls); do c=$$(cat $$i); echo $$i >> $(abspath $(services))/$$c; rm $$i; done) # We're building all projects together with one javac call; thus we cannot determine, from which project the generated file is thus we hardcode it for now $(eval vmconfig=$(1)/hotspot/HotSpotVMConfig.inline.hpp) @@ -199,8 +198,8 @@ endef define extract = - $(eval TMP := $(shell mktemp -d)) - mkdir -p $(2); + $(eval TMP := $(shell mktemp -d $(1)_XXXXX)) + mkdir -p $(2) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \ ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2)))) rm -r $(TMP) @@ -224,6 +223,7 @@ if d.name in selectedDists: dists.update(d.get_dist_deps(True, True)) projects.update(d.sorted_deps(includeLibs=False, transitive=True)) + for p in projects: deps = p.all_deps([], False, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=True) for d in deps: @@ -231,11 +231,6 @@ apd = d.definedAnnotationProcessorsDist ap.add(apd) - for d in mx_graal._jdkDeployedDists: - dist = mx.distribution(d.name) - if dist not in dists: # this sould go away - mf.add_definition("EXPORTED_FILES += $(MX_TARGET)/{}".format(os.path.relpath(dist.path, dist.suite.dir))) - if len(dists) > 0: mf.add_definition(jdkBootClassPathVariableName + " = " + bootClassPath) bootClassPathVarAccess = "$(" + jdkBootClassPathVariableName + ")" diff -r 30b4de402a58 -r f60f7994c5a5 mx/suite.py --- a/mx/suite.py Fri Jun 05 17:11:50 2015 +0200 +++ b/mx/suite.py Fri Jun 05 17:12:08 2015 +0200 @@ -284,74 +284,6 @@ "workingSets" : "JVMCI", }, - # ------------- JVMCI:Util ------------- - - "com.oracle.graal.asm" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "dependencies" : ["com.oracle.jvmci.code"], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Assembler", - }, - - "com.oracle.graal.asm.amd64" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "dependencies" : [ - "com.oracle.graal.asm", - "com.oracle.jvmci.amd64", - ], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Assembler,AMD64", - }, - - "com.oracle.graal.asm.sparc" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "dependencies" : [ - "com.oracle.graal.asm", - "com.oracle.jvmci.sparc", - ], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Assembler,SPARC", - }, - - "com.oracle.graal.bytecode" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Java", - }, - - "com.oracle.graal.asm.test" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "dependencies" : [ - "com.oracle.graal.test", - "com.oracle.jvmci.runtime", - ], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Assembler,Test", - }, - - "com.oracle.graal.asm.amd64.test" : { - "subDir" : "graal", - "sourceDirs" : ["src"], - "dependencies" : [ - "com.oracle.graal.asm.test", - "com.oracle.jvmci.common", - "com.oracle.graal.asm.amd64", - ], - "checkstyle" : "com.oracle.graal.graph", - "javaCompliance" : "1.8", - "workingSets" : "Graal,Assembler,AMD64,Test", - }, - # ------------- JVMCI:HotSpot ------------- "com.oracle.jvmci.amd64" : { @@ -473,6 +405,19 @@ # ------------- Graal ------------- + "com.oracle.graal.code" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.jvmci.service", + "com.oracle.jvmci.code", + ], + "annotationProcessors" : ["com.oracle.jvmci.service.processor"], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal", + }, + "com.oracle.graal.api.collections" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -650,6 +595,73 @@ "workingSets" : "Graal,Graph,Test", }, + "com.oracle.graal.asm" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : ["com.oracle.jvmci.code"], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Assembler", + }, + + "com.oracle.graal.asm.amd64" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.asm", + "com.oracle.jvmci.amd64", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Assembler,AMD64", + }, + + "com.oracle.graal.asm.sparc" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.asm", + "com.oracle.jvmci.sparc", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Assembler,SPARC", + }, + + "com.oracle.graal.bytecode" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Java", + }, + + "com.oracle.graal.asm.test" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.code", + "com.oracle.graal.test", + "com.oracle.jvmci.runtime", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Assembler,Test", + }, + + "com.oracle.graal.asm.amd64.test" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.asm.test", + "com.oracle.jvmci.common", + "com.oracle.graal.asm.amd64", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "Graal,Assembler,AMD64,Test", + }, + "com.oracle.graal.lir" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -1004,6 +1016,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.graal.code", "com.oracle.graal.java", "com.oracle.graal.compiler", ], diff -r 30b4de402a58 -r f60f7994c5a5 src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jun 05 17:12:08 2015 +0200 @@ -70,32 +70,9 @@ // Capture info about frame layout. Layout offsets are in jint // units because compiler frame slots are jints. #define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off -#define DEF_YMM_HI_OFFS(regnum) ymm_hi ## regnum ## _off = ymm_off + (regnum)*16/BytesPerInt enum layout { fpu_state_off = frame::arg_reg_save_area_bytes/BytesPerInt, // fxsave save area -#if defined(COMPILER2) || defined(JVMCI) - ymm_off = fpu_state_off, // offset in fxsave save area - DEF_YMM_HI_OFFS(0), - DEF_YMM_HI_OFFS(1), - DEF_YMM_HI_OFFS(2), - DEF_YMM_HI_OFFS(3), - DEF_YMM_HI_OFFS(4), - DEF_YMM_HI_OFFS(5), - DEF_YMM_HI_OFFS(6), - DEF_YMM_HI_OFFS(7), - DEF_YMM_HI_OFFS(8), - DEF_YMM_HI_OFFS(9), - DEF_YMM_HI_OFFS(10), - DEF_YMM_HI_OFFS(11), - DEF_YMM_HI_OFFS(12), - DEF_YMM_HI_OFFS(13), - DEF_YMM_HI_OFFS(14), - DEF_YMM_HI_OFFS(15), - ymm_hi_save_size = 16 * 16 / BytesPerInt, -#else - ymm_hi_save_size = 0, -#endif - xmm_off = fpu_state_off + 160/BytesPerInt + ymm_hi_save_size, // offset in fxsave save area + xmm_off = fpu_state_off + 160/BytesPerInt, // offset in fxsave save area DEF_XMM_OFFS(0), DEF_XMM_OFFS(1), DEF_XMM_OFFS(2), @@ -112,7 +89,7 @@ DEF_XMM_OFFS(13), DEF_XMM_OFFS(14), DEF_XMM_OFFS(15), - fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt) + ymm_hi_save_size, + fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt), fpu_stateH_end, r15_off, r15H_off, r14_off, r14H_off, @@ -162,6 +139,21 @@ }; OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { + int vect_words = 0; + int ymmhi_offset = -1; +#if defined(COMPILER2) || defined(JVMCI) + if (save_vectors) { + assert(UseAVX > 0, "256bit vectors are supported only with AVX"); + assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); + // Save upper half of YMM registes + vect_words = 16 * 16 / wordSize; + ymmhi_offset = additional_frame_words; + additional_frame_words += vect_words; + } +#else + assert(!save_vectors, "vectors are generated only by C2 and JVMCI"); +#endif + // Always make the frame size 16-byte aligned int frame_size_in_bytes = round_to(additional_frame_words*wordSize + reg_save_size*BytesPerInt, 16); @@ -182,32 +174,26 @@ __ enter(); // rsp becomes 16-byte aligned here __ push_CPU_state(); // Push a multiple of 16 bytes -#if defined(COMPILER2) || defined(JVMCI) - __ subptr(rsp, 256); // Save upper half of YMM registers - if (save_vectors) { - assert(UseAVX > 0, "256bit vectors are supported only with AVX"); - assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); - // Save upper half of YMM registers - __ vextractf128h(Address(rsp, ymm_hi0_off * BytesPerInt), xmm0); - __ vextractf128h(Address(rsp, ymm_hi1_off * BytesPerInt), xmm1); - __ vextractf128h(Address(rsp, ymm_hi2_off * BytesPerInt), xmm2); - __ vextractf128h(Address(rsp, ymm_hi3_off * BytesPerInt), xmm3); - __ vextractf128h(Address(rsp, ymm_hi4_off * BytesPerInt), xmm4); - __ vextractf128h(Address(rsp, ymm_hi5_off * BytesPerInt), xmm5); - __ vextractf128h(Address(rsp, ymm_hi6_off * BytesPerInt), xmm6); - __ vextractf128h(Address(rsp, ymm_hi7_off * BytesPerInt), xmm7); - __ vextractf128h(Address(rsp, ymm_hi8_off * BytesPerInt), xmm8); - __ vextractf128h(Address(rsp, ymm_hi9_off * BytesPerInt), xmm9); - __ vextractf128h(Address(rsp, ymm_hi10_off * BytesPerInt), xmm10); - __ vextractf128h(Address(rsp, ymm_hi11_off * BytesPerInt), xmm11); - __ vextractf128h(Address(rsp, ymm_hi12_off * BytesPerInt), xmm12); - __ vextractf128h(Address(rsp, ymm_hi13_off * BytesPerInt), xmm13); - __ vextractf128h(Address(rsp, ymm_hi14_off * BytesPerInt), xmm14); - __ vextractf128h(Address(rsp, ymm_hi15_off * BytesPerInt), xmm15); + if (vect_words > 0) { + assert(vect_words*wordSize == 256, ""); + __ subptr(rsp, 256); // Save upper half of YMM registes + __ vextractf128h(Address(rsp, 0),xmm0); + __ vextractf128h(Address(rsp, 16),xmm1); + __ vextractf128h(Address(rsp, 32),xmm2); + __ vextractf128h(Address(rsp, 48),xmm3); + __ vextractf128h(Address(rsp, 64),xmm4); + __ vextractf128h(Address(rsp, 80),xmm5); + __ vextractf128h(Address(rsp, 96),xmm6); + __ vextractf128h(Address(rsp,112),xmm7); + __ vextractf128h(Address(rsp,128),xmm8); + __ vextractf128h(Address(rsp,144),xmm9); + __ vextractf128h(Address(rsp,160),xmm10); + __ vextractf128h(Address(rsp,176),xmm11); + __ vextractf128h(Address(rsp,192),xmm12); + __ vextractf128h(Address(rsp,208),xmm13); + __ vextractf128h(Address(rsp,224),xmm14); + __ vextractf128h(Address(rsp,240),xmm15); } -#else - assert(!save_vectors, "vectors are generated only by C2 and JVMCI"); -#endif if (frame::arg_reg_save_area_bytes != 0) { // Allocate argument register save area __ subptr(rsp, frame::arg_reg_save_area_bytes); @@ -222,6 +208,7 @@ OopMap* map = new OopMap(frame_size_in_slots, 0); #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots) +#define YMMHI_STACK_OFFSET(x) VMRegImpl::stack2reg((x) + ymmhi_offset) map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg()); map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg()); @@ -259,22 +246,23 @@ #if defined(COMPILER2) || defined(JVMCI) if (save_vectors) { - map->set_callee_saved(STACK_OFFSET(ymm_hi0_off ), xmm0->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi1_off ), xmm1->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi2_off ), xmm2->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi3_off ), xmm3->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi4_off ), xmm4->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi5_off ), xmm5->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi6_off ), xmm6->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi7_off ), xmm7->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi8_off ), xmm8->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi9_off ), xmm9->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi10_off), xmm10->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi11_off), xmm11->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi12_off), xmm12->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi13_off), xmm13->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi14_off), xmm14->as_VMReg()->next()->next()->next()->next()); - map->set_callee_saved(STACK_OFFSET(ymm_hi15_off), xmm15->as_VMReg()->next()->next()->next()->next()); + assert(ymmhi_offset != -1, "save area must exist"); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm0_off ), xmm0->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm1_off ), xmm1->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm2_off ), xmm2->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm3_off ), xmm3->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm4_off ), xmm4->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm5_off ), xmm5->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm6_off ), xmm6->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm7_off ), xmm7->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm8_off ), xmm8->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm9_off ), xmm9->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm10_off), xmm10->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm11_off), xmm11->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm12_off), xmm12->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm13_off), xmm13->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm14_off), xmm14->as_VMReg()->next()->next()->next()->next()); + map->set_callee_saved(YMMHI_STACK_OFFSET(xmm15_off), xmm15->as_VMReg()->next()->next()->next()->next()); } #endif @@ -326,24 +314,24 @@ // Restore upper half of YMM registes. assert(UseAVX > 0, "256bit vectors are supported only with AVX"); assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); - __ vinsertf128h(xmm0, Address(rsp, ymm_hi0_off * BytesPerInt)); - __ vinsertf128h(xmm1, Address(rsp, ymm_hi1_off * BytesPerInt)); - __ vinsertf128h(xmm2, Address(rsp, ymm_hi2_off * BytesPerInt)); - __ vinsertf128h(xmm3, Address(rsp, ymm_hi3_off * BytesPerInt)); - __ vinsertf128h(xmm4, Address(rsp, ymm_hi4_off * BytesPerInt)); - __ vinsertf128h(xmm5, Address(rsp, ymm_hi5_off * BytesPerInt)); - __ vinsertf128h(xmm6, Address(rsp, ymm_hi6_off * BytesPerInt)); - __ vinsertf128h(xmm7, Address(rsp, ymm_hi7_off * BytesPerInt)); - __ vinsertf128h(xmm8, Address(rsp, ymm_hi8_off * BytesPerInt)); - __ vinsertf128h(xmm9, Address(rsp, ymm_hi9_off * BytesPerInt)); - __ vinsertf128h(xmm10, Address(rsp, ymm_hi10_off * BytesPerInt)); - __ vinsertf128h(xmm11, Address(rsp, ymm_hi11_off * BytesPerInt)); - __ vinsertf128h(xmm12, Address(rsp, ymm_hi12_off * BytesPerInt)); - __ vinsertf128h(xmm13, Address(rsp, ymm_hi13_off * BytesPerInt)); - __ vinsertf128h(xmm14, Address(rsp, ymm_hi14_off * BytesPerInt)); - __ vinsertf128h(xmm15, Address(rsp, ymm_hi15_off * BytesPerInt)); + __ vinsertf128h(xmm0, Address(rsp, 0)); + __ vinsertf128h(xmm1, Address(rsp, 16)); + __ vinsertf128h(xmm2, Address(rsp, 32)); + __ vinsertf128h(xmm3, Address(rsp, 48)); + __ vinsertf128h(xmm4, Address(rsp, 64)); + __ vinsertf128h(xmm5, Address(rsp, 80)); + __ vinsertf128h(xmm6, Address(rsp, 96)); + __ vinsertf128h(xmm7, Address(rsp,112)); + __ vinsertf128h(xmm8, Address(rsp,128)); + __ vinsertf128h(xmm9, Address(rsp,144)); + __ vinsertf128h(xmm10, Address(rsp,160)); + __ vinsertf128h(xmm11, Address(rsp,176)); + __ vinsertf128h(xmm12, Address(rsp,192)); + __ vinsertf128h(xmm13, Address(rsp,208)); + __ vinsertf128h(xmm14, Address(rsp,224)); + __ vinsertf128h(xmm15, Address(rsp,240)); + __ addptr(rsp, 256); } - __ addptr(rsp, 256); #else assert(!restore_vectors, "vectors are generated only by C2 and JVMCI"); #endif diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jun 05 17:12:08 2015 +0200 @@ -205,7 +205,6 @@ JVMCI_ONLY(do_klass(HotSpotCompiledNmethod_klass, com_oracle_jvmci_hotspot_HotSpotCompiledNmethod, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotForeignCallTarget_klass, com_oracle_jvmci_hotspot_HotSpotForeignCallTarget, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotReferenceMap_klass, com_oracle_jvmci_hotspot_HotSpotReferenceMap, Jvmci)) \ - JVMCI_ONLY(do_klass(HotSpotOopMap_klass, com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotInstalledCode_klass, com_oracle_jvmci_hotspot_HotSpotInstalledCode, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_jvmci_hotspot_HotSpotNmethod, Jvmci)) \ JVMCI_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_jvmci_hotspot_HotSpotResolvedJavaMethodImpl, Jvmci)) \ diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jun 05 17:12:08 2015 +0200 @@ -306,7 +306,6 @@ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotCompiledNmethod, "com/oracle/jvmci/hotspot/HotSpotCompiledNmethod")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotForeignCallTarget, "com/oracle/jvmci/hotspot/HotSpotForeignCallTarget")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap, "com/oracle/jvmci/hotspot/HotSpotReferenceMap")) \ - JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotReferenceMap_HotSpotOopMap, "com/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_CompilerToVMImpl, "com/oracle/jvmci/hotspot/CompilerToVMImpl")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotInstalledCode, "com/oracle/jvmci/hotspot/HotSpotInstalledCode")) \ JVMCI_ONLY(template(com_oracle_jvmci_hotspot_HotSpotNmethod, "com/oracle/jvmci/hotspot/HotSpotNmethod")) \ diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/jvmci/jvmciCodeInstaller.cpp --- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp Fri Jun 05 17:12:08 2015 +0200 @@ -69,83 +69,62 @@ return asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method)); } -const int MapWordBits = 64; - -static int entry_value(typeArrayOop words, int i) { - jint words_idx = i / MapWordBits; - assert(words_idx >= 0 && words_idx < words->length(), "unexpected index"); - jlong word = words->long_at(words_idx); - return (word >> (i % MapWordBits)) & 15LL; -} - -static int fixedmap_size(oop bitset) { - typeArrayOop arr = HotSpotOopMap::words(bitset); - return arr->length() * MapWordBits; -} - -static void set_vmreg_oops(OopMap* map, VMReg reg, typeArrayOop words, int idx) { - int value = entry_value(words, 4 * idx); - switch (value) { - case 10: - map->set_oop(reg); - break; - case 5: - map->set_narrowoop(reg); - map->set_narrowoop(reg->next()); - break; - case 1: - map->set_narrowoop(reg); - break; - case 4: - map->set_narrowoop(reg->next()); - break; - case 0: - break; - default: - assert(false, err_msg("unexpected bit pattern at %d = 0x%x", idx, value)); - ShouldNotReachHere(); +// creates a HotSpot oop map out of the byte arrays provided by DebugInfo +OopMap* CodeInstaller::create_oop_map(oop debug_info) { + oop reference_map = DebugInfo::referenceMap(debug_info); + if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) { + _has_wide_vector = true; } -} - -// creates a HotSpot oop map out of the byte arrays provided by DebugInfo -static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) { - OopMap* map = new OopMap(total_frame_size, parameter_count); - oop reference_map = DebugInfo::referenceMap(debug_info); - oop register_map = HotSpotReferenceMap::registerRefMap(reference_map); - oop frame_map = HotSpotReferenceMap::frameRefMap(reference_map); - oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); - - if (register_map != NULL) { - typeArrayOop words = HotSpotOopMap::words(register_map); - int mapIdx = 0; - for (jint i = 0; i < RegisterImpl::number_of_registers; i++) { - set_vmreg_oops(map, as_Register(i)->as_VMReg(), words, mapIdx); - mapIdx++; + OopMap* map = new OopMap(_total_frame_size, _parameter_count); + objArrayOop objects = HotSpotReferenceMap::objects(reference_map); + typeArrayOop bytesPerArray = HotSpotReferenceMap::bytesPerElement(reference_map); + for (int i = 0; i < objects->length(); i++) { + oop value = objects->obj_at(i); + oop lirKind = AbstractValue::lirKind(value); + oop platformKind = LIRKind::platformKind(lirKind); + int bytesPerElement = bytesPerArray->int_at(i); + assert(bytesPerElement == 4 || bytesPerElement == 8, "wrong sizes"); + jint referenceMask = LIRKind::referenceMask(lirKind); + assert(referenceMask != 0, "must be a reference type"); + assert(referenceMask != -1, "must not be a derived reference type"); + + VMReg vmReg; + if (value->is_a(RegisterValue::klass())) { + oop reg = RegisterValue::reg(value); + jint number = code_Register::number(reg); + vmReg = CodeInstaller::get_hotspot_reg(number); + } else if (value->is_a(StackSlot::klass())) { + jint offset = StackSlot::offset(value); +#ifdef TARGET_ARCH_sparc + if(offset >= 0) { + offset += 128; + } +#endif + if (StackSlot::addFrameSize(value)) { + offset += _total_frame_size; + } + assert(offset % 4 == 0, "must be aligned"); + vmReg = VMRegImpl::stack2reg(offset / 4); } -#ifdef TARGET_ARCH_x86 - for (jint i = 0; i < XMMRegisterImpl::number_of_registers; i++) { - VMReg reg = as_XMMRegister(i)->as_VMReg(); - for (jint j = 0; j < 4; j++) { - set_vmreg_oops(map, reg->next(2 * j), words, mapIdx++); + + int bit = 1; + while (referenceMask != 0) { + if (referenceMask & bit) { + if (bytesPerElement == 8) { + map->set_oop(vmReg); + } else { + map->set_narrowoop(vmReg); + } + referenceMask &= ~bit; } + vmReg = vmReg->next(); + if (bytesPerElement == 8) { + vmReg = vmReg->next(); + } + bit <<= 1; } -#endif -#ifdef TARGET_ARCH_sparc - for (jint i = 0; i < FloatRegisterImpl::number_of_registers; i++) { - VMReg reg = as_FloatRegister(i)->as_VMReg(); - set_vmreg_oops(map, reg, words, mapIdx++); - } -#endif } - - typeArrayOop words = HotSpotOopMap::words(frame_map); - int size = fixedmap_size(frame_map) / 4; - for (jint i = 0; i < size; i++) { - // HotSpot stack slots are 4 bytes - VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word); - set_vmreg_oops(map, reg, words, i); - } - + oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); if (callee_save_info != NULL) { objArrayOop registers = RegisterSaveLayout::registers(callee_save_info); typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info); @@ -261,7 +240,17 @@ return value; } } else if (value->is_a(StackSlot::klass())) { - Location::Type locationType; + jint offset = StackSlot::offset(value); +#ifdef TARGET_ARCH_sparc + if(offset >= 0) { + offset += 128; + } +#endif + if (StackSlot::addFrameSize(value)) { + offset += _total_frame_size; + } + + Location::Type locationType; if (type == T_LONG) { locationType = reference ? Location::oop : Location::lng; } else if (type == T_INT) { @@ -278,15 +267,6 @@ assert(type == T_OBJECT && reference, "unexpected type in stack slot"); locationType = Location::oop; } - jint offset = StackSlot::offset(value); -#ifdef TARGET_ARCH_sparc - if(offset >= 0) { - offset += 128; - } -#endif - if (StackSlot::addFrameSize(value)) { - offset += _total_frame_size; - } ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); if (type == T_DOUBLE || (type == T_LONG && !reference)) { second = value; @@ -470,8 +450,10 @@ // Make sure a valid compile_id is associated with every compile id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci); } - result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, - JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, false, installed_code, compiled_code, speculation_log); + result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, + stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, + JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, + false, _has_wide_vector, installed_code, compiled_code, speculation_log); cb = nm; } @@ -513,6 +495,8 @@ #endif _next_call_type = INVOKE_INVALID; + + _has_wide_vector = false; } int CodeInstaller::estimate_stub_entries() { @@ -856,7 +840,7 @@ // address instruction = _instructions->start() + pc_offset; // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); - _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); + _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info)); record_scope(pc_offset, debug_info); _debug_recorder->end_safepoint(pc_offset); } @@ -891,7 +875,7 @@ jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); if (debug_info != NULL) { - _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); + _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info)); record_scope(next_pc_offset, debug_info); } diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/jvmci/jvmciCodeInstaller.hpp --- a/src/share/vm/jvmci/jvmciCodeInstaller.hpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.hpp Fri Jun 05 17:12:08 2015 +0200 @@ -70,6 +70,8 @@ jobject _comments_handle; #endif + bool _has_wide_vector; + MarkId _next_call_type; address _invoke_mark_pc; @@ -139,6 +141,8 @@ void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); + OopMap* create_oop_map(oop debug_info); + void record_scope(jint pc_offset, oop debug_info); void record_scope(jint pc_offset, oop code_pos, GrowableArray* objects); void record_object_value(ObjectValue* sv, oop value, GrowableArray* objects); diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/jvmci/jvmciEnv.cpp --- a/src/share/vm/jvmci/jvmciEnv.cpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/jvmci/jvmciEnv.cpp Fri Jun 05 17:12:08 2015 +0200 @@ -483,6 +483,7 @@ JVMCIEnv* env, int compile_id, bool has_unsafe_access, + bool has_wide_vector, Handle installed_code, Handle compiled_code, Handle speculation_log) { @@ -546,12 +547,7 @@ } } else { nm->set_has_unsafe_access(has_unsafe_access); -#ifdef TARGET_ARCH_x86 - // It might be preferable to set this only for methods which - // use vector instructions but we currently don't track this - // and it probably wouldn't make much difference. - nm->set_has_wide_vectors(MaxVectorSize > 16); -#endif + nm->set_has_wide_vectors(has_wide_vector); // Record successful registration. // (Put nm into the task handle *before* publishing to the Java heap.) diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/jvmci/jvmciEnv.hpp --- a/src/share/vm/jvmci/jvmciEnv.hpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/jvmci/jvmciEnv.hpp Fri Jun 05 17:12:08 2015 +0200 @@ -157,6 +157,7 @@ JVMCIEnv* env, int compile_id, bool has_unsafe_access, + bool has_wide_vector, Handle installed_code, Handle compiled_code, Handle speculation_log); diff -r 30b4de402a58 -r f60f7994c5a5 src/share/vm/jvmci/jvmciJavaAccess.hpp --- a/src/share/vm/jvmci/jvmciJavaAccess.hpp Fri Jun 05 17:11:50 2015 +0200 +++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp Fri Jun 05 17:12:08 2015 +0200 @@ -157,16 +157,14 @@ objArrayOop_field(DebugInfo, virtualObjectMapping, "[Lcom/oracle/jvmci/meta/Value;") \ end_class \ start_class(HotSpotReferenceMap) \ - oop_field(HotSpotReferenceMap, registerRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ - oop_field(HotSpotReferenceMap, frameRefMap, "Lcom/oracle/jvmci/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ + objArrayOop_field(HotSpotReferenceMap, objects, "[Lcom/oracle/jvmci/meta/Value;") \ + typeArrayOop_field(HotSpotReferenceMap, bytesPerElement, "[I") \ + int_field(HotSpotReferenceMap, maxRegisterSize) \ end_class \ start_class(RegisterSaveLayout) \ objArrayOop_field(RegisterSaveLayout, registers, "[Lcom/oracle/jvmci/code/Register;") \ typeArrayOop_field(RegisterSaveLayout, slots, "[I") \ end_class \ - start_class(HotSpotOopMap) \ - typeArrayOop_field(HotSpotOopMap, words, "[J") \ - end_class \ start_class(BytecodeFrame) \ objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/jvmci/meta/Value;") \ int_field(BytecodeFrame, numLocals) \ @@ -223,15 +221,9 @@ start_class(RegisterValue) \ oop_field(RegisterValue, reg, "Lcom/oracle/jvmci/code/Register;") \ end_class \ - start_class(RegisterCategory) \ - oop_field(RegisterCategory, name, "Ljava/lang/String;") \ - int_field(RegisterCategory, referenceMapOffset) \ - int_field(RegisterCategory, referenceMapShift) \ - end_class \ start_class(code_Register) \ int_field(code_Register, number) \ int_field(code_Register, encoding) \ - oop_field(code_Register, registerCategory, "Lcom/oracle/jvmci/code/Register$RegisterCategory;") \ end_class \ start_class(StackSlot) \ int_field(StackSlot, offset) \