# HG changeset patch # User iveresov # Date 1534537253 25200 # Node ID 091c0d22e735cbb3d384c80d630242aba38b1cdd # Parent 72c82bd059716ccb6d04dcfc70141f468fd66471 8206992: Update Graal Reviewed-by: kvn diff -r 72c82bd05971 -r 091c0d22e735 make/CompileJavaModules.gmk --- a/make/CompileJavaModules.gmk Fri Aug 17 11:56:59 2018 -0500 +++ b/make/CompileJavaModules.gmk Fri Aug 17 13:20:53 2018 -0700 @@ -511,6 +511,10 @@ --add-exports jdk.internal.vm.ci/jdk.vm.ci.sparc=jdk.internal.vm.compiler,jdk.aot \ # +jdk.aot_EXCLUDES += \ + jdk.tools.jaotc.test + # + ################################################################################ sun.charsets_COPY += .dat diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT; @@ -137,23 +139,23 @@ */ private static final HashMap functionNamesToAOTSymbols = new HashMap<>(); + //@formatter:off private static final String[][] map = { -//@formatter:off - {"CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", "_aot_deopt_blob_unpack"}, - {"CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", "_aot_deopt_blob_uncommon_trap"}, - {"CompilerToVM::Data::SharedRuntime_ic_miss_stub", "_aot_ic_miss_stub"}, - {"CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", "_aot_handle_wrong_method_stub"}, - {"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"}, - {"SharedRuntime::register_finalizer", "_aot_register_finalizer"}, - {"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"}, - {"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"}, - {"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"}, - {"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"}, - {"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"}, - {"CompilerRuntime::resolve_method_by_symbol_and_load_counters","_aot_resolve_method_by_symbol_and_load_counters"}, - {"CompilerRuntime::initialize_klass_by_symbol", "_aot_initialize_klass_by_symbol"}, - {"CompilerRuntime::invocation_event", "_aot_invocation_event"}, - {"CompilerRuntime::backedge_event", "_aot_backedge_event"}, + {"CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", "_aot_deopt_blob_unpack"}, + {"CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", "_aot_deopt_blob_uncommon_trap"}, + {"CompilerToVM::Data::SharedRuntime_ic_miss_stub", "_aot_ic_miss_stub"}, + {"CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", "_aot_handle_wrong_method_stub"}, + {"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"}, + {"SharedRuntime::register_finalizer", "_aot_register_finalizer"}, + {"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"}, + {"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"}, + {"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"}, + {"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"}, + {"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"}, + {"CompilerRuntime::resolve_method_by_symbol_and_load_counters", "_aot_resolve_method_by_symbol_and_load_counters"}, + {"CompilerRuntime::initialize_klass_by_symbol", "_aot_initialize_klass_by_symbol"}, + {"CompilerRuntime::invocation_event", "_aot_invocation_event"}, + {"CompilerRuntime::backedge_event", "_aot_backedge_event"}, {"CompilerToVM::Data::dpow", "_aot_shared_runtime_dpow"}, {"CompilerToVM::Data::dexp", "_aot_shared_runtime_dexp"}, @@ -256,8 +258,8 @@ {"JVMCIRuntime::vm_error", "_aot_jvmci_runtime_vm_error"}, {"JVMCIRuntime::new_array", "_aot_jvmci_runtime_new_array"} - //@formatter:on }; + //@formatter:on static { for (String[] entry : map) { @@ -320,6 +322,7 @@ } private void recordConfiguration(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig, int gc) { + // @Checkstyle: stop // @formatter:off boolean[] booleanFlags = { graalHotSpotVMConfig.cAssertions, // Debug VM graalHotSpotVMConfig.useCompressedOops, @@ -343,6 +346,7 @@ gc }; // @formatter:on + // @Checkstyle: resume byte[] booleanFlagsAsBytes = flagsToByteArray(booleanFlags); int size0 = configContainer.getByteStreamSize(); @@ -447,7 +451,6 @@ return threadLocalHandshakes; } - /** * Gets the global AOT symbol associated with the function name. * @@ -542,8 +545,9 @@ JPECoffRelocObject pecoffobj = new JPECoffRelocObject(this, outputFileName); pecoffobj.createPECoffRelocObject(relocationTable, symbolTable.values()); break; - } else + } else { throw new InternalError("Unsupported platform: " + osName); + } } } @@ -553,6 +557,7 @@ * * @param symInfo symbol information to be added */ + @Override public void addSymbol(Symbol symInfo) { if (symInfo.getName().startsWith("got.") && !(symInfo instanceof GotSymbol)) { throw new InternalError("adding got. without being GotSymbol"); @@ -578,7 +583,8 @@ * @param info relocation information to be added */ public void addRelocation(Relocation info) { - // System.out.println("# Relocation [" + info.getSymbol() + "] [" + info.getOffset() + "] [" + + // System.out.println("# Relocation [" + info.getSymbol() + "] [" + info.getOffset() + "] [" + // + // info.getSection().getContainerName() + "] [" + info.getSymbol().getName() + "] [" + // info.getSymbol().getOffset() + " @ " + info.getSymbol().getSection().getContainerName() + // "]"); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ByteContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ByteContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ByteContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,11 +21,12 @@ * questions. */ + + package jdk.tools.jaotc.binformat; import jdk.tools.jaotc.binformat.Symbol.Binding; import jdk.tools.jaotc.binformat.Symbol.Kind; -import jdk.tools.jaotc.binformat.Container; import java.io.ByteArrayOutputStream; import java.nio.ByteBuffer; @@ -184,6 +185,7 @@ * * @return string containing name */ + @Override public String getContainerName() { return containerName; } @@ -218,6 +220,7 @@ sectionId = id; } + @Override public int getSectionId() { if (sectionId == -1) { throw new InternalError("Using sectionId before assigned"); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/CodeContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/CodeContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/CodeContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; /** diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Container.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Container.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Container.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; interface Container { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/GotSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/GotSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/GotSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; public final class GotSymbol extends Symbol { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/HeaderContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/HeaderContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/HeaderContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; import java.io.ByteArrayOutputStream; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/NativeSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/NativeSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/NativeSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,10 +21,12 @@ * questions. */ + + package jdk.tools.jaotc.binformat; /** - * This class represents ia native OS specific Symbol + * This class represents a native OS specific Symbol. */ public abstract class NativeSymbol { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ReadOnlyDataContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ReadOnlyDataContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/ReadOnlyDataContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; public final class ReadOnlyDataContainer extends ByteContainer { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Relocation.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Relocation.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Relocation.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,10 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat; public final class Relocation { + // @formatter:off (workaround for Eclipse formatting bug) public enum RelocType { UNDEFINED, JAVA_CALL_INDIRECT, @@ -35,6 +38,7 @@ EXTERNAL_GOT_TO_PLT, EXTERNAL_PLT_TO_GOT } + // @formatter:on private final RelocType type; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Symbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Symbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/Symbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,15 @@ * questions. */ + + package jdk.tools.jaotc.binformat; import java.util.Objects; -import jdk.tools.jaotc.binformat.NativeSymbol; - public class Symbol { + // @formatter:off (workaround for Eclipse formatting bug) public enum Binding { UNDEFINED, LOCAL, @@ -42,6 +43,7 @@ OBJECT, NOTYPE } + // @formatter:on private final String name; private final int size; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/SymbolTable.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/SymbolTable.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/SymbolTable.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat; public interface SymbolTable { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AArch64JELFRelocObject.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AArch64JELFRelocObject.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AArch64JELFRelocObject.java Fri Aug 17 13:20:53 2018 -0700 @@ -22,39 +22,24 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import jdk.tools.jaotc.binformat.BinaryContainer; -import jdk.tools.jaotc.binformat.ByteContainer; -import jdk.tools.jaotc.binformat.CodeContainer; -import jdk.tools.jaotc.binformat.ReadOnlyDataContainer; import jdk.tools.jaotc.binformat.Relocation; import jdk.tools.jaotc.binformat.Relocation.RelocType; import jdk.tools.jaotc.binformat.Symbol; -import jdk.tools.jaotc.binformat.Symbol.Binding; -import jdk.tools.jaotc.binformat.Symbol.Kind; - -import jdk.tools.jaotc.binformat.elf.ElfSymbol; -import jdk.tools.jaotc.binformat.elf.ElfTargetInfo; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; - public class AArch64JELFRelocObject extends JELFRelocObject { AArch64JELFRelocObject(BinaryContainer binContainer, String outputFileName) { super(binContainer, outputFileName); } + @Override void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) { RelocType relocType = reloc.getType(); @@ -66,38 +51,38 @@ int addend = 0; switch (relocType) { - case STUB_CALL_DIRECT: - case JAVA_CALL_DIRECT: { - break; - } - case EXTERNAL_PLT_TO_GOT: - offset -= 16; - elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend); - elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend); - return; + case STUB_CALL_DIRECT: + case JAVA_CALL_DIRECT: { + break; + } + case EXTERNAL_PLT_TO_GOT: + offset -= 16; + elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend); + elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend); + return; - case FOREIGN_CALL_INDIRECT_GOT: { - break; - } - case METASPACE_GOT_REFERENCE: { - offset -= 4; + case FOREIGN_CALL_INDIRECT_GOT: { + break; + } + case METASPACE_GOT_REFERENCE: { + offset -= 4; - elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend); - elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend); - return; - } + elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend); + elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend); + return; + } // break; - case JAVA_CALL_INDIRECT: { - addend = -4; - offset = offset + addend; - break; - } - case EXTERNAL_GOT_TO_PLT: { - // this is load time relocations - break; - } - default: - throw new InternalError("Unhandled relocation type: " + relocType); + case JAVA_CALL_INDIRECT: { + addend = -4; + offset = offset + addend; + break; + } + case EXTERNAL_GOT_TO_PLT: { + // this is load time relocations + break; + } + default: + throw new InternalError("Unhandled relocation type: " + relocType); } elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend); @@ -109,14 +94,14 @@ case Elf64_Ehdr.EM_AARCH64: // Return R_X86_64_* entries based on relocType if (relocType == RelocType.JAVA_CALL_DIRECT || - relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { + relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { elfRelocType = Elf64_Rela.R_AARCH64_CALL26; } else if (relocType == RelocType.STUB_CALL_DIRECT) { elfRelocType = Elf64_Rela.R_AARCH64_CALL26; } else if (relocType == RelocType.JAVA_CALL_INDIRECT) { elfRelocType = Elf64_Rela.R_AARCH64_CALL26; } else if (relocType == RelocType.METASPACE_GOT_REFERENCE || - relocType == RelocType.EXTERNAL_PLT_TO_GOT) { + relocType == RelocType.EXTERNAL_PLT_TO_GOT) { elfRelocType = Elf64_Rela.R_AARCH64_NONE; } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) { elfRelocType = Elf64_Rela.R_AARCH64_ABS64; @@ -126,8 +111,7 @@ break; default: - System.out.println("Relocation Type mapping: Unhandled architecture: " - + ElfTargetInfo.getElfArch()); + System.out.println("Relocation Type mapping: Unhandled architecture: " + ElfTargetInfo.getElfArch()); } return elfRelocType; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AMD64JELFRelocObject.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AMD64JELFRelocObject.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/AMD64JELFRelocObject.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,39 +21,24 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import jdk.tools.jaotc.binformat.BinaryContainer; -import jdk.tools.jaotc.binformat.ByteContainer; -import jdk.tools.jaotc.binformat.CodeContainer; -import jdk.tools.jaotc.binformat.ReadOnlyDataContainer; import jdk.tools.jaotc.binformat.Relocation; import jdk.tools.jaotc.binformat.Relocation.RelocType; import jdk.tools.jaotc.binformat.Symbol; -import jdk.tools.jaotc.binformat.Symbol.Binding; -import jdk.tools.jaotc.binformat.Symbol.Kind; - -import jdk.tools.jaotc.binformat.elf.ElfSymbol; -import jdk.tools.jaotc.binformat.elf.ElfTargetInfo; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; - public class AMD64JELFRelocObject extends JELFRelocObject { AMD64JELFRelocObject(BinaryContainer binContainer, String outputFileName) { super(binContainer, outputFileName); } + @Override protected void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) { RelocType relocType = reloc.getType(); @@ -65,62 +50,61 @@ int addend = 0; switch (relocType) { - case JAVA_CALL_DIRECT: - case STUB_CALL_DIRECT: - case FOREIGN_CALL_INDIRECT_GOT: { - // Create relocation entry - addend = -4; // Size in bytes of the patch location - // Relocation should be applied at the location after call operand - offset = offset + reloc.getSize() + addend; - break; - } - case JAVA_CALL_INDIRECT: - case METASPACE_GOT_REFERENCE: - case EXTERNAL_PLT_TO_GOT: { - addend = -4; // Size of 32-bit address of the GOT - /* - * Relocation should be applied before the test instruction to the move instruction. - * reloc.getOffset() points to the test instruction after the instruction that loads the address of - * polling page. So set the offset appropriately. - */ - offset = offset + addend; - break; - } - case EXTERNAL_GOT_TO_PLT: { - // this is load time relocations - break; - } - default: - throw new InternalError("Unhandled relocation type: " + relocType); + case JAVA_CALL_DIRECT: + case STUB_CALL_DIRECT: + case FOREIGN_CALL_INDIRECT_GOT: { + // Create relocation entry + addend = -4; // Size in bytes of the patch location + // Relocation should be applied at the location after call operand + offset = offset + reloc.getSize() + addend; + break; + } + case JAVA_CALL_INDIRECT: + case METASPACE_GOT_REFERENCE: + case EXTERNAL_PLT_TO_GOT: { + addend = -4; // Size of 32-bit address of the GOT + /* + * Relocation should be applied before the test instruction to the move instruction. + * reloc.getOffset() points to the test instruction after the instruction that loads + * the address of polling page. So set the offset appropriately. + */ + offset = offset + addend; + break; + } + case EXTERNAL_GOT_TO_PLT: { + // this is load time relocations + break; + } + default: + throw new InternalError("Unhandled relocation type: " + relocType); } elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend); } - private int getELFRelocationType(RelocType relocType) { + private static int getELFRelocationType(RelocType relocType) { int elfRelocType = 0; // R__NONE if #define'd to 0 for all values of ARCH switch (ElfTargetInfo.getElfArch()) { - case Elf64_Ehdr.EM_X86_64: - // Return R_X86_64_* entries based on relocType - if (relocType == RelocType.JAVA_CALL_DIRECT || - relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { - elfRelocType = Elf64_Rela.R_X86_64_PLT32; - } else if (relocType == RelocType.STUB_CALL_DIRECT) { - elfRelocType = Elf64_Rela.R_X86_64_PC32; - } else if (relocType == RelocType.JAVA_CALL_INDIRECT) { - elfRelocType = Elf64_Rela.R_X86_64_NONE; - } else if (relocType == RelocType.METASPACE_GOT_REFERENCE || - relocType == RelocType.EXTERNAL_PLT_TO_GOT) { - elfRelocType = Elf64_Rela.R_X86_64_PC32; - } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) { - elfRelocType = Elf64_Rela.R_X86_64_64; - } else { - assert false : "Unhandled relocation type: " + relocType; - } - break; + case Elf64_Ehdr.EM_X86_64: + // Return R_X86_64_* entries based on relocType + if (relocType == RelocType.JAVA_CALL_DIRECT || + relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { + elfRelocType = Elf64_Rela.R_X86_64_PLT32; + } else if (relocType == RelocType.STUB_CALL_DIRECT) { + elfRelocType = Elf64_Rela.R_X86_64_PC32; + } else if (relocType == RelocType.JAVA_CALL_INDIRECT) { + elfRelocType = Elf64_Rela.R_X86_64_NONE; + } else if (relocType == RelocType.METASPACE_GOT_REFERENCE || + relocType == RelocType.EXTERNAL_PLT_TO_GOT) { + elfRelocType = Elf64_Rela.R_X86_64_PC32; + } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) { + elfRelocType = Elf64_Rela.R_X86_64_64; + } else { + assert false : "Unhandled relocation type: " + relocType; + } + break; - default: - System.out.println("Relocation Type mapping: Unhandled architecture: " - + ElfTargetInfo.getElfArch()); + default: + System.out.println("Relocation Type mapping: Unhandled architecture: " + ElfTargetInfo.getElfArch()); } return elfRelocType; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/Elf.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/Elf.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/Elf.java Fri Aug 17 13:20:53 2018 -0700 @@ -22,18 +22,19 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; +//@Checkstyle: stop +//@formatter:off + /** - * * Support for the creation of Elf Object files. Current support is limited to 64 bit x86_64. - * */ - final class Elf { - //@formatter:off /** - * Elf64_Ehdr structure defines + * Elf64_Ehdr structure defines. */ enum Elf64_Ehdr { e_ident( 0,16), @@ -103,7 +104,7 @@ } /** - * Elf64_Shdr structure defines + * Elf64_Shdr structure defines. */ enum Elf64_Shdr { sh_name( 0, 4), @@ -190,7 +191,7 @@ } /** - * Elf64_Rel structure defines + * Elf64_Rel structure defines. */ enum Elf64_Rel { r_offset( 0, 8), @@ -207,7 +208,7 @@ static int totalsize = 16; /** - * Relocation types + * Relocation types. */ static final int R_X86_64_NONE = 0x0; @@ -270,9 +271,7 @@ static final int R_AARCH64_LDST64_ABS_LO12_NC = 286; static long ELF64_R_INFO(int symidx, int type) { - return (((long)symidx << 32) + type); + return (((long) symidx << 32) + type); } - } - //@formatter:on } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfByteBuffer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfByteBuffer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfByteBuffer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; import java.nio.ByteOrder; + import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; -import jdk.tools.jaotc.binformat.elf.ElfTargetInfo; final class ElfByteBuffer { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.io.File; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfHeader.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfHeader.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfHeader.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; -import jdk.tools.jaotc.binformat.elf.ElfTargetInfo; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfHeader { private final ByteBuffer header; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocEntry.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocEntry.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocEntry.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfRelocEntry { private final ByteBuffer entry; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocTable.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocTable.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfRelocTable.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; +import java.nio.ByteBuffer; import java.util.ArrayList; -import java.nio.ByteBuffer; -import jdk.tools.jaotc.binformat.elf.ElfRelocEntry; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfRelocTable { private final ArrayList> relocEntries; @@ -45,14 +45,14 @@ relocEntries.get(sectindex).add(entry); } - int getNumRelocs(int section_index) { - return relocEntries.get(section_index).size(); + int getNumRelocs(int sectionIndex) { + return relocEntries.get(sectionIndex).size(); } // Return the relocation entries for a single section // or null if no entries added to section - byte[] getRelocData(int section_index) { - ArrayList entryList = relocEntries.get(section_index); + byte[] getRelocData(int sectionIndex) { + ArrayList entryList = relocEntries.get(sectionIndex); if (entryList.size() == 0) { return null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSection.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSection.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSection.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,15 +21,16 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rel; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; +import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfSection { private final String name; @@ -39,9 +40,9 @@ private final int sectionIndex; /** - * String holding section name strings + * String holding section name strings. */ - private final static StringBuilder sectNameTab = new StringBuilder(); + private static final StringBuilder sectNameTab = new StringBuilder(); /** * Keeps track of bytes in section string table since strTabContent.length() is number of chars, @@ -50,7 +51,7 @@ private static int shStrTabNrOfBytes = 0; ElfSection(String sectName, byte[] sectData, int sectFlags, int sectType, - boolean hasRelocations, int align, int sectIndex) { + boolean hasRelocations, int align, int sectIndex) { section = ElfByteBuffer.allocate(Elf64_Shdr.totalsize); name = sectName; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,13 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.NativeSymbol; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfSymbol extends NativeSymbol { private final ByteBuffer sym; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymtab.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymtab.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfSymtab.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteBuffer; import java.util.ArrayList; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; -import jdk.tools.jaotc.binformat.elf.ElfSymbol; -import jdk.tools.jaotc.binformat.elf.ElfByteBuffer; final class ElfSymtab { @@ -36,12 +36,12 @@ private final ArrayList globalSymbols = new ArrayList<>(); /** - * number of symbols added + * Number of symbols added. */ private int symbolCount; /** - * String holding symbol table strings + * String holding symbol table strings. */ private final StringBuilder strTabContent = new StringBuilder(); @@ -77,10 +77,11 @@ strTabNrOfBytes += (name.getBytes().length + 1); sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size); - if ((bind & Elf64_Sym.STB_GLOBAL) != 0) + if ((bind & Elf64_Sym.STB_GLOBAL) != 0) { globalSymbols.add(sym); - else + } else { localSymbols.add(sym); + } } symbolCount++; return (sym); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfTargetInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfTargetInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/ElfTargetInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.nio.ByteOrder; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/elf/JELFRelocObject.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.elf; import java.io.IOException; @@ -34,17 +36,12 @@ import jdk.tools.jaotc.binformat.CodeContainer; import jdk.tools.jaotc.binformat.ReadOnlyDataContainer; import jdk.tools.jaotc.binformat.Relocation; -import jdk.tools.jaotc.binformat.Relocation.RelocType; import jdk.tools.jaotc.binformat.Symbol; import jdk.tools.jaotc.binformat.Symbol.Binding; import jdk.tools.jaotc.binformat.Symbol.Kind; - -import jdk.tools.jaotc.binformat.elf.ElfSymbol; -import jdk.tools.jaotc.binformat.elf.ElfTargetInfo; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr; import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym; -import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela; public abstract class JELFRelocObject { @@ -64,22 +61,22 @@ String archStr = System.getProperty("os.arch").toLowerCase(); if (archStr.equals("amd64") || archStr.equals("x86_64")) { return new AMD64JELFRelocObject(binContainer, outputFileName); - } else if (archStr.equals("aarch64")) { + } else if (archStr.equals("aarch64")) { return new AArch64JELFRelocObject(binContainer, outputFileName); } throw new InternalError("Unsupported platform: " + archStr); } private static ElfSection createByteSection(ArrayList sections, - String sectName, - byte[] scnData, - boolean hasRelocs, - int align, - int scnFlags, - int scnType) { + String sectName, + byte[] scnData, + boolean hasRelocs, + int align, + int scnFlags, + int scnType) { ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType, - hasRelocs, align, sections.size()); + hasRelocs, align, sections.size()); // Add this section to our list sections.add(sect); @@ -87,7 +84,7 @@ } private void createByteSection(ArrayList sections, - ByteContainer c, int scnFlags) { + ByteContainer c, int scnFlags) { ElfSection sect; boolean hasRelocs = c.hasRelocations(); byte[] scnData = c.getByteArray(); @@ -107,8 +104,8 @@ } sect = createByteSection(sections, c.getContainerName(), - scnData, hasRelocs, segmentSize, - scnFlags, scnType); + scnData, hasRelocs, segmentSize, + scnFlags, scnType); c.setSectionId(sect.getSectionId()); } @@ -125,7 +122,7 @@ } /** - * Create an ELF relocatable object + * Creates an ELF relocatable object. * * @param relocationTable * @param symbols @@ -166,18 +163,18 @@ // that order since symtab section needs to set the index of // strtab in sh_link field ElfSection strTabSection = createByteSection(sections, ".strtab", - symtab.getStrtabArray(), - false, 1, 0, - Elf64_Shdr.SHT_STRTAB); + symtab.getStrtabArray(), + false, 1, 0, + Elf64_Shdr.SHT_STRTAB); // Now create .symtab section with the symtab data constructed. // On Linux, sh_link of symtab contains the index of string table // its symbols reference and sh_info contains the index of first // non-local symbol ElfSection symTabSection = createByteSection(sections, ".symtab", - symtab.getSymtabArray(), - false, 8, 0, - Elf64_Shdr.SHT_SYMTAB); + symtab.getSymtabArray(), + false, 8, 0, + Elf64_Shdr.SHT_SYMTAB); symTabSection.setLink(strTabSection.getSectionId()); symTabSection.setInfo(symtab.getNumLocalSyms()); @@ -187,35 +184,35 @@ // Now, finally, after creating all sections, create shstrtab section ElfSection shStrTabSection = createByteSection(sections, ".shstrtab", - null, false, 1, 0, - Elf64_Shdr.SHT_STRTAB); + null, false, 1, 0, + Elf64_Shdr.SHT_STRTAB); eh.setSectionStrNdx(shStrTabSection.getSectionId()); // Update all section offsets and the Elf header section offset // Write the Header followed by the contents of each section // and then the section structures (section table). - int file_offset = Elf64_Ehdr.totalsize; + int fileOffset = Elf64_Ehdr.totalsize; // and round it up - file_offset = (file_offset + (sections.get(1).getDataAlign() - 1)) & - ~((sections.get(1).getDataAlign() - 1)); + fileOffset = (fileOffset + (sections.get(1).getDataAlign() - 1)) & + ~((sections.get(1).getDataAlign() - 1)); // Calc file offsets for section data skipping null section for (int i = 1; i < sections.size(); i++) { ElfSection sect = sections.get(i); - file_offset = (file_offset + (sect.getDataAlign() - 1)) & - ~((sect.getDataAlign() - 1)); - sect.setOffset(file_offset); - file_offset += sect.getSize(); + fileOffset = (fileOffset + (sect.getDataAlign() - 1)) & + ~((sect.getDataAlign() - 1)); + sect.setOffset(fileOffset); + fileOffset += sect.getSize(); } // Align the section table - file_offset = (file_offset + (ElfSection.getShdrAlign() - 1)) & - ~((ElfSection.getShdrAlign() - 1)); + fileOffset = (fileOffset + (ElfSection.getShdrAlign() - 1)) & + ~((ElfSection.getShdrAlign() - 1)); // Update the Elf Header with the offset of the first Elf64_Shdr // and the number of sections. - eh.setSectionOff(file_offset); + eh.setSectionOff(fileOffset); eh.setSectionNum(sections.size()); // Write out the Header @@ -237,8 +234,8 @@ } /** - * Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF symbol - * table and ELF symbol table are created from BinaryContainer's symbol info. + * Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF + * symbol table and ELF symbol table are created from BinaryContainer's symbol info. * * @param symbols */ @@ -283,11 +280,12 @@ * @param relocationTable */ private ElfRelocTable createElfRelocTable(ArrayList sections, - Map> relocationTable) { + Map> relocationTable) { ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size()); /* - * For each of the symbols with associated relocation records, create a Elf relocation entry. + * For each of the symbols with associated relocation records, create a Elf relocation + * entry. */ for (Map.Entry> entry : relocationTable.entrySet()) { List relocs = entry.getValue(); @@ -306,8 +304,8 @@ } private static void createElfRelocSections(ArrayList sections, - ElfRelocTable elfRelocTable, - int symtabsectidx) { + ElfRelocTable elfRelocTable, + int symtabsectidx) { // Grab count before we create new sections int count = sections.size(); @@ -317,8 +315,8 @@ ElfSection sect = sections.get(i); String relname = ".rela" + sect.getName(); ElfSection relocSection = createByteSection(sections, relname, - elfRelocTable.getRelocData(i), - false, 8, 0, Elf64_Shdr.SHT_RELA); + elfRelocTable.getRelocData(i), + false, 8, 0, Elf64_Shdr.SHT_RELA); relocSection.setLink(symtabsectidx); relocSection.setInfo(sect.getSectionId()); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/JMachORelocObject.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/JMachORelocObject.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/JMachORelocObject.java Fri Aug 17 13:20:53 2018 -0700 @@ -38,6 +38,8 @@ * */ + + package jdk.tools.jaotc.binformat.macho; import java.io.IOException; @@ -54,19 +56,14 @@ import jdk.tools.jaotc.binformat.Relocation.RelocType; import jdk.tools.jaotc.binformat.Symbol; import jdk.tools.jaotc.binformat.Symbol.Kind; - -import jdk.tools.jaotc.binformat.macho.MachO.section_64; +import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command; import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64; -import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64; -import jdk.tools.jaotc.binformat.macho.MachO.version_min_command; -import jdk.tools.jaotc.binformat.macho.MachO.symtab_command; -import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command; import jdk.tools.jaotc.binformat.macho.MachO.nlist_64; import jdk.tools.jaotc.binformat.macho.MachO.reloc_info; -import jdk.tools.jaotc.binformat.macho.MachOContainer; -import jdk.tools.jaotc.binformat.macho.MachOTargetInfo; -import jdk.tools.jaotc.binformat.macho.MachOSymtab; -import jdk.tools.jaotc.binformat.macho.MachORelocTable; +import jdk.tools.jaotc.binformat.macho.MachO.section_64; +import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64; +import jdk.tools.jaotc.binformat.macho.MachO.symtab_command; +import jdk.tools.jaotc.binformat.macho.MachO.version_min_command; public class JMachORelocObject { @@ -83,18 +80,18 @@ } private void createByteSection(ArrayList sections, - ByteContainer c, String sectName, String segName, int scnFlags) { + ByteContainer c, String sectName, String segName, int scnFlags) { if (c.getByteArray().length == 0) { // System.out.println("Skipping creation of " + sectName + " section, no data\n"); } MachOSection sect = new MachOSection(sectName, - segName, - c.getByteArray(), - scnFlags, - c.hasRelocations(), - segmentSize); + segName, + c.getByteArray(), + scnFlags, + c.hasRelocations(), + segmentSize); // Add this section to our list sections.add(sect); @@ -107,13 +104,13 @@ private void createCodeSection(ArrayList sections, CodeContainer c) { createByteSection(sections, c, /* c.getContainerName() */ "__text", "__TEXT", - section_64.S_ATTR_PURE_INSTRUCTIONS | - section_64.S_ATTR_SOME_INSTRUCTIONS); + section_64.S_ATTR_PURE_INSTRUCTIONS | + section_64.S_ATTR_SOME_INSTRUCTIONS); } private void createReadOnlySection(ArrayList sections, ReadOnlyDataContainer c) { createByteSection(sections, c, c.getContainerName(), "__TEXT", - section_64.S_ATTR_SOME_INSTRUCTIONS); + section_64.S_ATTR_SOME_INSTRUCTIONS); } private void createReadWriteSection(ArrayList sections, ByteContainer c) { @@ -121,7 +118,7 @@ } /** - * Create an MachO relocatable object + * Creates an MachO relocatable object. * * @param relocationTable * @param symbols @@ -130,10 +127,10 @@ public void createMachORelocObject(Map> relocationTable, Collection symbols) throws IOException { // Allocate MachO Header // with 4 load commands - // LC_SEGMENT_64 - // LC_VERSION_MIN_MACOSX - // LC_SYMTAB - // LC_DYSYMTAB + // LC_SEGMENT_64 + // LC_VERSION_MIN_MACOSX + // LC_SYMTAB + // LC_DYSYMTAB MachOHeader mh = new MachOHeader(); @@ -162,37 +159,37 @@ // Update the Header sizeofcmds size. // This doesn't include the Header struct size mh.setCmdSizes(4, segment_command_64.totalsize + - (section_64.totalsize * sections.size()) + - version_min_command.totalsize + - symtab_command.totalsize + - dysymtab_command.totalsize); + (section_64.totalsize * sections.size()) + + version_min_command.totalsize + + symtab_command.totalsize + + dysymtab_command.totalsize); // Initialize file offset for data past commands - int file_offset = mach_header_64.totalsize + mh.getCmdSize(); + int fileOffset = mach_header_64.totalsize + mh.getCmdSize(); // and round it up - file_offset = (file_offset + (sections.get(0).getAlign() - 1)) & ~((sections.get(0).getAlign() - 1)); + fileOffset = (fileOffset + (sections.get(0).getAlign() - 1)) & ~((sections.get(0).getAlign() - 1)); long address = 0; - int segment_offset = file_offset; + int segmentOffset = fileOffset; for (int i = 0; i < sections.size(); i++) { MachOSection sect = sections.get(i); - file_offset = (file_offset + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1)); + fileOffset = (fileOffset + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1)); address = (address + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1)); - sect.setOffset(file_offset); + sect.setOffset(fileOffset); sect.setAddr(address); - file_offset += sect.getSize(); + fileOffset += sect.getSize(); address += sect.getSize(); } // File size for Segment data - int segment_size = file_offset - segment_offset; + int segSize = fileOffset - segmentOffset; // Create the LC_SEGMENT_64 Segment which contains the MachOSections MachOSegment seg = new MachOSegment(segment_command_64.totalsize + - (section_64.totalsize * sections.size()), - segment_offset, - segment_size, - sections.size()); + (section_64.totalsize * sections.size()), + segmentOffset, + segSize, + sections.size()); MachOVersion vers = new MachOVersion(); @@ -201,28 +198,28 @@ // Create LC_DYSYMTAB command MachODySymtab dysymtab = new MachODySymtab(symtab.getNumLocalSyms(), - symtab.getNumGlobalSyms(), - symtab.getNumUndefSyms()); + symtab.getNumGlobalSyms(), + symtab.getNumUndefSyms()); // Create the Relocation Tables MachORelocTable machORelocs = createMachORelocTable(sections, relocationTable, symtab); // Calculate file offset for relocation data - file_offset = (file_offset + (MachORelocTable.getAlign() - 1)) & ~((MachORelocTable.getAlign() - 1)); + fileOffset = (fileOffset + (MachORelocTable.getAlign() - 1)) & ~((MachORelocTable.getAlign() - 1)); // Update relocation sizing information in each section for (int i = 0; i < sections.size(); i++) { MachOSection sect = sections.get(i); if (sect.hasRelocations()) { int nreloc = machORelocs.getNumRelocs(i); - sect.setReloff(file_offset); + sect.setReloff(fileOffset); sect.setRelcount(nreloc); - file_offset += (nreloc * reloc_info.totalsize); + fileOffset += (nreloc * reloc_info.totalsize); } } // Calculate and set file offset for symbol table data - file_offset = (file_offset + (MachOSymtab.getAlign() - 1)) & ~((MachOSymtab.getAlign() - 1)); - symtab.setOffset(file_offset); + fileOffset = (fileOffset + (MachOSymtab.getAlign() - 1)) & ~((MachOSymtab.getAlign() - 1)); + symtab.setOffset(fileOffset); // Write Out Header machoContainer.writeBytes(mh.getArray()); @@ -271,7 +268,7 @@ * @param symbols */ private static MachOSymtab createMachOSymbolTables(ArrayList sections, - Collection symbols) { + Collection symbols) { MachOSymtab symtab = new MachOSymtab(); // First, create the initial null symbol. This is a local symbol. symtab.addSymbolEntry("", (byte) nlist_64.N_UNDF, (byte) 0, 0); @@ -284,9 +281,9 @@ long sectionAddr = sections.get(sectionId).getAddr(); MachOSymbol machoSymbol = symtab.addSymbolEntry(symbol.getName(), - getMachOTypeOf(symbol), - (byte) sectionId, - symbol.getOffset() + sectionAddr); + getMachOTypeOf(symbol), + (byte) sectionId, + symbol.getOffset() + sectionAddr); symbol.setNativeSymbol(machoSymbol); } @@ -308,8 +305,8 @@ } // If Function or Data, add section type if (kind == Symbol.Kind.NATIVE_FUNCTION || - kind == Symbol.Kind.JAVA_FUNCTION || - kind == Symbol.Kind.OBJECT) { + kind == Symbol.Kind.JAVA_FUNCTION || + kind == Symbol.Kind.OBJECT) { type |= (nlist_64.N_SECT); } @@ -324,12 +321,13 @@ * @param symtab */ private MachORelocTable createMachORelocTable(ArrayList sections, - Map> relocationTable, - MachOSymtab symtab) { + Map> relocationTable, + MachOSymtab symtab) { MachORelocTable machORelocTable = new MachORelocTable(sections.size()); /* - * For each of the symbols with associated relocation records, create a MachO relocation entry. + * For each of the symbols with associated relocation records, create a MachO relocation + * entry. */ for (Map.Entry> entry : relocationTable.entrySet()) { List relocs = entry.getValue(); @@ -380,8 +378,8 @@ int addend = -4; // Size of 32-bit address of the GOT /* * Relocation should be applied before the test instruction to the move instruction. - * reloc.getOffset() points to the test instruction after the instruction that loads the address of - * polling page. So set the offset appropriately. + * reloc.getOffset() points to the test instruction after the instruction that loads + * the address of polling page. So set the offset appropriately. */ offset = offset + addend; pcrel = 1; @@ -398,8 +396,8 @@ throw new InternalError("Unhandled relocation type: " + relocType); } machORelocTable.createRelocationEntry(sectindex, offset, symno, - pcrel, length, isextern, - machORelocType); + pcrel, length, isextern, + machORelocType); } private static int getMachORelocationType(RelocType relocType) { @@ -408,14 +406,14 @@ case mach_header_64.CPU_TYPE_X86_64: // Return X86_64_RELOC_* entries based on relocType if (relocType == RelocType.JAVA_CALL_DIRECT || - relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { + relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { machORelocType = reloc_info.X86_64_RELOC_BRANCH; } else if (relocType == RelocType.STUB_CALL_DIRECT) { machORelocType = reloc_info.X86_64_RELOC_BRANCH; } else if (relocType == RelocType.JAVA_CALL_INDIRECT) { machORelocType = reloc_info.X86_64_RELOC_NONE; } else if (relocType == RelocType.METASPACE_GOT_REFERENCE || - relocType == RelocType.EXTERNAL_PLT_TO_GOT) { + relocType == RelocType.EXTERNAL_PLT_TO_GOT) { machORelocType = reloc_info.X86_64_RELOC_BRANCH; } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) { machORelocType = reloc_info.X86_64_RELOC_UNSIGNED; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachO.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachO.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachO.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,9 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; //@formatter:off +//@Checkstyle: stop + /** * * Support for the creation of Mach-o Object files. Current support is limited to 64 bit x86_64. @@ -305,4 +309,3 @@ static final int X86_64_RELOC_UNSIGNED = 0x0; } } -//@formatter:on diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOByteBuffer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOByteBuffer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOByteBuffer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,11 +21,12 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import jdk.tools.jaotc.binformat.macho.MachOTargetInfo; final class MachOByteBuffer { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.io.File; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachODySymtab.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachODySymtab.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachODySymtab.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachODySymtab { private final ByteBuffer dysymtab; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOHeader.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOHeader.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOHeader.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,13 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64; -import jdk.tools.jaotc.binformat.macho.MachOTargetInfo; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachOHeader { private final ByteBuffer header; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocEntry.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocEntry.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocEntry.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.reloc_info; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachORelocEntry { private final ByteBuffer entry; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocTable.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocTable.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachORelocTable.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; +import java.nio.ByteBuffer; import java.util.ArrayList; -import java.nio.ByteBuffer; -import jdk.tools.jaotc.binformat.macho.MachORelocEntry; import jdk.tools.jaotc.binformat.macho.MachO.reloc_info; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachORelocTable { private final ArrayList> relocEntries; @@ -50,14 +50,14 @@ return (4); } - int getNumRelocs(int section_index) { - return relocEntries.get(section_index).size(); + int getNumRelocs(int sectionIndex) { + return relocEntries.get(sectionIndex).size(); } // Return the relocation entries for a single section // or null if no entries added to section - byte[] getRelocData(int section_index) { - ArrayList entryList = relocEntries.get(section_index); + byte[] getRelocData(int sectionIndex) { + ArrayList entryList = relocEntries.get(sectionIndex); if (entryList.size() == 0) { return null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSection.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSection.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSection.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.section_64; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachOSection { private final ByteBuffer section; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSegment.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSegment.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSegment.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; public class MachOSegment { ByteBuffer segment; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,13 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.NativeSymbol; import jdk.tools.jaotc.binformat.macho.MachO.nlist_64; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachOSymbol extends NativeSymbol { private final ByteBuffer sym; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymtab.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymtab.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOSymtab.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,20 +21,20 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import java.util.ArrayList; +import jdk.tools.jaotc.binformat.macho.MachO.nlist_64; import jdk.tools.jaotc.binformat.macho.MachO.symtab_command; -import jdk.tools.jaotc.binformat.macho.MachO.nlist_64; -import jdk.tools.jaotc.binformat.macho.MachOSymbol; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachOSymtab { /** - * ByteBuffer holding the LC_SYMTAB command contents + * ByteBuffer holding the LC_SYMTAB command contents. */ private final ByteBuffer symtabCmd; @@ -45,17 +45,18 @@ private final ArrayList undefSymbols = new ArrayList<>(); /** - * number of symbols added + * Number of symbols added. */ private int symbolCount; /** - * String holding symbol table strings + * String holding symbol table strings. */ private final StringBuilder strTabContent = new StringBuilder(); /** - * Keeps track of bytes in string table since strTabContent.length() is number of chars, not bytes. + * Keeps track of bytes in string table since strTabContent.length() is number of chars, not + * bytes. */ private int strTabNrOfBytes = 0; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOTargetInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOTargetInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOTargetInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteOrder; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOVersion.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOVersion.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/macho/MachOVersion.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.macho; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.macho.MachO.version_min_command; -import jdk.tools.jaotc.binformat.macho.MachOByteBuffer; final class MachOVersion { private final ByteBuffer version; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/JPECoffRelocObject.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/JPECoffRelocObject.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/JPECoffRelocObject.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.io.IOException; @@ -38,13 +40,10 @@ import jdk.tools.jaotc.binformat.Symbol; import jdk.tools.jaotc.binformat.Symbol.Binding; import jdk.tools.jaotc.binformat.Symbol.Kind; - -import jdk.tools.jaotc.binformat.pecoff.PECoffSymbol; -import jdk.tools.jaotc.binformat.pecoff.PECoffTargetInfo; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER; +import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL; -import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION; public class JPECoffRelocObject { @@ -102,7 +101,7 @@ } /** - * Create an PECoff relocatable object + * Creates a PECoff relocatable object. * * @param relocationTable * @param symbols @@ -138,7 +137,11 @@ // Add Linker Directives Section int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_INFO | IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_REMOVE; - createByteSection(sections, ".drectve", symtab.getDirectiveArray(), false, scnFlags, 1 /* 1 byte alignment */); + createByteSection(sections, ".drectve", symtab.getDirectiveArray(), false, scnFlags, 1 /* + * 1 + * byte + * alignment + */); // Create the Relocation Tables PECoffRelocTable pecoffRelocs = createPECoffRelocTable(sections, relocationTable); @@ -154,28 +157,28 @@ // RELOCATION TABLE // Calculate Offset for Symbol table - int file_offset = IMAGE_FILE_HEADER.totalsize + + int fileOffset = IMAGE_FILE_HEADER.totalsize + (IMAGE_SECTION_HEADER.totalsize * sections.size()); // Update Header fields header.setSectionCount(sections.size()); header.setSymbolCount(symtab.getSymtabCount()); - header.setSymbolOff(file_offset); + header.setSymbolOff(fileOffset); // Calculate file offset for first section - file_offset += ((symtab.getSymtabCount() * IMAGE_SYMBOL.totalsize) + + fileOffset += ((symtab.getSymtabCount() * IMAGE_SYMBOL.totalsize) + symtab.getStrtabSize()); // And round it up - file_offset = (file_offset + (sections.get(0).getDataAlign() - 1)) & + fileOffset = (fileOffset + (sections.get(0).getDataAlign() - 1)) & ~((sections.get(0).getDataAlign() - 1)); // Calc file offsets for section data for (int i = 0; i < sections.size(); i++) { PECoffSection sect = sections.get(i); - file_offset = (file_offset + (sect.getDataAlign() - 1)) & + fileOffset = (fileOffset + (sect.getDataAlign() - 1)) & ~((sect.getDataAlign() - 1)); - sect.setOffset(file_offset); - file_offset += sect.getSize(); + sect.setOffset(fileOffset); + fileOffset += sect.getSize(); } // Update relocation sizing information in each section @@ -183,13 +186,13 @@ PECoffSection sect = sections.get(i); if (sect.hasRelocations()) { int nreloc = pecoffRelocs.getNumRelocs(i); - sect.setReloff(file_offset); + sect.setReloff(fileOffset); sect.setRelcount(nreloc); // extended relocations add an addition entry if (nreloc > 0xFFFF) { nreloc++; } - file_offset += (nreloc * IMAGE_RELOCATION.totalsize); + fileOffset += (nreloc * IMAGE_RELOCATION.totalsize); } } @@ -269,7 +272,8 @@ PECoffRelocTable pecoffRelocTable = new PECoffRelocTable(sections.size()); /* - * For each of the symbols with associated relocation records, create a PECoff relocation entry. + * For each of the symbols with associated relocation records, create a PECoff relocation + * entry. */ for (Map.Entry> entry : relocationTable.entrySet()) { List relocs = entry.getValue(); @@ -316,8 +320,8 @@ addend = -4; // Size of 32-bit address of the GOT /* * Relocation should be applied before the test instruction to the move instruction. - * reloc.getOffset() points to the test instruction after the instruction that loads the address of - * polling page. So set the offset appropriately. + * reloc.getOffset() points to the test instruction after the instruction that loads + * the address of polling page. So set the offset appropriately. */ offset = offset + addend; break; @@ -338,14 +342,14 @@ switch (PECoffTargetInfo.getPECoffArch()) { case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: if (relocType == RelocType.JAVA_CALL_DIRECT || - relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { + relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) { pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32; } else if (relocType == RelocType.STUB_CALL_DIRECT) { pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32; } else if (relocType == RelocType.JAVA_CALL_INDIRECT) { pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ABSOLUTE; } else if (relocType == RelocType.METASPACE_GOT_REFERENCE || - relocType == RelocType.EXTERNAL_PLT_TO_GOT) { + relocType == RelocType.EXTERNAL_PLT_TO_GOT) { pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32; } else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) { pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ADDR64; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoff.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoff.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoff.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; /** @@ -32,13 +34,13 @@ final class PECoff { //@formatter:off /** - * IMAGE_FILE_HEADER structure defines + * IMAGE_FILE_HEADER structure defines. */ enum IMAGE_FILE_HEADER { - Machine( 0, 2), - NumberOfSections( 2, 2), - TimeDateStamp( 4, 4), - PointerToSymbolTable( 8, 4), + Machine(0, 2), + NumberOfSections(2, 2), + TimeDateStamp(4, 4), + PointerToSymbolTable(8, 4), NumberOfSymbols(12, 4), SizeOfOptionalHeader(16, 2), Characteristics(18, 2); @@ -58,7 +60,7 @@ */ /** - * Machine + * Machine. */ static final char IMAGE_FILE_MACHINE_UNKNOWN = 0x0; static final char IMAGE_FILE_MACHINE_AMD64 = 0x8664; @@ -66,12 +68,12 @@ } /** - * IMAGE_SECTION_HEADER structure defines + * IMAGE_SECTION_HEADER structure defines. */ enum IMAGE_SECTION_HEADER { - Name( 0, 8), - PhysicalAddress( 8, 4), - VirtualSize( 8, 4), + Name(0, 8), + PhysicalAddress(8, 4), + VirtualSize(8, 4), VirtualAddress(12, 4), SizeOfRawData(16, 4), PointerToRawData(20, 4), @@ -96,7 +98,7 @@ */ /** - * Characteristics + * Characteristics. */ static final int IMAGE_SCN_CNT_CODE = 0x20; static final int IMAGE_SCN_CNT_INITIALIZED_DATA = 0x40; @@ -129,15 +131,15 @@ } /** - * Symbol table entry definitions + * Symbol table entry definitions. * * IMAGE_SYMBOL structure defines */ enum IMAGE_SYMBOL { - ShortName( 0, 8), - Short( 0, 4), - Long( 4, 4), - Value( 8, 4), + ShortName(0, 8), + Short(0, 4), + Long(4, 4), + Value(8, 4), SectionNumber(12, 2), Type(14, 2), StorageClass(16, 1), @@ -154,13 +156,13 @@ static int totalsize = 18; /** - * Type + * Type. */ static final int IMAGE_SYM_DTYPE_NONE = 0x0; static final int IMAGE_SYM_DTYPE_FUNCTION = 0x20; /** - * StorageClass + * StorageClass. */ static final int IMAGE_SYM_CLASS_NULL = 0x0; static final int IMAGE_SYM_CLASS_EXTERNAL = 0x2; @@ -170,12 +172,12 @@ } /** - * IMAGE_RELOCATION structure defines + * IMAGE_RELOCATION structure defines. */ enum IMAGE_RELOCATION { - VirtualAddress( 0, 4), - SymbolTableIndex( 4, 4), - Type( 8, 2); + VirtualAddress(0, 4), + SymbolTableIndex(4, 4), + Type(8, 2); final int off; final int sz; @@ -188,7 +190,7 @@ static int totalsize = 10; /** - * Relocation types + * Relocation types. */ static final int IMAGE_REL_AMD64_ABSOLUTE = 0x0; static final int IMAGE_REL_AMD64_ADDR32 = 0x2; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffByteBuffer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffByteBuffer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffByteBuffer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffContainer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffContainer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffContainer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.io.File; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffHeader.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffHeader.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffHeader.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffHeader { private final ByteBuffer header; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocEntry.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocEntry.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocEntry.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffRelocEntry { private final ByteBuffer entry; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocTable.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocTable.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffRelocTable.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,14 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; +import java.nio.ByteBuffer; import java.util.ArrayList; -import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION; -import jdk.tools.jaotc.binformat.pecoff.PECoffRelocEntry; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffRelocTable { ArrayList> relocEntries; @@ -49,14 +49,14 @@ return (4); } - int getNumRelocs(int section_index) { - return relocEntries.get(section_index).size(); + int getNumRelocs(int sectionIndex) { + return relocEntries.get(sectionIndex).size(); } // Return the relocation entries for a single section // or null if no entries added to section - byte[] getRelocData(int section_index) { - ArrayList entryList = relocEntries.get(section_index); + byte[] getRelocData(int sectionIndex) { + ArrayList entryList = relocEntries.get(sectionIndex); int entryCount = entryList.size(); int allocCount = entryCount; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSection.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSection.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSection.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,13 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffSection { private final ByteBuffer section; @@ -47,8 +48,8 @@ } // Copy only Max allowed bytes to Section Entry - byte[] Name = sectName.getBytes(); - int max = Name.length <= IMAGE_SECTION_HEADER.Name.sz ? Name.length : IMAGE_SECTION_HEADER.Name.sz; + byte[] name = sectName.getBytes(); + int max = name.length <= IMAGE_SECTION_HEADER.Name.sz ? name.length : IMAGE_SECTION_HEADER.Name.sz; assert !(sectAlign < 1 || sectAlign > 1024 || (sectAlign & (sectAlign - 1)) != 0) : "section alignment is not valid: " + sectAlign; align = sectAlign; @@ -58,7 +59,7 @@ // Clear and set alignment bits int sectFlags = (sectFlags0 & ~IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) | (sectAlignBits & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK); - section.put(Name, IMAGE_SECTION_HEADER.Name.off, max); + section.put(name, IMAGE_SECTION_HEADER.Name.off, max); section.putInt(IMAGE_SECTION_HEADER.VirtualSize.off, 0); section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,13 +21,14 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; import jdk.tools.jaotc.binformat.NativeSymbol; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffSymbol extends NativeSymbol { private final ByteBuffer sym; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymtab.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymtab.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffSymtab.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteBuffer; @@ -28,19 +30,17 @@ import java.util.ArrayList; import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL; -import jdk.tools.jaotc.binformat.pecoff.PECoffSymbol; -import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer; final class PECoffSymtab { ArrayList symbols = new ArrayList<>(); /** - * number of symbols added + * Number of symbols added. */ private int symbolCount; /** - * String holding symbol table strings + * String holding symbol table strings. */ private final StringBuilder strTabContent; @@ -51,7 +51,7 @@ private int strTabNrOfBytes; /** - * String holding Linker Directives + * String holding Linker Directives. */ private final StringBuilder directives; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffTargetInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffTargetInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/pecoff/PECoffTargetInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.binformat.pecoff; import java.nio.ByteOrder; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/HelloWorld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/HelloWorld.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 jdk.tools.jaotc.test; + +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello, world!"); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/NativeOrderOutputStreamTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/NativeOrderOutputStreamTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc.utils + * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.tools.jaotc.test.NativeOrderOutputStreamTest + */ + + + +package jdk.tools.jaotc.test; + +import jdk.tools.jaotc.utils.NativeOrderOutputStream; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class NativeOrderOutputStreamTest { + + private NativeOrderOutputStream target; + + @Before + public void setup() { + target = new NativeOrderOutputStream(); + } + + @Test + public void shouldAdd4BytesForInt() { + target.putInt(5); + Assert.assertEquals(4, target.position()); + } + + @Test + public void shouldAdd8BytesForLong() { + target.putLong(8); + Assert.assertEquals(8, target.position()); + } + + @Test + public void shouldHaveCorrectSizeBeforePatch() { + target.patchableInt(); + Assert.assertEquals(4, target.position()); + } + + @Test + public void shouldHaveCorrectSizeAfterPatch() { + NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt(); + patchableInt.set(12); + Assert.assertEquals(4, target.position()); + } + + @Test + public void shouldSetCorrectValueInPatch() { + NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt(); + patchableInt.set(42); + Assert.assertEquals(42, getInt(0)); + } + + private int getInt(int pos) { + ByteBuffer buffer = ByteBuffer.wrap(target.array()); + buffer.order(ByteOrder.nativeOrder()); + return buffer.getInt(pos); + } + + @Test + public void shouldPutArrayCorrectly() { + target.put(new byte[]{42, 5, 43, 44}); + Assert.assertEquals(4, target.position()); + Assert.assertEquals(42, target.array()[0]); + Assert.assertEquals(4, target.position()); + } + + @Test + public void shouldOnlyPatchSlot() { + NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt(); + target.putInt(7); + patchableInt.set(39); + Assert.assertEquals(39, getInt(0)); + Assert.assertEquals(7, getInt(4)); + } + + @Test + public void shouldBeAbleToPatchAnywhere() { + target.putInt(19); + NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt(); + patchableInt.set(242); + + Assert.assertEquals(19, getInt(0)); + Assert.assertEquals(242, getInt(4)); + } + + @Test + public void shouldHavePatchableAtRightOffset() { + target.putInt(27); + Assert.assertEquals(4, target.position()); + NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt(); + Assert.assertEquals(4, patchableInt.position()); + } + + @Test + public void shouldAlign() { + target.putInt(9); + target.align(16); + target.put(new byte[]{3}); + target.align(8); + Assert.assertEquals(24, target.position()); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * @run junit/othervm jdk.tools.jaotc.test.collect.ClassSearchTest + */ + + + +package jdk.tools.jaotc.test.collect; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; + +import org.junit.Assert; +import org.junit.Test; + +import jdk.tools.jaotc.LoadedClass; +import jdk.tools.jaotc.collect.ClassSearch; +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.SearchFor; +import jdk.tools.jaotc.collect.SearchPath; +import jdk.tools.jaotc.collect.SourceProvider; + +public class ClassSearchTest { + @Test(expected = InternalError.class) + public void itShouldThrowExceptionIfNoProvidersAvailable() { + ClassSearch target = new ClassSearch(); + SearchPath searchPath = new SearchPath(); + target.search(list(new SearchFor("foo")), searchPath); + } + + @Test + public void itShouldFindAProviderForEachEntry() { + Set searched = new HashSet<>(); + ClassSearch target = new ClassSearch(); + target.addProvider(provider("", (name, searchPath) -> { + searched.add(name); + return new NoopSource(); + })); + target.search(searchForList("foo", "bar", "foobar"), null); + Assert.assertEquals(hashset("foo", "bar", "foobar"), searched); + } + + private static SourceProvider provider(String supports, BiFunction fn) { + return new SourceProvider() { + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + return fn.apply(name, searchPath); + } + + @Override + public boolean supports(String type) { + return supports.equals(type); + } + }; + } + + @Test + public void itShouldOnlySearchSupportedProvidersForKnownType() { + Set visited = new HashSet<>(); + ClassSearch target = new ClassSearch(); + + target.addProvider(provider("jar", (name, searchPath) -> { + visited.add("jar"); + return null; + })); + + target.addProvider(provider("dir", (name, searchPath) -> { + visited.add("dir"); + return null; + })); + + try { + target.search(list(new SearchFor("some", "dir")), null); + } catch (InternalError e) { + // throws because no provider gives a source + } + + Assert.assertEquals(hashset("dir"), visited); + } + + @Test(expected = InternalError.class) + public void itShouldThrowErrorIfMultipleSourcesAreAvailable() { + ClassSearch target = new ClassSearch(); + target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail())); + target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail())); + + target.search(searchForList("somethign"), null); + } + + @Test + public void itShouldSearchAllProvidersForUnknownType() { + Set visited = new HashSet<>(); + ClassSearch target = new ClassSearch(); + target.addProvider(provider("", (name, searchPath) -> { + visited.add("1"); + return null; + })); + target.addProvider(provider("", (name, searchPath) -> { + visited.add("2"); + return null; + })); + + try { + target.search(searchForList("foo"), null); + } catch (InternalError e) { + // throws because no provider gives a source + } + + Assert.assertEquals(hashset("1", "2"), visited); + } + + @Test + public void itShouldTryToLoadSaidClassFromClassLoader() { + Set loaded = new HashSet<>(); + + ClassSearch target = new ClassSearch(); + target.addProvider(new SourceProvider() { + @Override + public boolean supports(String type) { + return true; + } + + @Override + public ClassSource findSource(String name, SearchPath searchPath) { + return new ClassSource() { + @Override + public void eachClass(BiConsumer consumer) { + consumer.accept("foo.Bar", new ClassLoader() { + @Override + public Class loadClass(String nm) throws ClassNotFoundException { + loaded.add(nm); + return null; + } + }); + } + }; + } + }); + + java.util.List search = target.search(searchForList("/tmp/something"), null); + Assert.assertEquals(list(new LoadedClass("foo.Bar", null)), search); + } + + @Test(expected = InternalError.class) + public void itShouldThrowInternalErrorWhenClassLoaderFails() { + ClassLoader classLoader = new ClassLoader() { + @Override + public Class loadClass(String name1) throws ClassNotFoundException { + throw new ClassNotFoundException("failed to find " + name1); + } + }; + + ClassSearch target = new ClassSearch(); + target.addProvider(provider("", (name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader))); + target.search(searchForList("foobar"), null); + } + + private static List searchForList(String... entries) { + List list = new ArrayList<>(); + for (String entry : entries) { + list.add(new SearchFor(entry)); + } + return list; + } + + @SafeVarargs + private static List list(T... entries) { + List list = new ArrayList<>(); + for (T entry : entries) { + list.add(entry); + } + return list; + } + + @SafeVarargs + private static Set hashset(T... entries) { + Set set = new HashSet<>(); + for (T entry : entries) { + set.add(entry); + } + return set; + } + + private static class NoopSource implements ClassSource { + @Override + public void eachClass(BiConsumer consumer) { + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * @build jdk.tools.jaotc.test.collect.Utils + * @run junit/othervm jdk.tools.jaotc.test.collect.ClassSourceTest + */ + + + +package jdk.tools.jaotc.test.collect; + +import org.junit.Assert; +import org.junit.Test; + +import java.nio.file.Paths; + +import static jdk.tools.jaotc.collect.ClassSource.makeClassName; + +import static jdk.tools.jaotc.test.collect.Utils.getpath; + +public class ClassSourceTest { + @Test(expected = IllegalArgumentException.class) + public void itShouldThrowExceptionIfPathDoesntEndWithClass() { + makeClassName(Paths.get("Bar.clazz")); + } + + @Test + public void itShouldReplaceSlashesWithDots() { + Assert.assertEquals("foo.Bar", makeClassName(getpath("foo/Bar.class"))); + } + + @Test + public void itShouldStripLeadingSlash() { + Assert.assertEquals("Hello", makeClassName(getpath("/Hello.class"))); + } + + @Test + public void itShouldReplaceMultipleDots() { + Assert.assertEquals("some.foo.bar.FooBar", makeClassName(getpath("/some/foo/bar/FooBar.class"))); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 jdk.tools.jaotc.test.collect; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; + +import jdk.tools.jaotc.collect.FileSupport; + +public class FakeFileSupport extends FileSupport { + private final Set exists = new HashSet<>(); + private final Set directories = new HashSet<>(); + + private final Set checkedExists = new HashSet<>(); + private final Set checkedDirectory = new HashSet<>(); + private final Set checkedJarFileSystemRoots = new HashSet<>(); + private final Set classloaderPaths = new HashSet<>(); + + private Path jarFileSystemRoot = null; + private final ClassLoader classLoader; + + public FakeFileSupport(Set existing, Set directories) { + this.exists.addAll(existing); + this.directories.addAll(directories); + + classLoader = new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + return null; + } + }; + } + + public void setJarFileSystemRoot(Path path) { + jarFileSystemRoot = path; + } + + @Override + public boolean exists(Path path) { + checkedExists.add(path.toString()); + return exists.contains(path.toString()); + } + + @Override + public boolean isDirectory(Path path) { + checkedDirectory.add(path.toString()); + return directories.contains(path.toString()); + } + + @Override + public ClassLoader createClassLoader(Path path) throws MalformedURLException { + classloaderPaths.add(path.toString()); + return classLoader; + } + + @Override + public Path getJarFileSystemRoot(Path jarFile) { + checkedJarFileSystemRoots.add(jarFile.toString()); + return jarFileSystemRoot; + } + + @Override + public boolean isAbsolute(Path entry) { + return entry.toString().startsWith("/"); + } + + public void addExist(String name) { + exists.add(name); + } + + public void addDirectory(String name) { + directories.add(name); + } + + public Set getCheckedExists() { + return checkedExists; + } + + public Set getCheckedDirectory() { + return checkedDirectory; + } + + public Set getCheckedJarFileSystemRoots() { + return checkedJarFileSystemRoots; + } + + public Set getClassloaderPaths() { + return classloaderPaths; + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 jdk.tools.jaotc.test.collect; + +import jdk.tools.jaotc.collect.SearchPath; + +import java.nio.file.FileSystem; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; + +import static jdk.tools.jaotc.test.collect.Utils.set; + +public class FakeSearchPath extends SearchPath { + private Path path = null; + public Set entries = set(); + + public FakeSearchPath(String name) { + if (name != null) { + path = Paths.get(name); + } + } + + @Override + public Path find(FileSystem fileSystem, Path entry, String... defaults) { + entries.add(entry.toString()); + return path; + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * + * @build jdk.tools.jaotc.test.collect.Utils + * @build jdk.tools.jaotc.test.collect.FakeFileSupport + * @run junit/othervm jdk.tools.jaotc.test.collect.SearchPathTest + */ + + + +package jdk.tools.jaotc.test.collect; + +import static jdk.tools.jaotc.test.collect.Utils.mkpath; +import static jdk.tools.jaotc.test.collect.Utils.mkpaths; +import static jdk.tools.jaotc.test.collect.Utils.set; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.Before; +import org.junit.Test; + +import jdk.tools.jaotc.collect.SearchPath; + +public class SearchPathTest { + private FakeFileSupport fileSupport; + private FileSystem fs; + + @Before + public void setUp() throws Exception { + fs = FileSystems.getDefault(); + } + + @Test + public void itShouldUsePathIfPathIsAbsoluteAndExisting() { + fileSupport = new FakeFileSupport(mkpaths("/foo"), set()); + SearchPath target = new SearchPath(fileSupport); + Path foo = Paths.get(mkpath("/foo")); + Path result = target.find(fs, foo); + assertSame(result, foo); + } + + @Test + public void itShouldReturnNullIfPathIsAbsoluteAndNonExisting() { + fileSupport = new FakeFileSupport(set(), set()); + SearchPath target = new SearchPath(fileSupport); + Path result = target.find(fs, Paths.get(mkpath("/bar"))); + assertNull(result); + } + + @Test + public void itShouldUseRelativeExisting() { + fileSupport = new FakeFileSupport(mkpaths("hello", "tmp/hello", "search/hello"), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("search"); + Path hello = Paths.get("hello"); + Path result = target.find(fs, hello, "tmp"); + assertSame(result, hello); + } + + @Test + public void itShouldSearchDefaultsBeforeSearchPaths() { + fileSupport = new FakeFileSupport(mkpaths("bar/foobar"), set()); + SearchPath target = new SearchPath(fileSupport); + Path result = target.find(fs, Paths.get("foobar"), "default1", "bar"); + assertEquals(mkpath("bar/foobar"), result.toString()); + assertEquals(mkpaths("foobar", "default1/foobar", "bar/foobar"), fileSupport.getCheckedExists()); + } + + @Test + public void itShouldUseSearchPathsIfNotInDefaults() { + fileSupport = new FakeFileSupport(mkpaths("bar/tmp/foobar"), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("foo/tmp", "bar/tmp"); + + Path result = target.find(fs, Paths.get("foobar"), "foo", "bar"); + assertEquals(mkpath("bar/tmp/foobar"), result.toString()); + assertEquals(mkpaths("foobar", "foo/foobar", "bar/foobar", "bar/tmp/foobar", "foo/tmp/foobar"), fileSupport.getCheckedExists()); + } + + @Test + public void itShouldReturnNullIfNoExistingPathIsFound() { + fileSupport = new FakeFileSupport(set(), set()); + SearchPath target = new SearchPath(fileSupport); + target.add("dir1", "dir2"); + + Path result = target.find(fs, Paths.get("entry"), "dir3", "dir4"); + assertNull(result); + assertEquals(mkpaths("entry", "dir1/entry", "dir2/entry", "dir3/entry", "dir4/entry"), fileSupport.getCheckedExists()); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/Utils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/Utils.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 jdk.tools.jaotc.test.collect; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.Set; + +public class Utils { + @SafeVarargs + public static Set set(T... entries) { + Set set = new HashSet<>(); + for (T entry : entries) { + set.add(entry); + } + return set; + } + + public static String mkpath(String path) { + return getpath(path).toString(); + } + + public static Set mkpaths(String... paths) { + Set set = new HashSet<>(); + for (String entry : paths) { + set.add(mkpath(entry)); + } + return set; + } + + public static Path getpath(String path) { + if (path.startsWith("/") && System.getProperty("os.name").startsWith("Windows")) { + return Paths.get(new File(path).getAbsolutePath()); + } else { + return Paths.get(path); + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * jdk.aot/jdk.tools.jaotc.collect.directory + * @compile ../Utils.java + * @compile ../FakeFileSupport.java + * @run junit/othervm jdk.tools.jaotc.test.collect.directory.DirectorySourceProviderTest + */ + + + +package jdk.tools.jaotc.test.collect.directory; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.directory.DirectorySourceProvider; +import jdk.tools.jaotc.test.collect.FakeFileSupport; +import jdk.tools.jaotc.collect.FileSupport; +import org.junit.Assert; +import org.junit.Test; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.Set; + +import static jdk.tools.jaotc.test.collect.Utils.set; + +public class DirectorySourceProviderTest { + @Test + public void itShouldReturnNullForNonExistantPath() { + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set(), set())); + ClassSource result = target.findSource("hello", null); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullForNonDirectory() { + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set())); + ClassSource result = target.findSource("foobar", null); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullForMalformedURI() { + Set visited = set(); + DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set("foobar")) { + @Override + public ClassLoader createClassLoader(Path path) throws MalformedURLException { + visited.add("1"); + throw new MalformedURLException("..."); + } + }); + ClassSource result = target.findSource("foobar", null); + Assert.assertNull(result); + Assert.assertEquals(set("1"), visited); + } + + @Test + public void itShouldCreateSourceIfNameExistsAndIsADirectory() { + FileSupport fileSupport = new FakeFileSupport(set("foo"), set("foo")); + DirectorySourceProvider target = new DirectorySourceProvider(fileSupport); + ClassSource foo = target.findSource("foo", null); + Assert.assertNotNull(foo); + Assert.assertEquals("directory:foo", foo.toString()); + } + +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * jdk.aot/jdk.tools.jaotc.collect.jar + * @compile ../Utils.java + * @compile ../FakeFileSupport.java + * @compile ../FakeSearchPath.java + * + * @run junit/othervm jdk.tools.jaotc.test.collect.jar.JarSourceProviderTest + */ + + + +package jdk.tools.jaotc.test.collect.jar; + +import static jdk.tools.jaotc.test.collect.Utils.mkpath; +import static jdk.tools.jaotc.test.collect.Utils.set; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.ProviderNotFoundException; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import jdk.tools.jaotc.collect.ClassSource; +import jdk.tools.jaotc.collect.jar.JarSourceProvider; +import jdk.tools.jaotc.test.collect.FakeFileSupport; +import jdk.tools.jaotc.test.collect.FakeSearchPath; + +public class JarSourceProviderTest { + + private FakeFileSupport fileSupport; + private JarSourceProvider target; + + @Before + public void setUp() throws Exception { + fileSupport = new FakeFileSupport(set(), set()); + target = new JarSourceProvider(fileSupport); + } + + @Test + public void itShouldUseSearchPathToFindPath() { + FakeSearchPath searchPath = new FakeSearchPath(null); + target.findSource("hello", searchPath); + + Assert.assertEquals(set("hello"), searchPath.entries); + } + + @Test + public void itShouldReturnNullIfPathIsNull() { + ClassSource source = target.findSource("foobar", new FakeSearchPath(null)); + Assert.assertNull(source); + } + + @Test + public void itShouldReturnNullIfPathIsDirectory() { + fileSupport.addDirectory("hello/foobar"); + ClassSource source = target.findSource("foobar", new FakeSearchPath("hello/foobar")); + + Assert.assertNull(source); + Assert.assertEquals(set(mkpath("hello/foobar")), fileSupport.getCheckedDirectory()); + } + + @Test + public void itShouldReturnNullIfUnableToMakeJarFileSystem() { + fileSupport.setJarFileSystemRoot(null); + ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar")); + + Assert.assertEquals(set(mkpath("foo/bar")), fileSupport.getCheckedJarFileSystemRoots()); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnNullIfNotValidJarProvider() { + fileSupport = new FakeFileSupport(set(), set()) { + + @Override + public Path getJarFileSystemRoot(Path jarFile) { + super.getJarFileSystemRoot(jarFile); + throw new ProviderNotFoundException(); + } + }; + fileSupport.setJarFileSystemRoot(null); + target = new JarSourceProvider(fileSupport); + + ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar")); + + Assert.assertEquals(set(mkpath("foo/bar")), fileSupport.getCheckedJarFileSystemRoots()); + Assert.assertNull(result); + } + + @Test + public void itShouldReturnSourceWhenAllIsValid() { + fileSupport.setJarFileSystemRoot(Paths.get("some/bar")); + ClassSource result = target.findSource("foobar", new FakeSearchPath("this/bar")); + + Assert.assertEquals(set(mkpath("this/bar")), fileSupport.getClassloaderPaths()); + Assert.assertEquals("jar:" + mkpath("this/bar"), result.toString()); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @requires vm.aot + * @modules jdk.aot/jdk.tools.jaotc + * jdk.aot/jdk.tools.jaotc.collect + * jdk.aot/jdk.tools.jaotc.collect.module + * @compile ../Utils.java + * @run junit/othervm jdk.tools.jaotc.test.collect.module.ModuleSourceProviderTest + */ + + + +package jdk.tools.jaotc.test.collect.module; + +import static jdk.tools.jaotc.test.collect.Utils.mkpath; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.function.BiFunction; + +import org.junit.Before; +import org.junit.Test; + +import jdk.tools.jaotc.collect.FileSupport; +import jdk.tools.jaotc.collect.module.ModuleSource; +import jdk.tools.jaotc.collect.module.ModuleSourceProvider; + +public class ModuleSourceProviderTest { + private ClassLoader classLoader; + private ModuleSourceProvider target; + private FileSupport fileSupport; + private BiFunction getSubDirectory = null; + + @Before + public void setUp() { + classLoader = new FakeClassLoader(); + fileSupport = new FileSupport() { + + @Override + public boolean isDirectory(Path path) { + return true; + } + + @Override + public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException { + if (getSubDirectory == null) { + throw new IOException("Nope"); + } + return getSubDirectory.apply(root, path); + } + }; + target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader, fileSupport); + } + + @Test + public void itShouldUseFileSupport() { + getSubDirectory = (root, path) -> { + if (root.toString().equals("modules") && path.toString().equals("test.module")) { + return Paths.get("modules/test.module"); + } + return null; + }; + + ModuleSource source = (ModuleSource) target.findSource("test.module", null); + assertEquals(mkpath("modules/test.module"), source.getModulePath().toString()); + assertEquals("module:" + mkpath("modules/test.module"), source.toString()); + } + + private static class FakeClassLoader extends ClassLoader { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + return null; + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ListIterator; @@ -28,7 +30,6 @@ import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.GraalCompiler; import org.graalvm.compiler.core.common.CompilationIdentifier; -import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.hotspot.HotSpotBackend; import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.concurrent.TimeUnit; @@ -87,6 +89,7 @@ /** * Compile a method or a constructor. */ + @Override @SuppressWarnings("try") public void run() { // Ensure a JVMCI runtime is initialized prior to Debug being initialized as the former @@ -186,12 +189,15 @@ @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (obj == null) + } + if (obj == null) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } AOTCompilationTask other = (AOTCompilationTask) obj; return (this.id == other.id); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,27 +21,27 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; +import jdk.tools.jaotc.AOTDynamicTypeStore.AdapterLocation; +import jdk.tools.jaotc.AOTDynamicTypeStore.AppendixLocation; +import jdk.tools.jaotc.AOTDynamicTypeStore.Location; import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.tools.jaotc.binformat.ReadOnlyDataContainer; import jdk.tools.jaotc.binformat.Symbol.Binding; import jdk.tools.jaotc.binformat.Symbol.Kind; - import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.tools.jaotc.AOTDynamicTypeStore.AdapterLocation; -import jdk.tools.jaotc.AOTDynamicTypeStore.AppendixLocation; -import jdk.tools.jaotc.AOTDynamicTypeStore.Location; - /** * Class encapsulating Graal-compiled output of a Java class. The compilation result of all methods * of a class {@code className} are maintained in an array list. @@ -74,7 +74,7 @@ this.dependentMethods = new ArrayList<>(); this.classId = classId; this.type = type; - this.metadataName = type.isAnonymous() ? "anon<"+ classId + ">": type.getName(); + this.metadataName = type.isAnonymous() ? "anon<" + classId + ">" : type.getName(); this.gotIndex = binaryContainer.addTwoSlotKlassSymbol(metadataName); this.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods. this.dependentMethodsOffset = -1; @@ -84,9 +84,9 @@ String name = metadataName; Set locs = dynoStore.getDynamicClassLocationsForType(type); if (locs == null) { - return new String[] {name}; + return new String[]{name}; } else { - ArrayList names = new ArrayList(); + ArrayList names = new ArrayList<>(); names.add(name); for (Location l : locs) { HotSpotResolvedObjectType cpType = l.getHolder(); @@ -95,14 +95,14 @@ // may record types that don't make it into the final graph. // We can safely ignore those here. if (data == null) { - // Not a compiled or inlined method - continue; + // Not a compiled or inlined method + continue; } int cpi = l.getCpi(); - String location = "<"+ data.classId + ":" + cpi + ">"; + String location = "<" + data.classId + ":" + cpi + ">"; if (l instanceof AdapterLocation) { names.add("adapter" + location); - AdapterLocation a = (AdapterLocation)l; + AdapterLocation a = (AdapterLocation) l; names.add("adapter:" + a.getMethodId() + location); } else { assert l instanceof AppendixLocation; @@ -319,26 +319,23 @@ /** * Add a klass data. */ - synchronized static AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) { - String name = type.getName(); - AOTKlassData data = klassData.get(name); - if (data != null) { - assert data.getType() == type : "duplicate classes for name " + name; - } else { + static synchronized AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) { + AOTKlassData data = getAOTKlassData(type); + if (data == null) { data = new AOTKlassData(binaryContainer, type, classesCount++); - klassData.put(name, data); + klassData.put(type.getName(), data); } return data; } - private synchronized static AOTKlassData getAOTKlassData(String name) { - return klassData.get(name); - } - - synchronized static AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) { + static synchronized AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) { String name = type.getName(); - AOTKlassData data = getAOTKlassData(name); - assert data == null || data.getType() == type : "duplicate classes for name " + name; + AOTKlassData data = klassData.get(name); + if (data != null) { + HotSpotResolvedObjectType oldType = data.getType(); + assert oldType == type : "duplicate classes for name " + type.getName() + ", fingerprints old: " + oldType.getFingerprint() + ", new: " + type.getFingerprint() + + ", klass pointers old: " + oldType.klass() + ", new: " + type.klass(); + } return data; } @@ -363,17 +360,14 @@ } } - synchronized static AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) { + static synchronized AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) { if (type.isArray()) { return addAOTKlassData(binaryContainer, type); } assert type.getFingerprint() != 0 : "no fingerprint for " + type.getName(); AOTKlassData old = getAOTKlassData(type); if (old != null) { - boolean assertsEnabled = false; - // Next assignment will be executed when asserts are enabled. - assert assertsEnabled = true; - if (assertsEnabled) { + if (areAssertionsEnabled()) { HotSpotResolvedObjectType s = type.getSuperclass(); if (s != null) { assert getAOTKlassData(s) != null : "fingerprint for super " + s.getName() + " needed for " + type.getName(); @@ -397,6 +391,14 @@ return addAOTKlassData(binaryContainer, type); } + @SuppressWarnings("all") + private static boolean areAssertionsEnabled() { + boolean assertsEnabled = false; + // Next assignment will be executed when asserts are enabled. + assert assertsEnabled = true; + return assertsEnabled; + } + /* * Put methods data to contained. */ @@ -431,9 +433,7 @@ } static HotSpotResolvedObjectType getType(Object ref) { - return (ref instanceof HotSpotResolvedObjectType) ? - (HotSpotResolvedObjectType)ref : - ((HotSpotResolvedJavaMethod)ref).getDeclaringClass(); + return (ref instanceof HotSpotResolvedObjectType) ? (HotSpotResolvedObjectType) ref : ((HotSpotResolvedJavaMethod) ref).getDeclaringClass(); } static String metadataName(HotSpotResolvedObjectType type) { @@ -448,11 +448,11 @@ static String metadataName(Object ref) { if (ref instanceof HotSpotResolvedJavaMethod) { - HotSpotResolvedJavaMethod m = (HotSpotResolvedJavaMethod)ref; + HotSpotResolvedJavaMethod m = (HotSpotResolvedJavaMethod) ref; return metadataName(m); } else { assert ref instanceof HotSpotResolvedObjectType : "unexpected object type " + ref.getClass().getName(); - HotSpotResolvedObjectType type = (HotSpotResolvedObjectType)ref; + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ref; return metadataName(type); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiler.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiler.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ArrayList; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTDynamicTypeStore.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTDynamicTypeStore.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTDynamicTypeStore.java Fri Aug 17 13:20:53 2018 -0700 @@ -20,32 +20,23 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.tools.jaotc; -import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin.DynamicTypeStore; -import org.graalvm.compiler.nodes.ConstantNode; -import org.graalvm.compiler.nodes.StructuredGraph; -import org.graalvm.compiler.nodes.ValueNode; -import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin; -import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; -import jdk.vm.ci.hotspot.HotSpotConstantPool; -import jdk.vm.ci.hotspot.HotSpotConstantPoolObject; -import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; -import jdk.vm.ci.hotspot.HotSpotObjectConstant; -import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import jdk.vm.ci.meta.ConstantPool; -import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; +package jdk.tools.jaotc; import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin.DynamicTypeStore; + +import jdk.vm.ci.hotspot.HotSpotConstantPool; +import jdk.vm.ci.hotspot.HotSpotConstantPoolObject; +import jdk.vm.ci.hotspot.HotSpotObjectConstant; +import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; +import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; +import jdk.vm.ci.meta.JavaConstant; + final class AOTDynamicTypeStore implements DynamicTypeStore { public static class Location { @@ -60,15 +51,22 @@ public HotSpotResolvedObjectType getHolder() { return holder; } + public int getCpi() { return cpi; } + + @Override public String toString() { return getHolder().getName() + "@" + cpi; } + + @Override public int hashCode() { return holder.hashCode() + getClass().hashCode() + cpi; } + + @Override public boolean equals(Object o) { if (this == o) { return true; @@ -76,7 +74,7 @@ if (getClass() != o.getClass()) { return false; } - Location l = (Location)o; + Location l = (Location) o; return cpi == l.cpi && holder.equals(l.holder); } } @@ -88,9 +86,12 @@ super(holder, cpi); this.methodId = methodId; } + public int getMethodId() { return methodId; } + + @Override public String toString() { return "adapter:" + methodId + "@" + super.toString(); } @@ -100,6 +101,8 @@ AppendixLocation(HotSpotResolvedObjectType holder, int cpi) { super(holder, cpi); } + + @Override public String toString() { return "appendix@" + super.toString(); } @@ -122,7 +125,7 @@ @Override public void recordAdapter(int opcode, HotSpotResolvedObjectType holder, int index, HotSpotResolvedJavaMethod adapter) { - int cpi = ((HotSpotConstantPool)holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); + int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); int methodId = adapter.methodIdnum(); HotSpotResolvedObjectType adapterType = adapter.getDeclaringClass(); recordDynamicTypeLocation(new AdapterLocation(holder, cpi, methodId), adapterType); @@ -130,8 +133,8 @@ @Override public JavaConstant recordAppendix(int opcode, HotSpotResolvedObjectType holder, int index, JavaConstant appendix) { - int cpi = ((HotSpotConstantPool)holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); - HotSpotResolvedObjectType appendixType = ((HotSpotObjectConstant)appendix).getType(); + int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode); + HotSpotResolvedObjectType appendixType = ((HotSpotObjectConstant) appendix).getType(); recordDynamicTypeLocation(new AppendixLocation(holder, cpi), appendixType); // Make the constant locatable return HotSpotConstantPoolObject.forObject(holder, cpi, appendix); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTHotSpotResolvedJavaMethod.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTHotSpotResolvedJavaMethod.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTHotSpotResolvedJavaMethod.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import org.graalvm.compiler.code.CompilationResult; @@ -39,15 +41,18 @@ this.backend = backend; } + @Override public String getSymbolName() { return JavaMethodInfo.uniqueMethodName(method); } + @Override public String getNameAndSignature() { String className = method.getDeclaringClass().getName(); return className + "." + method.getName() + method.getSignature().toMethodDescriptor(); } + @Override public HotSpotCompiledCode compiledCode(CompilationResult result) { return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTStub.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTStub.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import org.graalvm.compiler.code.CompilationResult; @@ -40,14 +42,17 @@ this.backend = backend; } + @Override public String getSymbolName() { return stub.toString(); } + @Override public String getNameAndSignature() { return stub.toString(); } + @Override public HotSpotCompiledCode compiledCode(CompilationResult result) { return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import org.graalvm.compiler.bytecode.Bytecodes; @@ -33,7 +35,7 @@ final class CallInfo { static boolean isStaticTarget(Call call) { - return !((HotSpotResolvedJavaMethod)call.target).hasReceiver(); + return !((HotSpotResolvedJavaMethod) call.target).hasReceiver(); } private static boolean isStaticOpcode(Call call) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.Relocation.RelocType; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallSiteRelocationSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.List; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeSectionProcessor.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeSectionProcessor.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeSectionProcessor.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,18 +21,18 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ArrayList; +import org.graalvm.compiler.code.CompilationResult; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; + import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.tools.jaotc.binformat.CodeContainer; import jdk.tools.jaotc.binformat.Symbol; -import jdk.tools.jaotc.StubInformation; -import org.graalvm.compiler.code.CompilationResult; -import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; - -import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.code.site.Call; @@ -75,7 +75,7 @@ if (infopoint.reason == InfopointReason.CALL) { final Call callInfopoint = (Call) infopoint; if (callInfopoint.target instanceof HotSpotForeignCallLinkage && - target.arch instanceof AMD64) { + target.arch instanceof AMD64) { // TODO 4 is x86 size of relative displacement. // For SPARC need something different. int destOffset = infopoint.pcOffset + callInfopoint.size - 4; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Collector.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Collector.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Collector.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.io.BufferedReader; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompilationSpec.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompilationSpec.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompilationSpec.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.HashSet; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.concurrent.atomic.AtomicInteger; @@ -147,7 +149,7 @@ } /** - * Method name + * Method name. */ private String name; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataBuilder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataBuilder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataBuilder.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ArrayList; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,21 +21,22 @@ * questions. */ + + package jdk.tools.jaotc; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import org.graalvm.compiler.code.DataSection; +import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction; + import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.tools.jaotc.binformat.Relocation; import jdk.tools.jaotc.binformat.Relocation.RelocType; import jdk.tools.jaotc.binformat.Symbol; import jdk.tools.jaotc.binformat.Symbol.Binding; import jdk.tools.jaotc.binformat.Symbol.Kind; -import jdk.tools.jaotc.AOTCompiledClass; -import org.graalvm.compiler.code.DataSection; -import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction; - import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.code.site.ConstantReference; import jdk.vm.ci.code.site.DataPatch; @@ -97,7 +98,7 @@ } else if (constant instanceof HotSpotObjectConstant) { HotSpotObjectConstant oopConstant = (HotSpotObjectConstant) constant; if (oopConstant instanceof HotSpotConstantPoolObject) { - HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject)oopConstant; + HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject) oopConstant; // Even if two locations use the same object, resolve separately targetSymbol = "ldc." + cpo.getCpType().getName() + cpo.getCpi(); } else { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ELFMacroAssembler.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ELFMacroAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ELFMacroAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,20 +21,20 @@ * questions. */ + + package jdk.tools.jaotc; -import jdk.tools.jaotc.StubInformation; +import jdk.tools.jaotc.aarch64.AArch64ELFMacroAssembler; import jdk.tools.jaotc.amd64.AMD64ELFMacroAssembler; -import jdk.tools.jaotc.aarch64.AArch64ELFMacroAssembler; - +import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.aarch64.AArch64; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.TargetDescription; public interface ELFMacroAssembler { - public static ELFMacroAssembler getELFMacroAssembler(TargetDescription target) { + static ELFMacroAssembler getELFMacroAssembler(TargetDescription target) { Architecture architecture = target.arch; if (architecture instanceof AMD64) { return new AMD64ELFMacroAssembler(target); @@ -45,12 +45,12 @@ } } - public int currentEndOfInstruction(); + int currentEndOfInstruction(); - public byte[] getPLTJumpCode(); + byte[] getPLTJumpCode(); - public byte[] getPLTStaticEntryCode(StubInformation stub); + byte[] getPLTStaticEntryCode(StubInformation stub); - public byte[] getPLTVirtualEntryCode(StubInformation stub); + byte[] getPLTVirtualEntryCode(StubInformation stub); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignCallSiteRelocationSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignGotCallSiteRelocationSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignGotCallSiteRelocationSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/ForeignGotCallSiteRelocationSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/GraalFilters.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.lang.annotation.Annotation; @@ -30,12 +32,6 @@ import java.util.Set; import java.util.stream.Collectors; -import jdk.vm.ci.hotspot.HotSpotConstantPool; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; - import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.replacements.ClassSubstitution; import org.graalvm.compiler.api.replacements.MethodSubstitution; @@ -47,6 +43,12 @@ import org.graalvm.compiler.replacements.Snippets; import jdk.internal.vm.compiler.word.WordBase; +import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.hotspot.HotSpotConstantPool; + final class GraalFilters { private List specialClasses; private List specialArgumentAndReturnTypes; @@ -90,7 +92,7 @@ return false; } // Skip klass with Condy until Graal is fixed. - if (((HotSpotConstantPool)((HotSpotResolvedObjectType) klass).getConstantPool()).hasDynamicConstant()) { + if (((HotSpotConstantPool) ((HotSpotResolvedObjectType) klass).getConstantPool()).hasDynamicConstant()) { return false; } return true; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InfopointProcessor.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InfopointProcessor.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InfopointProcessor.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InstructionDecoder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InstructionDecoder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/InstructionDecoder.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.amd64.AMD64InstructionDecoder; @@ -38,13 +40,13 @@ if (architecture instanceof AMD64) { return new AMD64InstructionDecoder(target); } else if (architecture instanceof AArch64) { - return new AArch64InstructionDecoder(target); + return new AArch64InstructionDecoder(); } else { throw new InternalError("Unsupported architecture " + architecture); } } - public abstract void decodePosition(final byte[] code, int pcOffset); + public abstract void decodePosition(byte[] code, int pcOffset); public abstract int currentEndOfInstruction(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.Relocation.RelocType; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,12 +21,12 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.tools.jaotc.binformat.Symbol; -import jdk.tools.jaotc.StubInformation; - import jdk.vm.ci.code.site.Call; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; @@ -44,11 +44,11 @@ String archStr = System.getProperty("os.arch").toLowerCase(); if (archStr.equals("aarch64")) { // AArch64 is a special case: it uses 48-bit addresses. - byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, 0, 0}; - minusOneSlot = non_oop_word; + byte[] nonOopWord = {-1, -1, -1, -1, -1, -1, 0, 0}; + minusOneSlot = nonOopWord; } else { - byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, -1, -1}; - minusOneSlot = non_oop_word; + byte[] nonOopWord = {-1, -1, -1, -1, -1, -1, -1, -1}; + minusOneSlot = nonOopWord; } } @@ -135,7 +135,6 @@ */ private static String getResolveSymbolName(CompiledMethodInfo mi, Call call) { String resolveSymbolName; - String name = call.target.toString(); if (CallInfo.isStaticCall(call)) { assert mi.hasMark(call, MarkId.INVOKESTATIC); resolveSymbolName = BinaryContainer.getResolveStaticEntrySymbolName(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaMethodInfo.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaMethodInfo.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaMethodInfo.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import org.graalvm.compiler.code.CompilationResult; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.io.BufferedReader; @@ -148,32 +150,7 @@ } /** - * Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012 - */ - public enum VSVERSIONS { - VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"), - VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"), - VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe"); - - private final String envvariable; - private final String wkp; - - VSVERSIONS(String envvariable, String wellknownpath) { - this.envvariable = envvariable; - this.wkp = wellknownpath; - } - - String EnvVariable() { - return envvariable; - } - - String WellKnownPath() { - return wkp; - } - } - - /** - * Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012 + * Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012. */ private static String getWindowsLinkPath() { String link = "\\VC\\bin\\amd64\\link.exe"; @@ -182,7 +159,7 @@ * First try searching the paths pointed to by the VS environment variables. */ for (VSVERSIONS vs : VSVERSIONS.values()) { - String vspath = System.getenv(vs.EnvVariable()); + String vspath = System.getenv(vs.getEnvVariable()); if (vspath != null) { File commonTools = new File(vspath); File vsRoot = commonTools.getParentFile().getParentFile(); @@ -197,7 +174,7 @@ * If we didn't find via the VS environment variables, try the well known paths */ for (VSVERSIONS vs : VSVERSIONS.values()) { - String wkp = vs.WellKnownPath(); + String wkp = vs.getWellKnownPath(); if (new File(wkp).exists()) { return wkp; } @@ -206,4 +183,30 @@ return null; } + // @formatter:off (workaround for Eclipse formatting bug) + /** + * Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012. + */ + enum VSVERSIONS { + VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"), + VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"), + VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe"); + + private final String envvariable; + private final String wkp; + + VSVERSIONS(String envvariable, String wellknownpath) { + this.envvariable = envvariable; + this.wkp = wellknownpath; + } + + String getEnvVariable() { + return envvariable; + } + + String getWellKnownPath() { + return wkp; + } + } + // @formatter:on } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; public class LoadedClass { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LogPrinter.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LogPrinter.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LogPrinter.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.io.FileWriter; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; @@ -33,9 +35,6 @@ import java.util.ListIterator; import java.util.Set; -import jdk.tools.jaotc.binformat.BinaryContainer; -import jdk.tools.jaotc.Options.Option; - import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; import org.graalvm.compiler.api.runtime.GraalJVMCICompiler; import org.graalvm.compiler.debug.DebugContext; @@ -45,7 +44,6 @@ import org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory; import org.graalvm.compiler.hotspot.HotSpotGraalOptionValues; import org.graalvm.compiler.hotspot.HotSpotGraalRuntime; -import org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC; import org.graalvm.compiler.hotspot.HotSpotHostBackend; import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin; import org.graalvm.compiler.java.GraphBuilderPhase; @@ -57,6 +55,8 @@ import org.graalvm.compiler.printer.GraalDebugHandlersFactory; import org.graalvm.compiler.runtime.RuntimeProvider; +import jdk.tools.jaotc.Options.Option; +import jdk.tools.jaotc.binformat.BinaryContainer; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.runtime.JVMCI; @@ -182,7 +182,7 @@ System.gc(); } - int gc = runtime.getGarbageCollector().ordinal()+1; + int gc = runtime.getGarbageCollector().ordinal() + 1; BinaryContainer binaryContainer = new BinaryContainer(graalOptions, graalHotSpotVMConfig, graphBuilderConfig, gc, JVM_VERSION); DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; @@ -55,7 +57,7 @@ private final int value; - private MarkId(String name) { + MarkId(String name) { this.value = (int) (long) HotSpotJVMCIRuntime.runtime().getConfigStore().getConstants().get(name); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.util.ArrayList; @@ -33,7 +35,6 @@ import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; - import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.site.DataPatch; import jdk.vm.ci.code.site.Infopoint; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Options.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Options.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Options.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import java.text.MessageFormat; @@ -255,7 +257,8 @@ } // Make checkstyle happy. - for (int i = 0; i < args.length; i++) { + int i = 0; + while (i < args.length) { String arg = args[i]; if (arg.charAt(0) == '-') { @@ -282,6 +285,7 @@ } else { task.options.files.add(new SearchFor(arg)); } + i++; } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubDirectCallSiteRelocationSymbol.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubDirectCallSiteRelocationSymbol.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubDirectCallSiteRelocationSymbol.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; import jdk.tools.jaotc.binformat.BinaryContainer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubInformation.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubInformation.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/StubInformation.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,15 +21,20 @@ * questions. */ + + package jdk.tools.jaotc; public final class StubInformation { private int stubOffset; // the offset inside the code (text + stubOffset) private int stubSize; // the stub size private int dispatchJumpOffset; // offset after main dispatch jump instruction - private int resolveJumpOffset; // offset after jump instruction to runtime call resolution function. - private int resolveJumpStart; // offset of jump instruction to VM runtime call resolution function. - private int c2iJumpOffset; // offset after jump instruction to c2i adapter for static calls. + private int resolveJumpOffset; // offset after jump instruction to runtime call resolution + // function. + private int resolveJumpStart; // offset of jump instruction to VM runtime call resolution + // function. + private int c2iJumpOffset; // offset after jump instruction to c2i adapter for static + // calls. private int movOffset; // offset after move instruction which loads from got cell: // - Method* for static call // - Klass* for virtual call diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Timer.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Timer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Timer.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc; final class Timer implements AutoCloseable { @@ -34,6 +36,7 @@ main.printer.printInfo(message); } + @Override public void close() { final long end = System.currentTimeMillis(); main.printer.printlnInfo(" (" + (end - start) + " ms)"); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64ELFMacroAssembler.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64ELFMacroAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64ELFMacroAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -22,19 +22,21 @@ * questions. */ + + package jdk.tools.jaotc.aarch64; -import jdk.tools.jaotc.StubInformation; -import jdk.tools.jaotc.ELFMacroAssembler; +import static jdk.vm.ci.aarch64.AArch64.r12; +import static jdk.vm.ci.aarch64.AArch64.r16; +import static jdk.vm.ci.aarch64.AArch64.r17; +import static jdk.vm.ci.aarch64.AArch64.r9; import org.graalvm.compiler.asm.aarch64.AArch64Address; import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler; - +import jdk.tools.jaotc.ELFMacroAssembler; +import jdk.tools.jaotc.StubInformation; import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.code.Register; - -import static jdk.vm.ci.aarch64.AArch64.*; public final class AArch64ELFMacroAssembler extends AArch64MacroAssembler implements ELFMacroAssembler { @@ -71,7 +73,7 @@ jmp(r16); stub.setDispatchJumpOffset(position()); - // C2I stub used to call interpreter. First load r12 + // C2I stub used to call interpreter. First load r12 // (i.e. rmethod) with a pointer to the Method structure ... addressOf(r12); ldr(64, r12, AArch64Address.createBaseRegisterOnlyAddress(r12)); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64InstructionDecoder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64InstructionDecoder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/aarch64/AArch64InstructionDecoder.java Fri Aug 17 13:20:53 2018 -0700 @@ -22,17 +22,17 @@ * questions. */ + + package jdk.tools.jaotc.aarch64; import jdk.tools.jaotc.InstructionDecoder; -import jdk.vm.ci.code.TargetDescription; - public final class AArch64InstructionDecoder extends InstructionDecoder { private int currentEndOfInstruction; - public AArch64InstructionDecoder(TargetDescription target) { + public AArch64InstructionDecoder() { } @Override diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64ELFMacroAssembler.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64ELFMacroAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64ELFMacroAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.amd64; import static jdk.vm.ci.amd64.AMD64.rax; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64InstructionDecoder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64InstructionDecoder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/amd64/AMD64InstructionDecoder.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.amd64; import jdk.tools.jaotc.InstructionDecoder; @@ -61,11 +63,13 @@ static final int VEX_2BYTES = 0xC5; } + @SuppressWarnings("unused") private static class VexPrefix { static final int VEX_R = 0x80; static final int VEX_W = 0x80; } + @SuppressWarnings("unused") private static class VexOpcode { static final int VEX_OPCODE_NONE = 0x0; static final int VEX_OPCODE_0F = 0x1; @@ -112,7 +116,7 @@ againAfterPrefix = false; switch (0xFF & code[ip++]) { - // These convenience macros generate groups of "case" labels for the switch. + // These convenience macros generate groups of "case" labels for the switch. case Prefix.CSSegment: case Prefix.SSSegment: @@ -421,18 +425,18 @@ case Prefix.VEX_3BYTES: case Prefix.VEX_2BYTES: assert ip == pcOffset + 1 : "no prefixes allowed"; - int vex_opcode; + int vexOpcode; // First byte if ((code[pcOffset] & 0xFF) == Prefix.VEX_3BYTES) { - vex_opcode = VexOpcode.VEX_OPCODE_MASK & code[ip]; + vexOpcode = VexOpcode.VEX_OPCODE_MASK & code[ip]; ip++; // third byte is64bit = ((VexPrefix.VEX_W & code[ip]) == VexPrefix.VEX_W); } else { - vex_opcode = VexOpcode.VEX_OPCODE_0F; + vexOpcode = VexOpcode.VEX_OPCODE_0F; } ip++; // opcode // To find the end of instruction (which == end_pc_operand). - switch (vex_opcode) { + switch (vexOpcode) { case VexOpcode.VEX_OPCODE_0F: switch (0xFF & code[ip]) { case 0x70: // pshufd r, r/a, #8 diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect; import jdk.tools.jaotc.LoadedClass; @@ -37,7 +39,9 @@ } public List search(List search, SearchPath searchPath) { - return search(search, searchPath, (s, t) -> { throw new InternalError(s + " : " + t, t); } ); + return search(search, searchPath, (s, t) -> { + throw new InternalError(s + " : " + t, t); + }); } public List search(List search, SearchPath searchPath, BiConsumer classLoadingErrorsHandler) { @@ -53,7 +57,9 @@ if (source != null) { source.eachClass((name, loader) -> { LoadedClass x = loadClass(name, loader, classLoadingErrorsHandler); - if (x != null) { loaded.add(x); } + if (x != null) { + loaded.add(x); + } }); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect; import java.nio.file.Path; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,11 +21,21 @@ * questions. */ + + package jdk.tools.jaotc.collect; import java.io.IOException; -import java.net.*; -import java.nio.file.*; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; public class FileSupport { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,16 +21,23 @@ * questions. */ + + package jdk.tools.jaotc.collect; +import static java.nio.file.FileVisitResult.CONTINUE; + import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Iterator; -import static java.nio.file.FileVisitResult.CONTINUE; - /** * {@link FileVisitor} implementation to find class files recursively. */ diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect; public final class SearchFor { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect; import java.nio.file.FileSystem; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect; public interface SourceProvider { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.classname; import jdk.tools.jaotc.collect.ClassSource; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.classname; import jdk.tools.jaotc.collect.ClassSource; @@ -32,7 +34,7 @@ import java.nio.file.Paths; public final class ClassNameSourceProvider implements SourceProvider { - public final static String TYPE = "class"; + public static final String TYPE = "class"; private final ClassLoader classLoader; public ClassNameSourceProvider(FileSupport fileSupport) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.directory; import jdk.tools.jaotc.collect.ClassSource; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.directory; import jdk.tools.jaotc.collect.ClassSource; @@ -36,7 +38,7 @@ public final class DirectorySourceProvider implements SourceProvider { private final FileSupport fileSupport; private final FileSystem fileSystem; - public final static String TYPE = "directory"; + public static final String TYPE = "directory"; public DirectorySourceProvider(FileSupport fileSupport) { this.fileSupport = fileSupport; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.jar; import jdk.tools.jaotc.collect.ClassSource; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.jar; import jdk.tools.jaotc.collect.ClassSource; @@ -37,7 +39,7 @@ public final class JarSourceProvider implements SourceProvider { private final FileSystem fileSystem; private final FileSupport fileSupport; - public final static String TYPE = "jar"; + public static final String TYPE = "jar"; public JarSourceProvider() { this(new FileSupport()); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.module; import jdk.tools.jaotc.collect.ClassSource; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.collect.module; import jdk.tools.jaotc.collect.ClassSource; @@ -38,7 +40,7 @@ private final FileSystem fileSystem; private final ClassLoader classLoader; private final FileSupport fileSupport; - public final static String TYPE = "module"; + public static final String TYPE = "module"; public ModuleSourceProvider() { this(FileSystems.getFileSystem(URI.create("jrt:/")), ClassLoader.getSystemClassLoader(), new FileSupport()); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/utils/NativeOrderOutputStream.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/utils/NativeOrderOutputStream.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/utils/NativeOrderOutputStream.java Fri Aug 17 13:20:53 2018 -0700 @@ -21,6 +21,8 @@ * questions. */ + + package jdk.tools.jaotc.utils; import java.io.ByteArrayOutputStream; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java --- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -30,7 +30,7 @@ import java.util.List; import org.graalvm.compiler.serviceprovider.ServiceProvider; -import org.graalvm.compiler.serviceprovider.GraalServices.JMXService; +import org.graalvm.compiler.serviceprovider.JMXService; import com.sun.management.ThreadMXBean; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java --- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicMapImplTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -114,7 +114,12 @@ } }); set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); - Assert.assertTrue(set.add(new Integer(0))); + Assert.assertTrue(set.add(newInteger(0))); + } + + @SuppressWarnings("deprecation") + private static Integer newInteger(int value) { + return new Integer(value); } @Test(expected = UnsupportedOperationException.class) diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java --- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections.test/src/jdk/internal/vm/compiler/collections/test/EconomicSetTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -142,7 +142,12 @@ } Assert.assertEquals(initialList, removalList); Assert.assertEquals(1, finalList.size()); - Assert.assertEquals(new Integer(9), finalList.get(0)); + Assert.assertEquals(newInteger(9), finalList.get(0)); + } + + @SuppressWarnings("deprecation") + private static Integer newInteger(int value) { + return new Integer(value); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/module-info.java --- a/src/jdk.internal.vm.compiler/share/classes/module-info.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/module-info.java Fri Aug 17 13:20:53 2018 -0700 @@ -39,7 +39,7 @@ uses org.graalvm.compiler.hotspot.HotSpotCodeCacheListener; uses org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration; uses org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory; - uses org.graalvm.compiler.serviceprovider.GraalServices.JMXService; + uses org.graalvm.compiler.serviceprovider.JMXService; exports jdk.internal.vm.compiler.collections to jdk.internal.vm.compiler.management; exports org.graalvm.compiler.api.directives to jdk.aot; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Address.java Fri Aug 17 13:20:53 2018 -0700 @@ -80,7 +80,6 @@ * address = base + imm9. base is updated to base + imm9 */ IMMEDIATE_PRE_INDEXED, - AddressingMode, } private final Register base; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64.test/src/org/graalvm/compiler/asm/amd64/test/BitOpsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64.test/src/org/graalvm/compiler/asm/amd64/test/BitOpsTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64.test/src/org/graalvm/compiler/asm/amd64/test/BitOpsTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,16 +25,23 @@ package org.graalvm.compiler.asm.amd64.test; +import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.LZCNT; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.TZCNT; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; -import static jdk.vm.ci.code.ValueUtil.asRegister; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; import static org.junit.Assume.assumeTrue; import java.lang.reflect.Field; import java.util.EnumSet; +import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler; +import org.graalvm.compiler.asm.test.AssemblerTest; +import org.graalvm.compiler.code.CompilationResult; +import org.junit.Before; +import org.junit.Test; + import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.code.CallingConvention; @@ -43,14 +50,6 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.JavaKind; -import org.junit.Before; -import org.junit.Test; - -import org.graalvm.compiler.asm.amd64.AMD64Address; -import org.graalvm.compiler.asm.amd64.AMD64Assembler; -import org.graalvm.compiler.asm.test.AssemblerTest; -import org.graalvm.compiler.code.CompilationResult; - public class BitOpsTest extends AssemblerTest { private static boolean lzcntSupported; private static boolean tzcntSupported; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,8 @@ package org.graalvm.compiler.asm.amd64; import static jdk.vm.ci.amd64.AMD64.CPU; +import static jdk.vm.ci.amd64.AMD64.MASK; import static jdk.vm.ci.amd64.AMD64.XMM; -import static jdk.vm.ci.amd64.AMD64.r12; -import static jdk.vm.ci.amd64.AMD64.r13; -import static jdk.vm.ci.amd64.AMD64.rbp; -import static jdk.vm.ci.amd64.AMD64.rip; -import static jdk.vm.ci.amd64.AMD64.rsp; import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop; @@ -45,23 +41,39 @@ import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.INC; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.NEG; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.NOT; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.BYTE; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PS; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.BYTE; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L128; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F38; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F3A; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_66; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F2; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F3; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W1; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.WIG; import static org.graalvm.compiler.core.common.NumUtil.isByte; import static org.graalvm.compiler.core.common.NumUtil.isInt; import static org.graalvm.compiler.core.common.NumUtil.isShiftCount; import static org.graalvm.compiler.core.common.NumUtil.isUByte; -import org.graalvm.compiler.asm.Assembler; +import java.util.EnumSet; + import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; +import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; import org.graalvm.compiler.core.common.NumUtil; +import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.debug.GraalError; import jdk.vm.ci.amd64.AMD64; @@ -70,14 +82,18 @@ import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register.RegisterCategory; import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.meta.PlatformKind; /** * This class implements an assembler that can encode most X86 instructions. */ -public class AMD64Assembler extends Assembler { - - private static final int MinEncodingNeedsRex = 8; +public class AMD64Assembler extends AMD64BaseAssembler { + + /** + * Constructs an assembler for the AMD64 architecture. + */ + public AMD64Assembler(TargetDescription target) { + super(target); + } /** * The x86 condition codes used for conditional jumps/moves. @@ -169,214 +185,6 @@ } /** - * Constants for X86 prefix bytes. - */ - private static class Prefix { - private static final int REX = 0x40; - private static final int REXB = 0x41; - private static final int REXX = 0x42; - private static final int REXXB = 0x43; - private static final int REXR = 0x44; - private static final int REXRB = 0x45; - private static final int REXRX = 0x46; - private static final int REXRXB = 0x47; - private static final int REXW = 0x48; - private static final int REXWB = 0x49; - private static final int REXWX = 0x4A; - private static final int REXWXB = 0x4B; - private static final int REXWR = 0x4C; - private static final int REXWRB = 0x4D; - private static final int REXWRX = 0x4E; - private static final int REXWRXB = 0x4F; - private static final int VEX_3BYTES = 0xC4; - private static final int VEX_2BYTES = 0xC5; - } - - private static class VexPrefix { - private static final int VEX_R = 0x80; - private static final int VEX_W = 0x80; - } - - private static class VexSimdPrefix { - private static final int VEX_SIMD_NONE = 0x0; - private static final int VEX_SIMD_66 = 0x1; - private static final int VEX_SIMD_F3 = 0x2; - private static final int VEX_SIMD_F2 = 0x3; - } - - private static class VexOpcode { - private static final int VEX_OPCODE_NONE = 0x0; - private static final int VEX_OPCODE_0F = 0x1; - private static final int VEX_OPCODE_0F_38 = 0x2; - private static final int VEX_OPCODE_0F_3A = 0x3; - } - - public static class AvxVectorLen { - public static final int AVX_128bit = 0x0; - public static final int AVX_256bit = 0x1; - public static final int AVX_512bit = 0x2; - public static final int AVX_NoVec = 0x4; - } - - public static class EvexTupleType { - public static final int EVEX_FV = 0; - public static final int EVEX_HV = 4; - public static final int EVEX_FVM = 6; - public static final int EVEX_T1S = 7; - public static final int EVEX_T1F = 11; - public static final int EVEX_T2 = 13; - public static final int EVEX_T4 = 15; - public static final int EVEX_T8 = 17; - public static final int EVEX_HVM = 18; - public static final int EVEX_QVM = 19; - public static final int EVEX_OVM = 20; - public static final int EVEX_M128 = 21; - public static final int EVEX_DUP = 22; - public static final int EVEX_ETUP = 23; - } - - public static class EvexInputSizeInBits { - public static final int EVEX_8bit = 0; - public static final int EVEX_16bit = 1; - public static final int EVEX_32bit = 2; - public static final int EVEX_64bit = 3; - public static final int EVEX_NObit = 4; - } - - private AMD64InstructionAttr curAttributes; - - AMD64InstructionAttr getCurAttributes() { - return curAttributes; - } - - void setCurAttributes(AMD64InstructionAttr attributes) { - curAttributes = attributes; - } - - /** - * The x86 operand sizes. - */ - public enum OperandSize { - BYTE(1, AMD64Kind.BYTE) { - @Override - protected void emitImmediate(AMD64Assembler asm, int imm) { - assert imm == (byte) imm; - asm.emitByte(imm); - } - - @Override - protected int immediateSize() { - return 1; - } - }, - - WORD(2, AMD64Kind.WORD, 0x66) { - @Override - protected void emitImmediate(AMD64Assembler asm, int imm) { - assert imm == (short) imm; - asm.emitShort(imm); - } - - @Override - protected int immediateSize() { - return 2; - } - }, - - DWORD(4, AMD64Kind.DWORD) { - @Override - protected void emitImmediate(AMD64Assembler asm, int imm) { - asm.emitInt(imm); - } - - @Override - protected int immediateSize() { - return 4; - } - }, - - QWORD(8, AMD64Kind.QWORD) { - @Override - protected void emitImmediate(AMD64Assembler asm, int imm) { - asm.emitInt(imm); - } - - @Override - protected int immediateSize() { - return 4; - } - }, - - SS(4, AMD64Kind.SINGLE, 0xF3, true), - - SD(8, AMD64Kind.DOUBLE, 0xF2, true), - - PS(16, AMD64Kind.V128_SINGLE, true), - - PD(16, AMD64Kind.V128_DOUBLE, 0x66, true); - - private final int sizePrefix; - private final int bytes; - private final boolean xmm; - private final AMD64Kind kind; - - OperandSize(int bytes, AMD64Kind kind) { - this(bytes, kind, 0); - } - - OperandSize(int bytes, AMD64Kind kind, int sizePrefix) { - this(bytes, kind, sizePrefix, false); - } - - OperandSize(int bytes, AMD64Kind kind, boolean xmm) { - this(bytes, kind, 0, xmm); - } - - OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) { - this.sizePrefix = sizePrefix; - this.bytes = bytes; - this.kind = kind; - this.xmm = xmm; - } - - public int getBytes() { - return bytes; - } - - public boolean isXmmType() { - return xmm; - } - - public AMD64Kind getKind() { - return kind; - } - - public static OperandSize get(PlatformKind kind) { - for (OperandSize operandSize : OperandSize.values()) { - if (operandSize.kind.equals(kind)) { - return operandSize; - } - } - throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString()); - } - - /** - * Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded - * as sign-extended 32-bit values. - * - * @param asm - * @param imm - */ - protected void emitImmediate(AMD64Assembler asm, int imm) { - throw new UnsupportedOperationException(); - } - - protected int immediateSize() { - throw new UnsupportedOperationException(); - } - } - - /** * Operand size and register type constraints. */ private enum OpAssertion { @@ -417,261 +225,18 @@ assert false : "invalid operand size " + size + " used in " + op; return false; } - } - - public abstract static class OperandDataAnnotation extends CodeAnnotation { - /** - * The position (bytes from the beginning of the method) of the operand. - */ - public final int operandPosition; - /** - * The size of the operand, in bytes. - */ - public final int operandSize; - /** - * The position (bytes from the beginning of the method) of the next instruction. On AMD64, - * RIP-relative operands are relative to this position. - */ - public final int nextInstructionPosition; - - OperandDataAnnotation(int instructionPosition, int operandPosition, int operandSize, int nextInstructionPosition) { - super(instructionPosition); - - this.operandPosition = operandPosition; - this.operandSize = operandSize; - this.nextInstructionPosition = nextInstructionPosition; - } - - @Override - public String toString() { - return getClass().getSimpleName() + " instruction [" + instructionPosition + ", " + nextInstructionPosition + "[ operand at " + operandPosition + " size " + operandSize; - } - } - - /** - * Annotation that stores additional information about the displacement of a - * {@link Assembler#getPlaceholder placeholder address} that needs patching. - */ - public static class AddressDisplacementAnnotation extends OperandDataAnnotation { - AddressDisplacementAnnotation(int instructionPosition, int operandPosition, int operndSize, int nextInstructionPosition) { - super(instructionPosition, operandPosition, operndSize, nextInstructionPosition); - } - } - - /** - * Annotation that stores additional information about the immediate operand, e.g., of a call - * instruction, that needs patching. - */ - public static class ImmediateOperandAnnotation extends OperandDataAnnotation { - ImmediateOperandAnnotation(int instructionPosition, int operandPosition, int operndSize, int nextInstructionPosition) { - super(instructionPosition, operandPosition, operndSize, nextInstructionPosition); - } - } - - /** - * Constructs an assembler for the AMD64 architecture. - */ - public AMD64Assembler(TargetDescription target) { - super(target); - } - - public boolean supports(CPUFeature feature) { - return ((AMD64) target.arch).getFeatures().contains(feature); - } - - private static int encode(Register r) { - assert r.encoding < 16 && r.encoding >= 0 : "encoding out of range: " + r.encoding; - return r.encoding & 0x7; - } - - /** - * Get RXB bits for register-register instruction. In that encoding, ModRM.rm contains a - * register index. The R bit extends the ModRM.reg field and the B bit extends the ModRM.rm - * field. The X bit must be 0. - */ - protected static int getRXB(Register reg, Register rm) { - int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; - rxb |= (rm == null ? 0 : rm.encoding & 0x08) >> 3; - return rxb; - } - - /** - * Get RXB bits for register-memory instruction. The R bit extends the ModRM.reg field. There - * are two cases for the memory operand:
- * ModRM.rm contains the base register: In that case, B extends the ModRM.rm field and X = 0. - *
- * There is an SIB byte: In that case, X extends SIB.index and B extends SIB.base. - */ - protected static int getRXB(Register reg, AMD64Address rm) { - int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; - if (!rm.getIndex().equals(Register.None)) { - rxb |= (rm.getIndex().encoding & 0x08) >> 2; - } - if (!rm.getBase().equals(Register.None)) { - rxb |= (rm.getBase().encoding & 0x08) >> 3; - } - return rxb; - } - - /** - * Emit the ModR/M byte for one register operand and an opcode extension in the R field. - *

- * Format: [ 11 reg r/m ] - */ - protected void emitModRM(int reg, Register rm) { - assert (reg & 0x07) == reg; - emitByte(0xC0 | (reg << 3) | (rm.encoding & 0x07)); - } - - /** - * Emit the ModR/M byte for two register operands. - *

- * Format: [ 11 reg r/m ] - */ - protected void emitModRM(Register reg, Register rm) { - emitModRM(reg.encoding & 0x07, rm); - } - - protected void emitOperandHelper(Register reg, AMD64Address addr, int additionalInstructionSize) { - assert !reg.equals(Register.None); - emitOperandHelper(encode(reg), addr, false, additionalInstructionSize); + } - /** - * Emits the ModR/M byte and optionally the SIB byte for one register and one memory operand. - * - * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte - */ - protected void emitOperandHelper(Register reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize) { - assert !reg.equals(Register.None); - emitOperandHelper(encode(reg), addr, force4Byte, additionalInstructionSize); - } - - protected void emitOperandHelper(int reg, AMD64Address addr, int additionalInstructionSize) { - emitOperandHelper(reg, addr, false, additionalInstructionSize); - } - - /** - * Emits the ModR/M byte and optionally the SIB byte for one memory operand and an opcode - * extension in the R field. - * - * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte - * @param additionalInstructionSize the number of bytes that will be emitted after the operand, - * so that the start position of the next instruction can be computed even though - * this instruction has not been completely emitted yet. - */ - protected void emitOperandHelper(int reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize) { - assert (reg & 0x07) == reg; - int regenc = reg << 3; - - Register base = addr.getBase(); - Register index = addr.getIndex(); - - AMD64Address.Scale scale = addr.getScale(); - int disp = addr.getDisplacement(); - - if (base.equals(AMD64.rip)) { // also matches addresses returned by getPlaceholder() - // [00 000 101] disp32 - assert index.equals(Register.None) : "cannot use RIP relative addressing with index register"; - emitByte(0x05 | regenc); - if (codePatchingAnnotationConsumer != null && addr.instructionStartPosition >= 0) { - codePatchingAnnotationConsumer.accept(new AddressDisplacementAnnotation(addr.instructionStartPosition, position(), 4, position() + 4 + additionalInstructionSize)); - } - emitInt(disp); - } else if (base.isValid()) { - int baseenc = base.isValid() ? encode(base) : 0; - if (index.isValid()) { - int indexenc = encode(index) << 3; - // [base + indexscale + disp] - if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { - // [base + indexscale] - // [00 reg 100][ss index base] - assert !index.equals(rsp) : "illegal addressing mode"; - emitByte(0x04 | regenc); - emitByte(scale.log2 << 6 | indexenc | baseenc); - } else if (isByte(disp) && !force4Byte) { - // [base + indexscale + imm8] - // [01 reg 100][ss index base] imm8 - assert !index.equals(rsp) : "illegal addressing mode"; - emitByte(0x44 | regenc); - emitByte(scale.log2 << 6 | indexenc | baseenc); - emitByte(disp & 0xFF); - } else { - // [base + indexscale + disp32] - // [10 reg 100][ss index base] disp32 - assert !index.equals(rsp) : "illegal addressing mode"; - emitByte(0x84 | regenc); - emitByte(scale.log2 << 6 | indexenc | baseenc); - emitInt(disp); - } - } else if (base.equals(rsp) || base.equals(r12)) { - // [rsp + disp] - if (disp == 0) { - // [rsp] - // [00 reg 100][00 100 100] - emitByte(0x04 | regenc); - emitByte(0x24); - } else if (isByte(disp) && !force4Byte) { - // [rsp + imm8] - // [01 reg 100][00 100 100] disp8 - emitByte(0x44 | regenc); - emitByte(0x24); - emitByte(disp & 0xFF); - } else { - // [rsp + imm32] - // [10 reg 100][00 100 100] disp32 - emitByte(0x84 | regenc); - emitByte(0x24); - emitInt(disp); - } - } else { - // [base + disp] - assert !base.equals(rsp) && !base.equals(r12) : "illegal addressing mode"; - if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { - // [base] - // [00 reg base] - emitByte(0x00 | regenc | baseenc); - } else if (isByte(disp) && !force4Byte) { - // [base + disp8] - // [01 reg base] disp8 - emitByte(0x40 | regenc | baseenc); - emitByte(disp & 0xFF); - } else { - // [base + disp32] - // [10 reg base] disp32 - emitByte(0x80 | regenc | baseenc); - emitInt(disp); - } - } - } else { - if (index.isValid()) { - int indexenc = encode(index) << 3; - // [indexscale + disp] - // [00 reg 100][ss index 101] disp32 - assert !index.equals(rsp) : "illegal addressing mode"; - emitByte(0x04 | regenc); - emitByte(scale.log2 << 6 | indexenc | 0x05); - emitInt(disp); - } else { - // [disp] ABSOLUTE - // [00 reg 100][00 100 101] disp32 - emitByte(0x04 | regenc); - emitByte(0x25); - emitInt(disp); - } - } - setCurAttributes(null); - } + protected static final int P_0F = 0x0F; + protected static final int P_0F38 = 0x380F; + protected static final int P_0F3A = 0x3A0F; /** * Base class for AMD64 opcodes. */ public static class AMD64Op { - protected static final int P_0F = 0x0F; - protected static final int P_0F38 = 0x380F; - protected static final int P_0F3A = 0x3A0F; - private final String opcode; protected final int prefix1; @@ -705,8 +270,8 @@ if (prefix1 != 0) { asm.emitByte(prefix1); } - if (size.sizePrefix != 0) { - asm.emitByte(size.sizePrefix); + if (size.getSizePrefix() != 0) { + asm.emitByte(size.getSizePrefix()); } int rexPrefix = 0x40 | rxb; if (size == QWORD) { @@ -729,6 +294,32 @@ return true; } + public OperandSize[] getAllowedSizes() { + return assertion.allowedSizes; + } + + protected final boolean isSSEInstruction() { + if (feature == null) { + return false; + } + switch (feature) { + case SSE: + case SSE2: + case SSE3: + case SSSE3: + case SSE4A: + case SSE4_1: + case SSE4_2: + return true; + default: + return false; + } + } + + public final OpAssertion getAssertion() { + return assertion; + } + @Override public String toString() { return opcode; @@ -743,7 +334,11 @@ private final boolean immIsByte; protected AMD64ImmOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion) { - super(opcode, 0, prefix, op, assertion, null); + this(opcode, immIsByte, prefix, op, assertion, null); + } + + protected AMD64ImmOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion, CPUFeature feature) { + super(opcode, 0, prefix, op, assertion, feature); this.immIsByte = immIsByte; } @@ -760,7 +355,7 @@ if (immIsByte) { return 1; } else { - return size.bytes; + return size.getBytes(); } } } @@ -782,22 +377,6 @@ } /** - * Opcode with operand order of either RM or MR for 3 address forms. - */ - public abstract static class AMD64RRROp extends AMD64Op { - - protected AMD64RRROp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) { - super(opcode, prefix1, prefix2, op, assertion, feature); - } - - protected AMD64RRROp(String opcode, int prefix1, int prefix2, int op, boolean dstIsByte, boolean srcIsByte, OpAssertion assertion, CPUFeature feature) { - super(opcode, prefix1, prefix2, op, dstIsByte, srcIsByte, assertion, feature); - } - - public abstract void emit(AMD64Assembler asm, OperandSize size, Register dst, Register nds, Register src); - } - - /** * Opcode with operand order of RM. */ public static class AMD64RMOp extends AMD64RROp { @@ -805,9 +384,12 @@ public static final AMD64RMOp IMUL = new AMD64RMOp("IMUL", P_0F, 0xAF, OpAssertion.ByteOrLargerAssertion); public static final AMD64RMOp BSF = new AMD64RMOp("BSF", P_0F, 0xBC); public static final AMD64RMOp BSR = new AMD64RMOp("BSR", P_0F, 0xBD); - public static final AMD64RMOp POPCNT = new AMD64RMOp("POPCNT", 0xF3, P_0F, 0xB8, CPUFeature.POPCNT); - public static final AMD64RMOp TZCNT = new AMD64RMOp("TZCNT", 0xF3, P_0F, 0xBC, CPUFeature.BMI1); - public static final AMD64RMOp LZCNT = new AMD64RMOp("LZCNT", 0xF3, P_0F, 0xBD, CPUFeature.LZCNT); + // POPCNT, TZCNT, and LZCNT support word operation. However, the legacy size prefix should + // be emitted before the mandatory prefix 0xF3. Since we are not emitting bit count for + // 16-bit operands, here we simply use DwordOrLargerAssertion. + public static final AMD64RMOp POPCNT = new AMD64RMOp("POPCNT", 0xF3, P_0F, 0xB8, OpAssertion.DwordOrLargerAssertion, CPUFeature.POPCNT); + public static final AMD64RMOp TZCNT = new AMD64RMOp("TZCNT", 0xF3, P_0F, 0xBC, OpAssertion.DwordOrLargerAssertion, CPUFeature.BMI1); + public static final AMD64RMOp LZCNT = new AMD64RMOp("LZCNT", 0xF3, P_0F, 0xBD, OpAssertion.DwordOrLargerAssertion, CPUFeature.LZCNT); public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB", P_0F, 0xB6, false, true, OpAssertion.WordOrLargerAssertion); public static final AMD64RMOp MOVZX = new AMD64RMOp("MOVZX", P_0F, 0xB7, OpAssertion.DwordOrLargerAssertion); public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB", P_0F, 0xBE, false, true, OpAssertion.WordOrLargerAssertion); @@ -863,80 +445,35 @@ @Override public final void emit(AMD64Assembler asm, OperandSize size, Register dst, Register src) { assert verify(asm, size, dst, src); - boolean isSimd = false; - boolean noNds = false; - - switch (op) { - case 0x2A: - case 0x2C: - case 0x2E: - case 0x5A: - case 0x6E: - isSimd = true; - noNds = true; - break; - case 0x10: - case 0x51: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - isSimd = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; + if (isSSEInstruction()) { + Register nds = Register.None; + switch (op) { + case 0x10: + case 0x51: + if ((size == SS) || (size == SD)) { + nds = dst; + } break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; + case 0x2A: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + nds = dst; break; default: - opc = VexOpcode.VEX_OPCODE_NONE; - isSimd = false; break; } - } - - if (isSimd) { - int pre; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - int encode; - if (noNds) { - encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes); - } else { - encode = asm.simdPrefixAndEncode(dst, dst, src, pre, opc, attributes); - } + asm.simdPrefix(dst, nds, src, size, prefix1, prefix2, size == QWORD); asm.emitByte(op); - asm.emitByte(0xC0 | encode); + asm.emitModRM(dst, src); } else { emitOpcode(asm, size, getRXB(dst, src), dst.encoding, src.encoding); asm.emitModRM(dst, src); @@ -945,75 +482,32 @@ public final void emit(AMD64Assembler asm, OperandSize size, Register dst, AMD64Address src) { assert verify(asm, size, dst, null); - boolean isSimd = false; - boolean noNds = false; - - switch (op) { - case 0x10: - case 0x2A: - case 0x2C: - case 0x2E: - case 0x6E: - isSimd = true; - noNds = true; - break; - case 0x51: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - isSimd = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; + if (isSSEInstruction()) { + Register nds = Register.None; + switch (op) { + case 0x51: + if ((size == SS) || (size == SD)) { + nds = dst; + } break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; + case 0x2A: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + nds = dst; break; default: - isSimd = false; break; } - } - - if (isSimd) { - int pre; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - if (noNds) { - asm.simdPrefix(dst, Register.None, src, pre, opc, attributes); - } else { - asm.simdPrefix(dst, dst, src, pre, opc, attributes); - } + asm.simdPrefix(dst, nds, src, size, prefix1, prefix2, size == QWORD); asm.emitByte(op); asm.emitOperandHelper(dst, src, 0); } else { @@ -1024,123 +518,6 @@ } /** - * Opcode with operand order of RM. - */ - public static class AMD64RRMOp extends AMD64RRROp { - protected AMD64RRMOp(String opcode, int op) { - this(opcode, 0, op); - } - - protected AMD64RRMOp(String opcode, int op, OpAssertion assertion) { - this(opcode, 0, op, assertion); - } - - protected AMD64RRMOp(String opcode, int prefix, int op) { - this(opcode, 0, prefix, op, null); - } - - protected AMD64RRMOp(String opcode, int prefix, int op, OpAssertion assertion) { - this(opcode, 0, prefix, op, assertion, null); - } - - protected AMD64RRMOp(String opcode, int prefix, int op, OpAssertion assertion, CPUFeature feature) { - this(opcode, 0, prefix, op, assertion, feature); - } - - protected AMD64RRMOp(String opcode, int prefix, int op, boolean dstIsByte, boolean srcIsByte, OpAssertion assertion) { - super(opcode, 0, prefix, op, dstIsByte, srcIsByte, assertion, null); - } - - protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) { - this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature); - } - - protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) { - super(opcode, prefix1, prefix2, op, assertion, feature); - } - - @Override - public final void emit(AMD64Assembler asm, OperandSize size, Register dst, Register nds, Register src) { - assert verify(asm, size, dst, src); - int pre; - int opc; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; - break; - default: - throw GraalError.shouldNotReachHere("invalid VEX instruction prefix"); - } - int encode; - encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes); - asm.emitByte(op); - asm.emitByte(0xC0 | encode); - } - - public final void emit(AMD64Assembler asm, OperandSize size, Register dst, Register nds, AMD64Address src) { - assert verify(asm, size, dst, null); - int pre; - int opc; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; - break; - default: - throw GraalError.shouldNotReachHere("invalid VEX instruction prefix"); - } - asm.simdPrefix(dst, nds, src, pre, opc, attributes); - asm.emitByte(op); - asm.emitOperandHelper(dst, src, 0); - } - } - - /** * Opcode with operand order of MR. */ public static class AMD64MROp extends AMD64RROp { @@ -1185,64 +562,20 @@ @Override public final void emit(AMD64Assembler asm, OperandSize size, Register dst, Register src) { assert verify(asm, size, src, dst); - boolean isSimd = false; - boolean noNds = false; - - switch (op) { - case 0x7E: - isSimd = true; - noNds = true; - break; - case 0x11: - isSimd = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; + if (isSSEInstruction()) { + Register nds = Register.None; + switch (op) { + case 0x11: + if ((size == SS) || (size == SD)) { + nds = src; + } break; default: - isSimd = false; break; } - } - - if (isSimd) { - int pre; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - int encode; - if (noNds) { - encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes); - } else { - encode = asm.simdPrefixAndEncode(src, src, dst, pre, opc, attributes); - } + asm.simdPrefix(src, nds, dst, size, prefix1, prefix2, size == QWORD); asm.emitByte(op); - asm.emitByte(0xC0 | encode); + asm.emitModRM(src, dst); } else { emitOpcode(asm, size, getRXB(src, dst), src.encoding, dst.encoding); asm.emitModRM(src, dst); @@ -1250,60 +583,14 @@ } public final void emit(AMD64Assembler asm, OperandSize size, AMD64Address dst, Register src) { - assert verify(asm, size, null, src); - boolean isSimd = false; - - switch (op) { - case 0x7E: - case 0x11: - isSimd = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; - break; - default: - isSimd = false; - break; - } - } - - if (isSimd) { - int pre; - boolean rexVexW = (size == QWORD) ? true : false; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - asm.simdPrefix(src, Register.None, dst, pre, opc, attributes); + assert verify(asm, size, src, null); + if (isSSEInstruction()) { + asm.simdPrefix(src, Register.None, dst, size, prefix1, prefix2, size == QWORD); asm.emitByte(op); - asm.emitOperandHelper(src, dst, 0); } else { emitOpcode(asm, size, getRXB(src, dst), src.encoding, 0); - asm.emitOperandHelper(src, dst, 0); } + asm.emitOperandHelper(src, dst, 0); } } @@ -1382,17 +669,37 @@ } public final void emit(AMD64Assembler asm, OperandSize size, Register dst, int imm) { + emit(asm, size, dst, imm, false); + } + + public final void emit(AMD64Assembler asm, OperandSize size, Register dst, int imm, boolean annotateImm) { assert verify(asm, size, dst, null); + int insnPos = asm.position(); emitOpcode(asm, size, getRXB(null, dst), 0, dst.encoding); asm.emitModRM(ext, dst); + int immPos = asm.position(); emitImmediate(asm, size, imm); + int nextInsnPos = asm.position(); + if (annotateImm && asm.codePatchingAnnotationConsumer != null) { + asm.codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(insnPos, immPos, nextInsnPos - immPos, nextInsnPos)); + } } public final void emit(AMD64Assembler asm, OperandSize size, AMD64Address dst, int imm) { + emit(asm, size, dst, imm, false); + } + + public final void emit(AMD64Assembler asm, OperandSize size, AMD64Address dst, int imm, boolean annotateImm) { assert verify(asm, size, null, null); + int insnPos = asm.position(); emitOpcode(asm, size, getRXB(null, dst), 0, 0); asm.emitOperandHelper(ext, dst, immediateSize(size)); + int immPos = asm.position(); emitImmediate(asm, size, imm); + int nextInsnPos = asm.position(); + if (annotateImm && asm.codePatchingAnnotationConsumer != null) { + asm.codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(insnPos, immPos, nextInsnPos - immPos, nextInsnPos)); + } } } @@ -1406,153 +713,66 @@ // @formatter:off public static final AMD64RMIOp IMUL = new AMD64RMIOp("IMUL", false, 0x69); public static final AMD64RMIOp IMUL_SX = new AMD64RMIOp("IMUL", true, 0x6B); - public static final AMD64RMIOp ROUNDSS = new AMD64RMIOp("ROUNDSS", true, P_0F3A, 0x0A, OpAssertion.PackedDoubleAssertion); - public static final AMD64RMIOp ROUNDSD = new AMD64RMIOp("ROUNDSD", true, P_0F3A, 0x0B, OpAssertion.PackedDoubleAssertion); + public static final AMD64RMIOp ROUNDSS = new AMD64RMIOp("ROUNDSS", true, P_0F3A, 0x0A, OpAssertion.PackedDoubleAssertion, CPUFeature.SSE4_1); + public static final AMD64RMIOp ROUNDSD = new AMD64RMIOp("ROUNDSD", true, P_0F3A, 0x0B, OpAssertion.PackedDoubleAssertion, CPUFeature.SSE4_1); // @formatter:on protected AMD64RMIOp(String opcode, boolean immIsByte, int op) { - this(opcode, immIsByte, 0, op, OpAssertion.WordOrLargerAssertion); + this(opcode, immIsByte, 0, op, OpAssertion.WordOrLargerAssertion, null); } - protected AMD64RMIOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion) { - super(opcode, immIsByte, prefix, op, assertion); + protected AMD64RMIOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion, CPUFeature feature) { + super(opcode, immIsByte, prefix, op, assertion, feature); } public final void emit(AMD64Assembler asm, OperandSize size, Register dst, Register src, int imm) { assert verify(asm, size, dst, src); - boolean isSimd = false; - boolean noNds = false; - - switch (op) { - case 0x0A: - case 0x0B: - isSimd = true; - noNds = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; + if (isSSEInstruction()) { + Register nds = Register.None; + switch (op) { + case 0x0A: + case 0x0B: + nds = dst; break; default: - isSimd = false; break; } - } - - if (isSimd) { - int pre; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - int encode; - if (noNds) { - encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes); - } else { - encode = asm.simdPrefixAndEncode(dst, dst, src, pre, opc, attributes); - } + asm.simdPrefix(dst, nds, src, size, prefix1, prefix2, false); asm.emitByte(op); - asm.emitByte(0xC0 | encode); - emitImmediate(asm, size, imm); + asm.emitModRM(dst, src); } else { emitOpcode(asm, size, getRXB(dst, src), dst.encoding, src.encoding); asm.emitModRM(dst, src); - emitImmediate(asm, size, imm); } + emitImmediate(asm, size, imm); } public final void emit(AMD64Assembler asm, OperandSize size, Register dst, AMD64Address src, int imm) { assert verify(asm, size, dst, null); - - boolean isSimd = false; - boolean noNds = false; - - switch (op) { - case 0x0A: - case 0x0B: - isSimd = true; - noNds = true; - break; - } - - int opc = 0; - if (isSimd) { - switch (prefix2) { - case P_0F: - opc = VexOpcode.VEX_OPCODE_0F; - break; - case P_0F38: - opc = VexOpcode.VEX_OPCODE_0F_38; - break; - case P_0F3A: - opc = VexOpcode.VEX_OPCODE_0F_3A; + if (isSSEInstruction()) { + Register nds = Register.None; + switch (op) { + case 0x0A: + case 0x0B: + nds = dst; break; default: - isSimd = false; break; } - } - - if (isSimd) { - int pre; - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); - int curPrefix = size.sizePrefix | prefix1; - switch (curPrefix) { - case 0x66: - pre = VexSimdPrefix.VEX_SIMD_66; - break; - case 0xF2: - pre = VexSimdPrefix.VEX_SIMD_F2; - break; - case 0xF3: - pre = VexSimdPrefix.VEX_SIMD_F3; - break; - default: - pre = VexSimdPrefix.VEX_SIMD_NONE; - break; - } - if (noNds) { - asm.simdPrefix(dst, Register.None, src, pre, opc, attributes); - } else { - asm.simdPrefix(dst, dst, src, pre, opc, attributes); - } + asm.simdPrefix(dst, nds, src, size, prefix1, prefix2, false); asm.emitByte(op); - asm.emitOperandHelper(dst, src, immediateSize(size)); - emitImmediate(asm, size, imm); } else { emitOpcode(asm, size, getRXB(dst, src), dst.encoding, 0); - asm.emitOperandHelper(dst, src, immediateSize(size)); - emitImmediate(asm, size, imm); } + asm.emitOperandHelper(dst, src, immediateSize(size)); + emitImmediate(asm, size, imm); } } public static class SSEOp extends AMD64RMOp { // @formatter:off public static final SSEOp CVTSI2SS = new SSEOp("CVTSI2SS", 0xF3, P_0F, 0x2A, OpAssertion.IntToFloatAssertion); - public static final SSEOp CVTSI2SD = new SSEOp("CVTSI2SS", 0xF2, P_0F, 0x2A, OpAssertion.IntToFloatAssertion); + public static final SSEOp CVTSI2SD = new SSEOp("CVTSI2SD", 0xF2, P_0F, 0x2A, OpAssertion.IntToFloatAssertion); public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatToIntAssertion); public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatToIntAssertion); public static final SSEOp UCOMIS = new SSEOp("UCOMIS", P_0F, 0x2E, OpAssertion.PackedFloatAssertion); @@ -1584,33 +804,6 @@ } } - public static class AVXOp extends AMD64RRMOp { - // @formatter:off - public static final AVXOp AND = new AVXOp("AND", P_0F, 0x54, OpAssertion.PackedFloatAssertion); - public static final AVXOp ANDN = new AVXOp("ANDN", P_0F, 0x55, OpAssertion.PackedFloatAssertion); - public static final AVXOp OR = new AVXOp("OR", P_0F, 0x56, OpAssertion.PackedFloatAssertion); - public static final AVXOp XOR = new AVXOp("XOR", P_0F, 0x57, OpAssertion.PackedFloatAssertion); - public static final AVXOp ADD = new AVXOp("ADD", P_0F, 0x58); - public static final AVXOp MUL = new AVXOp("MUL", P_0F, 0x59); - public static final AVXOp SUB = new AVXOp("SUB", P_0F, 0x5C); - public static final AVXOp MIN = new AVXOp("MIN", P_0F, 0x5D); - public static final AVXOp DIV = new AVXOp("DIV", P_0F, 0x5E); - public static final AVXOp MAX = new AVXOp("MAX", P_0F, 0x5F); - // @formatter:on - - protected AVXOp(String opcode, int prefix, int op) { - this(opcode, prefix, op, OpAssertion.FloatAssertion); - } - - protected AVXOp(String opcode, int prefix, int op, OpAssertion assertion) { - this(opcode, 0, prefix, op, assertion); - } - - protected AVXOp(String opcode, int mandatoryPrefix, int prefix, int op, OpAssertion assertion) { - super(opcode, mandatoryPrefix, prefix, op, assertion, CPUFeature.AVX); - } - } - /** * Arithmetic operation with operand order of RM, MR or MI. */ @@ -1700,6 +893,661 @@ } } + private enum AVXOpAssertion { + AVX1(CPUFeature.AVX, CPUFeature.AVX), + AVX1_2(CPUFeature.AVX, CPUFeature.AVX2), + AVX2(CPUFeature.AVX2, CPUFeature.AVX2), + AVX1_128ONLY(CPUFeature.AVX, null), + AVX1_256ONLY(null, CPUFeature.AVX), + AVX2_256ONLY(null, CPUFeature.AVX2), + XMM_CPU(CPUFeature.AVX, null, XMM, null, CPU, null), + XMM_XMM_CPU(CPUFeature.AVX, null, XMM, XMM, CPU, null), + CPU_XMM(CPUFeature.AVX, null, CPU, null, XMM, null), + AVX1_2_CPU_XMM(CPUFeature.AVX, CPUFeature.AVX2, CPU, null, XMM, null); + + private final CPUFeature avx128feature; + private final CPUFeature avx256feature; + + private final RegisterCategory rCategory; + private final RegisterCategory vCategory; + private final RegisterCategory mCategory; + private final RegisterCategory imm8Category; + + AVXOpAssertion(CPUFeature avx128feature, CPUFeature avx256feature) { + this(avx128feature, avx256feature, XMM, XMM, XMM, XMM); + } + + AVXOpAssertion(CPUFeature avx128feature, CPUFeature avx256feature, RegisterCategory rCategory, RegisterCategory vCategory, RegisterCategory mCategory, RegisterCategory imm8Category) { + this.avx128feature = avx128feature; + this.avx256feature = avx256feature; + this.rCategory = rCategory; + this.vCategory = vCategory; + this.mCategory = mCategory; + this.imm8Category = imm8Category; + } + + public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m) { + return check(arch, size, r, v, m, null); + } + + public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m, Register imm8) { + switch (size) { + case XMM: + assert avx128feature != null && arch.getFeatures().contains(avx128feature) : "emitting illegal 128 bit instruction"; + break; + case YMM: + assert avx256feature != null && arch.getFeatures().contains(avx256feature) : "emitting illegal 256 bit instruction"; + break; + } + if (r != null) { + assert r.getRegisterCategory().equals(rCategory); + } + if (v != null) { + assert v.getRegisterCategory().equals(vCategory); + } + if (m != null) { + assert m.getRegisterCategory().equals(mCategory); + } + if (imm8 != null) { + assert imm8.getRegisterCategory().equals(imm8Category); + } + return true; + } + + public boolean supports(EnumSet features, AVXSize avxSize) { + switch (avxSize) { + case XMM: + return avx128feature != null && features.contains(avx128feature); + case YMM: + return avx256feature != null && features.contains(avx256feature); + default: + throw GraalError.shouldNotReachHere(); + } + } + } + + /** + * Base class for VEX-encoded instructions. + */ + public static class VexOp { + protected final int pp; + protected final int mmmmm; + protected final int w; + protected final int op; + + private final String opcode; + protected final AVXOpAssertion assertion; + + protected VexOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + this.pp = pp; + this.mmmmm = mmmmm; + this.w = w; + this.op = op; + this.opcode = opcode; + this.assertion = assertion; + } + + public boolean isSupported(AMD64Assembler vasm, AMD64Kind kind) { + return assertion.supports(((AMD64) vasm.target.arch).getFeatures(), AVXKind.getRegisterSize(kind)); + } + + public final boolean isSupported(AMD64Assembler vasm, AVXSize size) { + return assertion.supports(((AMD64) vasm.target.arch).getFeatures(), size); + } + + @Override + public String toString() { + return opcode; + } + } + + /** + * VEX-encoded instructions with an operand order of RM, but the M operand must be a register. + */ + public static class VexRROp extends VexOp { + // @formatter:off + public static final VexRROp VMASKMOVDQU = new VexRROp("VMASKMOVDQU", P_66, M_0F, WIG, 0xF7, AVXOpAssertion.AVX1_128ONLY); + // @formatter:on + + protected VexRROp(String opcode, int pp, int mmmmm, int w, int op) { + this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1); + } + + protected VexRROp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); + assert op != 0x1A || op != 0x5A; + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src); + } + } + + /** + * VEX-encoded instructions with an operand order of RM. + */ + public static class VexRMOp extends VexRROp { + // @formatter:off + public static final VexRMOp VCVTTSS2SI = new VexRMOp("VCVTTSS2SI", P_F3, M_0F, W0, 0x2C, AVXOpAssertion.CPU_XMM); + public static final VexRMOp VCVTTSS2SQ = new VexRMOp("VCVTTSS2SQ", P_F3, M_0F, W1, 0x2C, AVXOpAssertion.CPU_XMM); + public static final VexRMOp VCVTTSD2SI = new VexRMOp("VCVTTSD2SI", P_F2, M_0F, W0, 0x2C, AVXOpAssertion.CPU_XMM); + public static final VexRMOp VCVTTSD2SQ = new VexRMOp("VCVTTSD2SQ", P_F2, M_0F, W1, 0x2C, AVXOpAssertion.CPU_XMM); + public static final VexRMOp VCVTPS2PD = new VexRMOp("VCVTPS2PD", P_, M_0F, WIG, 0x5A); + public static final VexRMOp VCVTPD2PS = new VexRMOp("VCVTPD2PS", P_66, M_0F, WIG, 0x5A); + public static final VexRMOp VCVTDQ2PS = new VexRMOp("VCVTDQ2PS", P_, M_0F, WIG, 0x5B); + public static final VexRMOp VCVTTPS2DQ = new VexRMOp("VCVTTPS2DQ", P_F3, M_0F, WIG, 0x5B); + public static final VexRMOp VCVTTPD2DQ = new VexRMOp("VCVTTPD2DQ", P_66, M_0F, WIG, 0xE6); + public static final VexRMOp VCVTDQ2PD = new VexRMOp("VCVTDQ2PD", P_F3, M_0F, WIG, 0xE6); + public static final VexRMOp VBROADCASTSS = new VexRMOp("VBROADCASTSS", P_66, M_0F38, W0, 0x18); + public static final VexRMOp VBROADCASTSD = new VexRMOp("VBROADCASTSD", P_66, M_0F38, W0, 0x19, AVXOpAssertion.AVX1_256ONLY); + public static final VexRMOp VBROADCASTF128 = new VexRMOp("VBROADCASTF128", P_66, M_0F38, W0, 0x1A, AVXOpAssertion.AVX1_256ONLY); + public static final VexRMOp VPBROADCASTI128 = new VexRMOp("VPBROADCASTI128", P_66, M_0F38, W0, 0x5A, AVXOpAssertion.AVX2_256ONLY); + public static final VexRMOp VPBROADCASTB = new VexRMOp("VPBROADCASTB", P_66, M_0F38, W0, 0x78, AVXOpAssertion.AVX2); + public static final VexRMOp VPBROADCASTW = new VexRMOp("VPBROADCASTW", P_66, M_0F38, W0, 0x79, AVXOpAssertion.AVX2); + public static final VexRMOp VPBROADCASTD = new VexRMOp("VPBROADCASTD", P_66, M_0F38, W0, 0x58, AVXOpAssertion.AVX2); + public static final VexRMOp VPBROADCASTQ = new VexRMOp("VPBROADCASTQ", P_66, M_0F38, W0, 0x59, AVXOpAssertion.AVX2); + public static final VexRMOp VPMOVMSKB = new VexRMOp("VPMOVMSKB", P_66, M_0F, WIG, 0xD7, AVXOpAssertion.AVX1_2_CPU_XMM); + public static final VexRMOp VPMOVSXBW = new VexRMOp("VPMOVSXBW", P_66, M_0F38, WIG, 0x20); + public static final VexRMOp VPMOVSXBD = new VexRMOp("VPMOVSXBD", P_66, M_0F38, WIG, 0x21); + public static final VexRMOp VPMOVSXBQ = new VexRMOp("VPMOVSXBQ", P_66, M_0F38, WIG, 0x22); + public static final VexRMOp VPMOVSXWD = new VexRMOp("VPMOVSXWD", P_66, M_0F38, WIG, 0x23); + public static final VexRMOp VPMOVSXWQ = new VexRMOp("VPMOVSXWQ", P_66, M_0F38, WIG, 0x24); + public static final VexRMOp VPMOVSXDQ = new VexRMOp("VPMOVSXDQ", P_66, M_0F38, WIG, 0x25); + public static final VexRMOp VPMOVZXBW = new VexRMOp("VPMOVZXBW", P_66, M_0F38, WIG, 0x30); + public static final VexRMOp VPMOVZXBD = new VexRMOp("VPMOVZXBD", P_66, M_0F38, WIG, 0x31); + public static final VexRMOp VPMOVZXBQ = new VexRMOp("VPMOVZXBQ", P_66, M_0F38, WIG, 0x32); + public static final VexRMOp VPMOVZXWD = new VexRMOp("VPMOVZXWD", P_66, M_0F38, WIG, 0x33); + public static final VexRMOp VPMOVZXWQ = new VexRMOp("VPMOVZXWQ", P_66, M_0F38, WIG, 0x34); + public static final VexRMOp VPMOVZXDQ = new VexRMOp("VPMOVZXDQ", P_66, M_0F38, WIG, 0x35); + public static final VexRMOp VPTEST = new VexRMOp("VPTEST", P_66, M_0F38, WIG, 0x17); + public static final VexRMOp VSQRTPD = new VexRMOp("VSQRTPD", P_66, M_0F, WIG, 0x51); + public static final VexRMOp VSQRTPS = new VexRMOp("VSQRTPS", P_, M_0F, WIG, 0x51); + public static final VexRMOp VSQRTSD = new VexRMOp("VSQRTSD", P_F2, M_0F, WIG, 0x51); + public static final VexRMOp VSQRTSS = new VexRMOp("VSQRTSS", P_F3, M_0F, WIG, 0x51); + public static final VexRMOp VUCOMISS = new VexRMOp("VUCOMISS", P_, M_0F, WIG, 0x2E); + public static final VexRMOp VUCOMISD = new VexRMOp("VUCOMISD", P_66, M_0F, WIG, 0x2E); + // @formatter:on + + protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op) { + this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1); + } + + protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src, 0); + } + } + + /** + * VEX-encoded move instructions. + *

+ * These instructions have two opcodes: op is the forward move instruction with an operand order + * of RM, and opReverse is the reverse move instruction with an operand order of MR. + */ + public static final class VexMoveOp extends VexRMOp { + // @formatter:off + public static final VexMoveOp VMOVDQA = new VexMoveOp("VMOVDQA", P_66, M_0F, WIG, 0x6F, 0x7F); + public static final VexMoveOp VMOVDQU = new VexMoveOp("VMOVDQU", P_F3, M_0F, WIG, 0x6F, 0x7F); + public static final VexMoveOp VMOVAPS = new VexMoveOp("VMOVAPS", P_, M_0F, WIG, 0x28, 0x29); + public static final VexMoveOp VMOVAPD = new VexMoveOp("VMOVAPD", P_66, M_0F, WIG, 0x28, 0x29); + public static final VexMoveOp VMOVUPS = new VexMoveOp("VMOVUPS", P_, M_0F, WIG, 0x10, 0x11); + public static final VexMoveOp VMOVUPD = new VexMoveOp("VMOVUPD", P_66, M_0F, WIG, 0x10, 0x11); + public static final VexMoveOp VMOVSS = new VexMoveOp("VMOVSS", P_F3, M_0F, WIG, 0x10, 0x11); + public static final VexMoveOp VMOVSD = new VexMoveOp("VMOVSD", P_F2, M_0F, WIG, 0x10, 0x11); + public static final VexMoveOp VMOVD = new VexMoveOp("VMOVD", P_66, M_0F, W0, 0x6E, 0x7E, AVXOpAssertion.XMM_CPU); + public static final VexMoveOp VMOVQ = new VexMoveOp("VMOVQ", P_66, M_0F, W1, 0x6E, 0x7E, AVXOpAssertion.XMM_CPU); + // @formatter:on + + private final int opReverse; + + private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) { + this(opcode, pp, mmmmm, w, op, opReverse, AVXOpAssertion.AVX1); + } + + private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + this.opReverse = opReverse; + } + + public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register src) { + assert assertion.check((AMD64) asm.target.arch, size, src, null, null); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.emitByte(opReverse); + asm.emitOperandHelper(src, dst, 0); + } + + public void emitReverse(AMD64Assembler asm, AVXSize size, Register dst, Register src) { + assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.emitByte(opReverse); + asm.emitModRM(src, dst); + } + } + + public interface VexRRIOp { + void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8); + } + + /** + * VEX-encoded instructions with an operand order of RMI. + */ + public static final class VexRMIOp extends VexOp implements VexRRIOp { + // @formatter:off + public static final VexRMIOp VPERMQ = new VexRMIOp("VPERMQ", P_66, M_0F3A, W1, 0x00, AVXOpAssertion.AVX2_256ONLY); + public static final VexRMIOp VPSHUFLW = new VexRMIOp("VPSHUFLW", P_F2, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2); + public static final VexRMIOp VPSHUFHW = new VexRMIOp("VPSHUFHW", P_F3, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2); + public static final VexRMIOp VPSHUFD = new VexRMIOp("VPSHUFD", P_66, M_0F, WIG, 0x70, AVXOpAssertion.AVX1_2); + // @formatter:on + + private VexRMIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + @Override + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src); + asm.emitByte(imm8); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, AMD64Address src, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); + asm.vexPrefix(dst, Register.None, src, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src, 1); + asm.emitByte(imm8); + } + } + + /** + * VEX-encoded instructions with an operand order of MRI. + */ + public static final class VexMRIOp extends VexOp implements VexRRIOp { + // @formatter:off + public static final VexMRIOp VEXTRACTF128 = new VexMRIOp("VEXTRACTF128", P_66, M_0F3A, W0, 0x19, AVXOpAssertion.AVX1_256ONLY); + public static final VexMRIOp VEXTRACTI128 = new VexMRIOp("VEXTRACTI128", P_66, M_0F3A, W0, 0x39, AVXOpAssertion.AVX2_256ONLY); + public static final VexMRIOp VPEXTRB = new VexMRIOp("VPEXTRB", P_66, M_0F3A, W0, 0x14, AVXOpAssertion.XMM_CPU); + public static final VexMRIOp VPEXTRW = new VexMRIOp("VPEXTRW", P_66, M_0F3A, W0, 0x15, AVXOpAssertion.XMM_CPU); + public static final VexMRIOp VPEXTRD = new VexMRIOp("VPEXTRD", P_66, M_0F3A, W0, 0x16, AVXOpAssertion.XMM_CPU); + public static final VexMRIOp VPEXTRQ = new VexMRIOp("VPEXTRQ", P_66, M_0F3A, W1, 0x16, AVXOpAssertion.XMM_CPU); + // @formatter:on + + private VexMRIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + @Override + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(src, dst); + asm.emitByte(imm8); + } + + public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register src, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, src, null, null); + asm.vexPrefix(src, Register.None, dst, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(src, dst, 1); + asm.emitByte(imm8); + } + } + + /** + * VEX-encoded instructions with an operand order of RVMR. + */ + public static class VexRVMROp extends VexOp { + // @formatter:off + public static final VexRVMROp VPBLENDVB = new VexRVMROp("VPBLENDVB", P_66, M_0F3A, W0, 0x4C, AVXOpAssertion.AVX1_2); + public static final VexRVMROp VPBLENDVPS = new VexRVMROp("VPBLENDVPS", P_66, M_0F3A, W0, 0x4A, AVXOpAssertion.AVX1); + public static final VexRVMROp VPBLENDVPD = new VexRVMROp("VPBLENDVPD", P_66, M_0F3A, W0, 0x4B, AVXOpAssertion.AVX1); + // @formatter:on + + protected VexRVMROp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, Register src1, Register src2) { + assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, src2); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src2); + asm.emitByte(mask.encoding() << 4); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, Register src1, AMD64Address src2) { + assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, null); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src2, 0); + asm.emitByte(mask.encoding() << 4); + } + } + + /** + * VEX-encoded instructions with an operand order of RVM. + */ + public static class VexRVMOp extends VexOp { + // @formatter:off + public static final VexRVMOp VANDPS = new VexRVMOp("VANDPS", P_, M_0F, WIG, 0x54); + public static final VexRVMOp VANDPD = new VexRVMOp("VANDPD", P_66, M_0F, WIG, 0x54); + public static final VexRVMOp VANDNPS = new VexRVMOp("VANDNPS", P_, M_0F, WIG, 0x55); + public static final VexRVMOp VANDNPD = new VexRVMOp("VANDNPD", P_66, M_0F, WIG, 0x55); + public static final VexRVMOp VORPS = new VexRVMOp("VORPS", P_, M_0F, WIG, 0x56); + public static final VexRVMOp VORPD = new VexRVMOp("VORPD", P_66, M_0F, WIG, 0x56); + public static final VexRVMOp VXORPS = new VexRVMOp("VXORPS", P_, M_0F, WIG, 0x57); + public static final VexRVMOp VXORPD = new VexRVMOp("VXORPD", P_66, M_0F, WIG, 0x57); + public static final VexRVMOp VADDPS = new VexRVMOp("VADDPS", P_, M_0F, WIG, 0x58); + public static final VexRVMOp VADDPD = new VexRVMOp("VADDPD", P_66, M_0F, WIG, 0x58); + public static final VexRVMOp VADDSS = new VexRVMOp("VADDSS", P_F3, M_0F, WIG, 0x58); + public static final VexRVMOp VADDSD = new VexRVMOp("VADDSD", P_F2, M_0F, WIG, 0x58); + public static final VexRVMOp VMULPS = new VexRVMOp("VMULPS", P_, M_0F, WIG, 0x59); + public static final VexRVMOp VMULPD = new VexRVMOp("VMULPD", P_66, M_0F, WIG, 0x59); + public static final VexRVMOp VMULSS = new VexRVMOp("VMULSS", P_F3, M_0F, WIG, 0x59); + public static final VexRVMOp VMULSD = new VexRVMOp("VMULSD", P_F2, M_0F, WIG, 0x59); + public static final VexRVMOp VSUBPS = new VexRVMOp("VSUBPS", P_, M_0F, WIG, 0x5C); + public static final VexRVMOp VSUBPD = new VexRVMOp("VSUBPD", P_66, M_0F, WIG, 0x5C); + public static final VexRVMOp VSUBSS = new VexRVMOp("VSUBSS", P_F3, M_0F, WIG, 0x5C); + public static final VexRVMOp VSUBSD = new VexRVMOp("VSUBSD", P_F2, M_0F, WIG, 0x5C); + public static final VexRVMOp VMINPS = new VexRVMOp("VMINPS", P_, M_0F, WIG, 0x5D); + public static final VexRVMOp VMINPD = new VexRVMOp("VMINPD", P_66, M_0F, WIG, 0x5D); + public static final VexRVMOp VMINSS = new VexRVMOp("VMINSS", P_F3, M_0F, WIG, 0x5D); + public static final VexRVMOp VMINSD = new VexRVMOp("VMINSD", P_F2, M_0F, WIG, 0x5D); + public static final VexRVMOp VDIVPS = new VexRVMOp("VDIVPS", P_, M_0F, WIG, 0x5E); + public static final VexRVMOp VDIVPD = new VexRVMOp("VDIVPD", P_66, M_0F, WIG, 0x5E); + public static final VexRVMOp VDIVSS = new VexRVMOp("VDIVPS", P_F3, M_0F, WIG, 0x5E); + public static final VexRVMOp VDIVSD = new VexRVMOp("VDIVPD", P_F2, M_0F, WIG, 0x5E); + public static final VexRVMOp VMAXPS = new VexRVMOp("VMAXPS", P_, M_0F, WIG, 0x5F); + public static final VexRVMOp VMAXPD = new VexRVMOp("VMAXPD", P_66, M_0F, WIG, 0x5F); + public static final VexRVMOp VMAXSS = new VexRVMOp("VMAXSS", P_F3, M_0F, WIG, 0x5F); + public static final VexRVMOp VMAXSD = new VexRVMOp("VMAXSD", P_F2, M_0F, WIG, 0x5F); + public static final VexRVMOp VADDSUBPS = new VexRVMOp("VADDSUBPS", P_F2, M_0F, WIG, 0xD0); + public static final VexRVMOp VADDSUBPD = new VexRVMOp("VADDSUBPD", P_66, M_0F, WIG, 0xD0); + public static final VexRVMOp VPAND = new VexRVMOp("VPAND", P_66, M_0F, WIG, 0xDB, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPOR = new VexRVMOp("VPOR", P_66, M_0F, WIG, 0xEB, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", P_66, M_0F, WIG, 0xEF, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPADDB = new VexRVMOp("VPADDB", P_66, M_0F, WIG, 0xFC, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPADDW = new VexRVMOp("VPADDW", P_66, M_0F, WIG, 0xFD, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPADDD = new VexRVMOp("VPADDD", P_66, M_0F, WIG, 0xFE, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPADDQ = new VexRVMOp("VPADDQ", P_66, M_0F, WIG, 0xD4, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPMULHUW = new VexRVMOp("VPMULHUW", P_66, M_0F, WIG, 0xE4, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPMULHW = new VexRVMOp("VPMULHW", P_66, M_0F, WIG, 0xE5, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPMULLW = new VexRVMOp("VPMULLW", P_66, M_0F, WIG, 0xD5, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPMULLD = new VexRVMOp("VPMULLD", P_66, M_0F38, WIG, 0x40, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPSUBB = new VexRVMOp("VPSUBB", P_66, M_0F, WIG, 0xF8, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPSUBW = new VexRVMOp("VPSUBW", P_66, M_0F, WIG, 0xF9, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPSUBD = new VexRVMOp("VPSUBD", P_66, M_0F, WIG, 0xFA, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPSUBQ = new VexRVMOp("VPSUBQ", P_66, M_0F, WIG, 0xFB, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPSHUFB = new VexRVMOp("VPSHUFB", P_66, M_0F38, WIG, 0x00, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VCVTSD2SS = new VexRVMOp("VCVTSD2SS", P_F2, M_0F, WIG, 0x5A); + public static final VexRVMOp VCVTSS2SD = new VexRVMOp("VCVTSS2SD", P_F3, M_0F, WIG, 0x5A); + public static final VexRVMOp VCVTSI2SD = new VexRVMOp("VCVTSI2SD", P_F2, M_0F, W0, 0x2A, AVXOpAssertion.XMM_XMM_CPU); + public static final VexRVMOp VCVTSQ2SD = new VexRVMOp("VCVTSQ2SD", P_F2, M_0F, W1, 0x2A, AVXOpAssertion.XMM_XMM_CPU); + public static final VexRVMOp VCVTSI2SS = new VexRVMOp("VCVTSI2SS", P_F3, M_0F, W0, 0x2A, AVXOpAssertion.XMM_XMM_CPU); + public static final VexRVMOp VCVTSQ2SS = new VexRVMOp("VCVTSQ2SS", P_F3, M_0F, W1, 0x2A, AVXOpAssertion.XMM_XMM_CPU); + public static final VexRVMOp VPCMPEQB = new VexRVMOp("VPCMPEQB", P_66, M_0F, WIG, 0x74, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPEQW = new VexRVMOp("VPCMPEQW", P_66, M_0F, WIG, 0x75, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPEQD = new VexRVMOp("VPCMPEQD", P_66, M_0F, WIG, 0x76, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPEQQ = new VexRVMOp("VPCMPEQQ", P_66, M_0F38, WIG, 0x29, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPGTB = new VexRVMOp("VPCMPGTB", P_66, M_0F, WIG, 0x64, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPGTW = new VexRVMOp("VPCMPGTW", P_66, M_0F, WIG, 0x65, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPGTD = new VexRVMOp("VPCMPGTD", P_66, M_0F, WIG, 0x66, AVXOpAssertion.AVX1_2); + public static final VexRVMOp VPCMPGTQ = new VexRVMOp("VPCMPGTQ", P_66, M_0F38, WIG, 0x37, AVXOpAssertion.AVX1_2); + // @formatter:on + + private VexRVMOp(String opcode, int pp, int mmmmm, int w, int op) { + this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1); + } + + protected VexRVMOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src2); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src2, 0); + } + } + + /** + * VEX-encoded shift instructions with an operand order of either RVM or VMI. + */ + public static final class VexShiftOp extends VexRVMOp implements VexRRIOp { + // @formatter:off + public static final VexShiftOp VPSRLW = new VexShiftOp("VPSRLW", P_66, M_0F, WIG, 0xD1, 0x71, 2); + public static final VexShiftOp VPSRLD = new VexShiftOp("VPSRLD", P_66, M_0F, WIG, 0xD2, 0x72, 2); + public static final VexShiftOp VPSRLQ = new VexShiftOp("VPSRLQ", P_66, M_0F, WIG, 0xD3, 0x73, 2); + public static final VexShiftOp VPSRAW = new VexShiftOp("VPSRAW", P_66, M_0F, WIG, 0xE1, 0x71, 4); + public static final VexShiftOp VPSRAD = new VexShiftOp("VPSRAD", P_66, M_0F, WIG, 0xE2, 0x72, 4); + public static final VexShiftOp VPSLLW = new VexShiftOp("VPSLLW", P_66, M_0F, WIG, 0xF1, 0x71, 6); + public static final VexShiftOp VPSLLD = new VexShiftOp("VPSLLD", P_66, M_0F, WIG, 0xF2, 0x72, 6); + public static final VexShiftOp VPSLLQ = new VexShiftOp("VPSLLQ", P_66, M_0F, WIG, 0xF3, 0x73, 6); + // @formatter:on + + private final int immOp; + private final int r; + + private VexShiftOp(String opcode, int pp, int mmmmm, int w, int op, int immOp, int r) { + super(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1_2); + this.immOp = immOp; + this.r = r; + } + + @Override + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, null, dst, src); + asm.vexPrefix(null, dst, src, size, pp, mmmmm, w); + asm.emitByte(immOp); + asm.emitModRM(r, src); + asm.emitByte(imm8); + } + } + + public static final class VexMaskMoveOp extends VexOp { + // @formatter:off + public static final VexMaskMoveOp VMASKMOVPS = new VexMaskMoveOp("VMASKMOVPS", P_66, M_0F38, W0, 0x2C, 0x2E); + public static final VexMaskMoveOp VMASKMOVPD = new VexMaskMoveOp("VMASKMOVPD", P_66, M_0F38, W0, 0x2D, 0x2F); + public static final VexMaskMoveOp VPMASKMOVD = new VexMaskMoveOp("VPMASKMOVD", P_66, M_0F38, W0, 0x8C, 0x8E, AVXOpAssertion.AVX2); + public static final VexMaskMoveOp VPMASKMOVQ = new VexMaskMoveOp("VPMASKMOVQ", P_66, M_0F38, W1, 0x8C, 0x8E, AVXOpAssertion.AVX2); + // @formatter:on + + private final int opReverse; + + private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) { + this(opcode, pp, mmmmm, w, op, opReverse, AVXOpAssertion.AVX1); + } + + private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + this.opReverse = opReverse; + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register mask, AMD64Address src) { + assert assertion.check((AMD64) asm.target.arch, size, dst, mask, null); + asm.vexPrefix(dst, mask, src, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src, 0); + } + + public void emit(AMD64Assembler asm, AVXSize size, AMD64Address dst, Register mask, Register src) { + assert assertion.check((AMD64) asm.target.arch, size, src, mask, null); + asm.vexPrefix(src, mask, dst, size, pp, mmmmm, w); + asm.emitByte(opReverse); + asm.emitOperandHelper(src, dst, 0); + } + } + + /** + * VEX-encoded instructions with an operand order of RVMI. + */ + public static final class VexRVMIOp extends VexOp { + // @formatter:off + public static final VexRVMIOp VSHUFPS = new VexRVMIOp("VSHUFPS", P_, M_0F, WIG, 0xC6); + public static final VexRVMIOp VSHUFPD = new VexRVMIOp("VSHUFPD", P_66, M_0F, WIG, 0xC6); + public static final VexRVMIOp VINSERTF128 = new VexRVMIOp("VINSERTF128", P_66, M_0F3A, W0, 0x18, AVXOpAssertion.AVX1_256ONLY); + public static final VexRVMIOp VINSERTI128 = new VexRVMIOp("VINSERTI128", P_66, M_0F3A, W0, 0x38, AVXOpAssertion.AVX2_256ONLY); + // @formatter:on + + private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op) { + this(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1); + } + + private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op, AVXOpAssertion assertion) { + super(opcode, pp, mmmmm, w, op, assertion); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); + assert (imm8 & 0xFF) == imm8; + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src2); + asm.emitByte(imm8); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, int imm8) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); + assert (imm8 & 0xFF) == imm8; + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src2, 1); + asm.emitByte(imm8); + } + } + + /** + * VEX-encoded comparison operation with an operand order of RVMI. The immediate operand is a + * comparison operator. + */ + public static final class VexFloatCompareOp extends VexOp { + // @formatter:off + public static final VexFloatCompareOp VCMPPS = new VexFloatCompareOp("VCMPPS", P_, M_0F, WIG, 0xC2); + public static final VexFloatCompareOp VCMPPD = new VexFloatCompareOp("VCMPPD", P_66, M_0F, WIG, 0xC2); + public static final VexFloatCompareOp VCMPSS = new VexFloatCompareOp("VCMPSS", P_F2, M_0F, WIG, 0xC2); + public static final VexFloatCompareOp VCMPSD = new VexFloatCompareOp("VCMPSD", P_F2, M_0F, WIG, 0xC2); + // @formatter:on + + public enum Predicate { + EQ_OQ(0x00), + LT_OS(0x01), + LE_OS(0x02), + UNORD_Q(0x03), + NEQ_UQ(0x04), + NLT_US(0x05), + NLE_US(0x06), + ORD_Q(0x07), + EQ_UQ(0x08), + NGE_US(0x09), + NGT_US(0x0a), + FALSE_OQ(0x0b), + NEQ_OQ(0x0c), + GE_OS(0x0d), + GT_OS(0x0e), + TRUE_UQ(0x0f), + EQ_OS(0x10), + LT_OQ(0x11), + LE_OQ(0x12), + UNORD_S(0x13), + NEQ_US(0x14), + NLT_UQ(0x15), + NLE_UQ(0x16), + ORD_S(0x17), + EQ_US(0x18), + NGE_UQ(0x19), + NGT_UQ(0x1a), + FALSE_OS(0x1b), + NEQ_OS(0x1c), + GE_OQ(0x1d), + GT_OQ(0x1e), + TRUE_US(0x1f); + + private int imm8; + + Predicate(int imm8) { + this.imm8 = imm8; + } + + public static Predicate getPredicate(Condition condition, boolean unorderedIsTrue) { + if (unorderedIsTrue) { + switch (condition) { + case EQ: + return EQ_UQ; + case NE: + return NEQ_UQ; + case LT: + return NGE_UQ; + case LE: + return NGT_UQ; + case GT: + return NLE_UQ; + case GE: + return NLT_UQ; + default: + throw GraalError.shouldNotReachHere(); + } + } else { + switch (condition) { + case EQ: + return EQ_OQ; + case NE: + return NEQ_OQ; + case LT: + return LT_OQ; + case LE: + return LE_OQ; + case GT: + return GT_OQ; + case GE: + return GE_OQ; + default: + throw GraalError.shouldNotReachHere(); + } + } + } + } + + private VexFloatCompareOp(String opcode, int pp, int mmmmm, int w, int op) { + super(opcode, pp, mmmmm, w, op, AVXOpAssertion.AVX1); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, Register src2, Predicate p) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitModRM(dst, src2); + asm.emitByte(p.imm8); + } + + public void emit(AMD64Assembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Predicate p) { + assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); + asm.vexPrefix(dst, src1, src2, size, pp, mmmmm, w); + asm.emitByte(op); + asm.emitOperandHelper(dst, src2, 1); + asm.emitByte(p.imm8); + } + } + public final void addl(AMD64Address dst, int imm32) { ADD.getMIOpcode(DWORD, isByte(imm32)).emit(this, DWORD, dst, imm32); } @@ -1713,35 +1561,19 @@ } public final void addpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x58); - emitByte(0xC0 | encode); + SSEOp.ADD.emit(this, PD, dst, src); } public final void addpd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x58); - emitOperandHelper(dst, src, 0); + SSEOp.ADD.emit(this, PD, dst, src); } public final void addsd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x58); - emitByte(0xC0 | encode); + SSEOp.ADD.emit(this, SD, dst, src); } public final void addsd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x58); - emitOperandHelper(dst, src, 0); + SSEOp.ADD.emit(this, SD, dst, src); } private void addrNop4() { @@ -1787,39 +1619,31 @@ } public final void andpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x54); - emitByte(0xC0 | encode); + SSEOp.AND.emit(this, PD, dst, src); } public final void andpd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x54); - emitOperandHelper(dst, src, 0); + SSEOp.AND.emit(this, PD, dst, src); } public final void bsfq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding(), src.encoding()); + prefixq(dst, src); emitByte(0x0F); emitByte(0xBC); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void bsrl(Register dst, Register src) { - int encode = prefixAndEncode(dst.encoding(), src.encoding()); + prefix(dst, src); emitByte(0x0F); emitByte(0xBD); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void bswapl(Register reg) { - int encode = prefixAndEncode(reg.encoding); + prefix(reg); emitByte(0x0F); - emitByte(0xC8 | encode); + emitModRM(1, reg); } public final void cdql() { @@ -1827,10 +1651,10 @@ } public final void cmovl(ConditionFlag cc, Register dst, Register src) { - int encode = prefixAndEncode(dst.encoding, src.encoding); + prefix(dst, src); emitByte(0x0F); emitByte(0x40 | cc.getValue()); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void cmovl(ConditionFlag cc, Register dst, AMD64Address src) { @@ -1894,53 +1718,21 @@ } public final void cvtsi2sdl(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.CPU); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x2A); - emitByte(0xC0 | encode); + SSEOp.CVTSI2SD.emit(this, DWORD, dst, src); } public final void cvttsd2sil(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.CPU) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x2C); - emitByte(0xC0 | encode); + SSEOp.CVTTSD2SI.emit(this, DWORD, dst, src); } - protected final void decl(AMD64Address dst) { + public final void decl(AMD64Address dst) { prefix(dst); emitByte(0xFF); emitOperandHelper(1, dst, 0); } public final void divsd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x5E); - emitByte(0xC0 | encode); - } - - public final void evmovdquq(Register dst, AMD64Address src, int vectorLen) { - assert supports(CPUFeature.AVX512F); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target); - attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit); - attributes.setIsEvexInstruction(); - vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6F); - emitOperandHelper(dst, src, 0); - } - - public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src, int vectorLen) { - assert supports(CPUFeature.AVX512BW); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target); - attributes.setIsEvexInstruction(); - attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit); - vexPrefix(src, nds, kdst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x74); - emitOperandHelper(kdst, src, 0); + SSEOp.DIV.emit(this, SD, dst, src); } public final void hlt() { @@ -1955,7 +1747,7 @@ } } - protected final void incl(AMD64Address dst) { + public final void incl(AMD64Address dst) { prefix(dst); emitByte(0xFF); emitOperandHelper(0, dst, 0); @@ -2041,15 +1833,15 @@ } public final void jmp(Register entry) { - int encode = prefixAndEncode(entry.encoding); + prefix(entry); emitByte(0xFF); - emitByte(0xE0 | encode); + emitModRM(4, entry); } public final void jmp(AMD64Address adr) { prefix(adr); emitByte(0xFF); - emitOperandHelper(rsp, adr, 0); + emitOperandHelper(AMD64.rsp, adr, 0); } public final void jmpb(Label l) { @@ -2068,32 +1860,6 @@ } } - // This instruction produces ZF or CF flags - public final void kortestql(Register src1, Register src2) { - assert supports(CPUFeature.AVX512BW); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target); - int encode = vexPrefixAndEncode(src1, Register.None, src2, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x98); - emitByte(0xC0 | encode); - } - - public final void kmovql(Register dst, Register src) { - assert supports(CPUFeature.AVX512BW); - if (src.getRegisterCategory().equals(AMD64.MASK)) { - // kmovql(KRegister dst, KRegister src) - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target); - int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x90); - emitByte(0xC0 | encode); - } else { - // kmovql(KRegister dst, Register src) - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target); - int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x92); - emitByte(0xC0 | encode); - } - } - public final void lead(Register dst, AMD64Address src) { prefix(src, dst); emitByte(0x8D); @@ -2115,19 +1881,17 @@ } public final void movapd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0x28); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movaps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PS, P_0F, false); emitByte(0x28); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movb(AMD64Address dst, int imm8) { @@ -2138,22 +1902,32 @@ } public final void movb(AMD64Address dst, Register src) { - assert src.getRegisterCategory().equals(AMD64.CPU) : "must have byte register"; + assert src.getRegisterCategory().equals(CPU) : "must have byte register"; prefixb(dst, src); emitByte(0x88); emitOperandHelper(src, dst, 0); } public final void movl(Register dst, int imm32) { - int encode = prefixAndEncode(dst.encoding); - emitByte(0xB8 | encode); + movl(dst, imm32, false); + } + + public final void movl(Register dst, int imm32, boolean annotateImm) { + int insnPos = position(); + prefix(dst); + emitByte(0xB8 + encode(dst)); + int immPos = position(); emitInt(imm32); + int nextInsnPos = position(); + if (annotateImm && codePatchingAnnotationConsumer != null) { + codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(insnPos, immPos, nextInsnPos - immPos, nextInsnPos)); + } } public final void movl(Register dst, Register src) { - int encode = prefixAndEncode(dst.encoding, src.encoding); + prefix(dst, src); emitByte(0x8B); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movl(Register dst, AMD64Address src) { @@ -2191,19 +1965,17 @@ * {@link AMD64MacroAssembler#movflt(Register, Register)}. */ public final void movlpd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x12); emitOperandHelper(dst, src, 0); } public final void movlhps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, src, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, src, src, PS, P_0F, false); emitByte(0x16); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movq(Register dst, AMD64Address src) { @@ -2211,9 +1983,8 @@ } public final void movq(Register dst, AMD64Address src, boolean wide) { - if (dst.getRegisterCategory().equals(AMD64.XMM)) { - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ wide, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); + if (dst.getRegisterCategory().equals(XMM)) { + simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x7E); emitOperandHelper(dst, src, wide, 0); } else { @@ -2225,15 +1996,14 @@ } public final void movq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x8B); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movq(AMD64Address dst, Register src) { - if (src.getRegisterCategory().equals(AMD64.XMM)) { - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + if (src.getRegisterCategory().equals(XMM)) { + simdPrefix(src, Register.None, dst, PD, P_0F, true); emitByte(0xD6); emitOperandHelper(src, dst, 0); } else { @@ -2252,10 +2022,10 @@ } public final void movsbl(Register dst, Register src) { - int encode = prefixAndEncode(dst.encoding, false, src.encoding, true); + prefix(dst, false, src, true); emitByte(0x0F); emitByte(0xBE); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movsbq(Register dst, AMD64Address src) { @@ -2266,98 +2036,54 @@ } public final void movsbq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x0F); emitByte(0xBE); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movsd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x10); - emitByte(0xC0 | encode); + AMD64RMOp.MOVSD.emit(this, SD, dst, src); } public final void movsd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x10); - emitOperandHelper(dst, src, 0); + AMD64RMOp.MOVSD.emit(this, SD, dst, src); } public final void movsd(AMD64Address dst, Register src) { - assert src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x11); - emitOperandHelper(src, dst, 0); + AMD64MROp.MOVSD.emit(this, SD, dst, src); } public final void movss(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x10); - emitByte(0xC0 | encode); + AMD64RMOp.MOVSS.emit(this, SS, dst, src); } public final void movss(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x10); - emitOperandHelper(dst, src, 0); + AMD64RMOp.MOVSS.emit(this, SS, dst, src); } public final void movss(AMD64Address dst, Register src) { - assert src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x11); - emitOperandHelper(src, dst, 0); + AMD64MROp.MOVSS.emit(this, SS, dst, src); } public final void mulpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x59); - emitByte(0xC0 | encode); + SSEOp.MUL.emit(this, PD, dst, src); } public final void mulpd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x59); - emitOperandHelper(dst, src, 0); + SSEOp.MUL.emit(this, PD, dst, src); } public final void mulsd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x59); - emitByte(0xC0 | encode); + SSEOp.MUL.emit(this, SD, dst, src); } public final void mulsd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x59); - emitOperandHelper(dst, src, 0); + SSEOp.MUL.emit(this, SD, dst, src); } public final void mulss(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x59); - emitByte(0xC0 | encode); + SSEOp.MUL.emit(this, SS, dst, src); } public final void movswl(Register dst, AMD64Address src) { @@ -2390,11 +2116,11 @@ } public final void movzbl(Register dst, Register src) { - AMD64RMOp.MOVZXB.emit(this, OperandSize.DWORD, dst, src); + AMD64RMOp.MOVZXB.emit(this, DWORD, dst, src); } public final void movzbq(Register dst, Register src) { - AMD64RMOp.MOVZXB.emit(this, OperandSize.QWORD, dst, src); + AMD64RMOp.MOVZXB.emit(this, QWORD, dst, src); } public final void movzwl(Register dst, AMD64Address src) { @@ -2639,8 +2365,8 @@ } public final void pop(Register dst) { - int encode = prefixAndEncode(dst.encoding); - emitByte(0x58 | encode); + prefix(dst); + emitByte(0x58 + encode(dst)); } public void popfq() { @@ -2649,26 +2375,32 @@ public final void ptest(Register dst, Register src) { assert supports(CPUFeature.SSE4_1); - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F38, false); emitByte(0x17); - emitByte(0xC0 | encode); + emitModRM(dst, src); } - public final void vptest(Register dst, Register src) { - assert supports(CPUFeature.AVX); - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes); - emitByte(0x17); - emitByte(0xC0 | encode); + public final void pcmpeqb(Register dst, Register src) { + assert supports(CPUFeature.SSE2); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); + emitByte(0x74); + emitModRM(dst, src); + } + + public final void pcmpeqw(Register dst, Register src) { + assert supports(CPUFeature.SSE2); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); + emitByte(0x75); + emitModRM(dst, src); } public final void pcmpestri(Register dst, AMD64Address src, int imm8) { assert supports(CPUFeature.SSE4_2); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes); + assert dst.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F3A, false); emitByte(0x61); emitOperandHelper(dst, src, 0); emitByte(imm8); @@ -2676,36 +2408,33 @@ public final void pcmpestri(Register dst, Register src, int imm8) { assert supports(CPUFeature.SSE4_2); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F3A, false); emitByte(0x61); - emitByte(0xC0 | encode); + emitModRM(dst, src); emitByte(imm8); } + public final void pmovmskb(Register dst, Register src) { + assert supports(CPUFeature.SSE2); + assert dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F, false); + emitByte(0xD7); + emitModRM(dst, src); + } + public final void pmovzxbw(Register dst, AMD64Address src) { assert supports(CPUFeature.SSE4_2); + assert dst.getRegisterCategory().equals(XMM); // XXX legacy_mode should be: _legacy_mode_bw - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target); - attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes); - emitByte(0x30); - emitOperandHelper(dst, src, 0); - } - - public final void vpmovzxbw(Register dst, AMD64Address src, int vectorLen) { - assert supports(CPUFeature.AVX); - // XXX legacy_mode should be: _legacy_mode_bw - AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target); - attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit); - vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes); + simdPrefix(dst, Register.None, src, PD, P_0F38, false); emitByte(0x30); emitOperandHelper(dst, src, 0); } public final void push(Register src) { - int encode = prefixAndEncode(src.encoding); - emitByte(0x50 | encode); + prefix(src); + emitByte(0x50 + encode(src)); } public void pushfq() { @@ -2713,178 +2442,161 @@ } public final void paddd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xFE); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void paddq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xD4); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void pextrw(Register dst, Register src, int imm8) { - assert dst.getRegisterCategory().equals(AMD64.CPU) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0xC5); - emitByte(0xC0 | encode); + emitModRM(dst, src); emitByte(imm8); } public final void pinsrw(Register dst, Register src, int imm8) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.CPU); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xC4); - emitByte(0xC0 | encode); + emitModRM(dst, src); emitByte(imm8); } public final void por(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xEB); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void pand(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xDB); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void pxor(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xEF); - emitByte(0xC0 | encode); - } - - public final void vpxor(Register dst, Register nds, Register src) { - assert supports(CPUFeature.AVX); - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = vexPrefixAndEncode(dst, nds, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0xEF); - emitByte(0xC0 | encode); - } - - public final void vpxor(Register dst, Register nds, AMD64Address src) { - assert supports(CPUFeature.AVX); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target); - attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FV, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_32bit); - vexPrefix(src, nds, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0xEF); - emitOperandHelper(dst, src, 0); + emitModRM(dst, src); } public final void pslld(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); + assert dst.getRegisterCategory().equals(XMM); // XMM6 is for /6 encoding: 66 0F 72 /6 ib - int encode = simdPrefixAndEncode(AMD64.xmm6, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + simdPrefix(AMD64.xmm6, dst, dst, PD, P_0F, false); emitByte(0x72); - emitByte(0xC0 | encode); + emitModRM(6, dst); emitByte(imm8 & 0xFF); } public final void psllq(Register dst, Register shift) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && shift.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, shift, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && shift.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, shift, PD, P_0F, false); emitByte(0xF3); - emitByte(0xC0 | encode); + emitModRM(dst, shift); } public final void psllq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); + assert dst.getRegisterCategory().equals(XMM); // XMM6 is for /6 encoding: 66 0F 73 /6 ib - int encode = simdPrefixAndEncode(AMD64.xmm6, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + simdPrefix(AMD64.xmm6, dst, dst, PD, P_0F, false); emitByte(0x73); - emitByte(0xC0 | encode); + emitModRM(6, dst); emitByte(imm8); } public final void psrad(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - // XMM4 is for /2 encoding: 66 0F 72 /4 ib - int encode = simdPrefixAndEncode(AMD64.xmm4, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM); + // XMM4 is for /4 encoding: 66 0F 72 /4 ib + simdPrefix(AMD64.xmm4, dst, dst, PD, P_0F, false); emitByte(0x72); - emitByte(0xC0 | encode); + emitModRM(4, dst); emitByte(imm8); } public final void psrld(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); + assert dst.getRegisterCategory().equals(XMM); // XMM2 is for /2 encoding: 66 0F 72 /2 ib - int encode = simdPrefixAndEncode(AMD64.xmm2, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + simdPrefix(AMD64.xmm2, dst, dst, PD, P_0F, false); emitByte(0x72); - emitByte(0xC0 | encode); + emitModRM(2, dst); emitByte(imm8); } public final void psrlq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); + assert dst.getRegisterCategory().equals(XMM); // XMM2 is for /2 encoding: 66 0F 73 /2 ib - int encode = simdPrefixAndEncode(AMD64.xmm2, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + simdPrefix(AMD64.xmm2, dst, dst, PD, P_0F, false); emitByte(0x73); - emitByte(0xC0 | encode); + emitModRM(2, dst); emitByte(imm8); } public final void psrldq(Register dst, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(AMD64.xmm3, dst, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM); + simdPrefix(AMD64.xmm3, dst, dst, PD, P_0F, false); emitByte(0x73); - emitByte(0xC0 | encode); + emitModRM(3, dst); + emitByte(imm8); + } + + public final void pshufb(Register dst, Register src) { + assert supports(CPUFeature.SSSE3); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F38, false); + emitByte(0x00); + emitModRM(dst, src); + } + + public final void pshuflw(Register dst, Register src, int imm8) { + assert supports(CPUFeature.SSE2); + assert isUByte(imm8) : "invalid value"; + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, SD, P_0F, false); + emitByte(0x70); + emitModRM(dst, src); emitByte(imm8); } public final void pshufd(Register dst, Register src, int imm8) { assert isUByte(imm8) : "invalid value"; - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0x70); - emitByte(0xC0 | encode); + emitModRM(dst, src); emitByte(imm8); } public final void psubd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0xFA); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void rcpps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ true, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PS, P_0F, false); emitByte(0x53); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void ret(int imm16) { @@ -2897,49 +2609,51 @@ } public final void sarl(Register dst, int imm8) { - int encode = prefixAndEncode(dst.encoding); + prefix(dst); assert isShiftCount(imm8 >> 1) : "illegal shift count"; if (imm8 == 1) { emitByte(0xD1); - emitByte(0xF8 | encode); + emitModRM(7, dst); } else { emitByte(0xC1); - emitByte(0xF8 | encode); + emitModRM(7, dst); emitByte(imm8); } } public final void shll(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; - int encode = prefixAndEncode(dst.encoding); + prefix(dst); if (imm8 == 1) { emitByte(0xD1); - emitByte(0xE0 | encode); + emitModRM(4, dst); } else { emitByte(0xC1); - emitByte(0xE0 | encode); + emitModRM(4, dst); emitByte(imm8); } } public final void shll(Register dst) { - int encode = prefixAndEncode(dst.encoding); + // Multiply dst by 2, CL times. + prefix(dst); emitByte(0xD3); - emitByte(0xE0 | encode); + emitModRM(4, dst); } public final void shrl(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; - int encode = prefixAndEncode(dst.encoding); + prefix(dst); emitByte(0xC1); - emitByte(0xE8 | encode); + emitModRM(5, dst); emitByte(imm8); } public final void shrl(Register dst) { - int encode = prefixAndEncode(dst.encoding); + // Unsigned divide dst by 2, CL times. + prefix(dst); emitByte(0xD3); - emitByte(0xE8 | encode); + emitModRM(5, dst); } public final void subl(AMD64Address dst, int imm32) { @@ -2955,48 +2669,35 @@ } public final void subpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x5C); - emitByte(0xC0 | encode); + SSEOp.SUB.emit(this, PD, dst, src); } public final void subsd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x5C); - emitByte(0xC0 | encode); + SSEOp.SUB.emit(this, SD, dst, src); } public final void subsd(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x5C); - emitOperandHelper(dst, src, 0); + SSEOp.SUB.emit(this, SD, dst, src); } public final void testl(Register dst, int imm32) { // not using emitArith because test // doesn't support sign-extension of // 8bit operands - int encode = dst.encoding; - if (encode == 0) { + if (dst.encoding == 0) { emitByte(0xA9); } else { - encode = prefixAndEncode(encode); + prefix(dst); emitByte(0xF7); - emitByte(0xC0 | encode); + emitModRM(0, dst); } emitInt(imm32); } public final void testl(Register dst, Register src) { - int encode = prefixAndEncode(dst.encoding, src.encoding); + prefix(dst, src); emitByte(0x85); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void testl(Register dst, AMD64Address src) { @@ -3006,19 +2707,17 @@ } public final void unpckhpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x15); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void unpcklpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, dst, src, PD, P_0F, false); emitByte(0x14); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void xorl(Register dst, Register src) { @@ -3026,335 +2725,25 @@ } public final void xorpd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x57); - emitByte(0xC0 | encode); + SSEOp.XOR.emit(this, PD, dst, src); } public final void xorps(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x57); - emitByte(0xC0 | encode); + SSEOp.XOR.emit(this, PS, dst, src); } protected final void decl(Register dst) { // Use two-byte form (one-byte form is a REX prefix in 64-bit mode) - int encode = prefixAndEncode(dst.encoding); + prefix(dst); emitByte(0xFF); - emitByte(0xC8 | encode); + emitModRM(1, dst); } protected final void incl(Register dst) { // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixAndEncode(dst.encoding); + prefix(dst); emitByte(0xFF); - emitByte(0xC0 | encode); - } - - private int prefixAndEncode(int regEnc) { - return prefixAndEncode(regEnc, false); - } - - private int prefixAndEncode(int regEnc, boolean byteinst) { - if (regEnc >= 8) { - emitByte(Prefix.REXB); - return regEnc - 8; - } else if (byteinst && regEnc >= 4) { - emitByte(Prefix.REX); - } - return regEnc; - } - - private int prefixqAndEncode(int regEnc) { - if (regEnc < 8) { - emitByte(Prefix.REXW); - return regEnc; - } else { - emitByte(Prefix.REXWB); - return regEnc - 8; - } - } - - private int prefixAndEncode(int dstEnc, int srcEnc) { - return prefixAndEncode(dstEnc, false, srcEnc, false); - } - - private int prefixAndEncode(int dstEncoding, boolean dstIsByte, int srcEncoding, boolean srcIsByte) { - int srcEnc = srcEncoding; - int dstEnc = dstEncoding; - if (dstEnc < 8) { - if (srcEnc >= 8) { - emitByte(Prefix.REXB); - srcEnc -= 8; - } else if ((srcIsByte && srcEnc >= 4) || (dstIsByte && dstEnc >= 4)) { - emitByte(Prefix.REX); - } - } else { - if (srcEnc < 8) { - emitByte(Prefix.REXR); - } else { - emitByte(Prefix.REXRB); - srcEnc -= 8; - } - dstEnc -= 8; - } - return dstEnc << 3 | srcEnc; - } - - /** - * Creates prefix and the encoding of the lower 6 bits of the ModRM-Byte. It emits an operand - * prefix. If the given operands exceed 3 bits, the 4th bit is encoded in the prefix. - * - * @param regEncoding the encoding of the register part of the ModRM-Byte - * @param rmEncoding the encoding of the r/m part of the ModRM-Byte - * @return the lower 6 bits of the ModRM-Byte that should be emitted - */ - private int prefixqAndEncode(int regEncoding, int rmEncoding) { - int rmEnc = rmEncoding; - int regEnc = regEncoding; - if (regEnc < 8) { - if (rmEnc < 8) { - emitByte(Prefix.REXW); - } else { - emitByte(Prefix.REXWB); - rmEnc -= 8; - } - } else { - if (rmEnc < 8) { - emitByte(Prefix.REXWR); - } else { - emitByte(Prefix.REXWRB); - rmEnc -= 8; - } - regEnc -= 8; - } - return regEnc << 3 | rmEnc; - } - - private void vexPrefix(int rxb, int ndsEncoding, int pre, int opc, AMD64InstructionAttr attributes) { - int vectorLen = attributes.getVectorLen(); - boolean vexW = attributes.isRexVexW(); - boolean isXorB = ((rxb & 0x3) > 0); - if (isXorB || vexW || (opc == VexOpcode.VEX_OPCODE_0F_38) || (opc == VexOpcode.VEX_OPCODE_0F_3A)) { - emitByte(Prefix.VEX_3BYTES); - - int byte1 = (rxb << 5); - byte1 = ((~byte1) & 0xE0) | opc; - emitByte(byte1); - - int byte2 = ((~ndsEncoding) & 0xf) << 3; - byte2 |= (vexW ? VexPrefix.VEX_W : 0) | ((vectorLen > 0) ? 4 : 0) | pre; - emitByte(byte2); - } else { - emitByte(Prefix.VEX_2BYTES); - - int byte1 = ((rxb & 0x4) > 0) ? VexPrefix.VEX_R : 0; - byte1 = (~byte1) & 0x80; - byte1 |= ((~ndsEncoding) & 0xf) << 3; - byte1 |= ((vectorLen > 0) ? 4 : 0) | pre; - emitByte(byte1); - } - } - - private void vexPrefix(AMD64Address adr, Register nds, Register src, int pre, int opc, AMD64InstructionAttr attributes) { - int rxb = getRXB(src, adr); - int ndsEncoding = nds.isValid() ? nds.encoding : 0; - vexPrefix(rxb, ndsEncoding, pre, opc, attributes); - setCurAttributes(attributes); - } - - private int vexPrefixAndEncode(Register dst, Register nds, Register src, int pre, int opc, AMD64InstructionAttr attributes) { - int rxb = getRXB(dst, src); - int ndsEncoding = nds.isValid() ? nds.encoding : 0; - vexPrefix(rxb, ndsEncoding, pre, opc, attributes); - // return modrm byte components for operands - return (((dst.encoding & 7) << 3) | (src.encoding & 7)); - } - - private void simdPrefix(Register xreg, Register nds, AMD64Address adr, int pre, int opc, AMD64InstructionAttr attributes) { - if (supports(CPUFeature.AVX)) { - vexPrefix(adr, nds, xreg, pre, opc, attributes); - } else { - switch (pre) { - case VexSimdPrefix.VEX_SIMD_66: - emitByte(0x66); - break; - case VexSimdPrefix.VEX_SIMD_F2: - emitByte(0xF2); - break; - case VexSimdPrefix.VEX_SIMD_F3: - emitByte(0xF3); - break; - } - if (attributes.isRexVexW()) { - prefixq(adr, xreg); - } else { - prefix(adr, xreg); - } - switch (opc) { - case VexOpcode.VEX_OPCODE_0F: - emitByte(0x0F); - break; - case VexOpcode.VEX_OPCODE_0F_38: - emitByte(0x0F); - emitByte(0x38); - break; - case VexOpcode.VEX_OPCODE_0F_3A: - emitByte(0x0F); - emitByte(0x3A); - break; - } - } - } - - private int simdPrefixAndEncode(Register dst, Register nds, Register src, int pre, int opc, AMD64InstructionAttr attributes) { - if (supports(CPUFeature.AVX)) { - return vexPrefixAndEncode(dst, nds, src, pre, opc, attributes); - } else { - switch (pre) { - case VexSimdPrefix.VEX_SIMD_66: - emitByte(0x66); - break; - case VexSimdPrefix.VEX_SIMD_F2: - emitByte(0xF2); - break; - case VexSimdPrefix.VEX_SIMD_F3: - emitByte(0xF3); - break; - } - int encode; - int dstEncoding = dst.encoding; - int srcEncoding = src.encoding; - if (attributes.isRexVexW()) { - encode = prefixqAndEncode(dstEncoding, srcEncoding); - } else { - encode = prefixAndEncode(dstEncoding, srcEncoding); - } - switch (opc) { - case VexOpcode.VEX_OPCODE_0F: - emitByte(0x0F); - break; - case VexOpcode.VEX_OPCODE_0F_38: - emitByte(0x0F); - emitByte(0x38); - break; - case VexOpcode.VEX_OPCODE_0F_3A: - emitByte(0x0F); - emitByte(0x3A); - break; - } - return encode; - } - } - - private static boolean needsRex(Register reg) { - return reg.encoding >= MinEncodingNeedsRex; - } - - private void prefix(AMD64Address adr) { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXXB); - } else { - emitByte(Prefix.REXB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXX); - } - } - } - - private void prefixq(AMD64Address adr) { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWXB); - } else { - emitByte(Prefix.REXWB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWX); - } else { - emitByte(Prefix.REXW); - } - } - } - - private void prefixb(AMD64Address adr, Register reg) { - prefix(adr, reg, true); - } - - private void prefix(AMD64Address adr, Register reg) { - prefix(adr, reg, false); - } - - private void prefix(AMD64Address adr, Register reg, boolean byteinst) { - if (reg.encoding < 8) { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXXB); - } else { - emitByte(Prefix.REXB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXX); - } else if (byteinst && reg.encoding >= 4) { - emitByte(Prefix.REX); - } - } - } else { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXRXB); - } else { - emitByte(Prefix.REXRB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXRX); - } else { - emitByte(Prefix.REXR); - } - } - } - } - - private void prefixq(AMD64Address adr, Register src) { - if (src.encoding < 8) { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWXB); - } else { - emitByte(Prefix.REXWB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWX); - } else { - emitByte(Prefix.REXW); - } - } - } else { - if (needsRex(adr.getBase())) { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWRXB); - } else { - emitByte(Prefix.REXWRB); - } - } else { - if (needsRex(adr.getIndex())) { - emitByte(Prefix.REXWRX); - } else { - emitByte(Prefix.REXWR); - } - } - } + emitModRM(0, dst); } public final void addq(Register dst, int imm32) { @@ -3378,35 +2767,35 @@ } public final void bsrq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding(), src.encoding()); + prefixq(dst, src); emitByte(0x0F); emitByte(0xBD); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void bswapq(Register reg) { - int encode = prefixqAndEncode(reg.encoding); + prefixq(reg); emitByte(0x0F); - emitByte(0xC8 | encode); + emitByte(0xC8 + encode(reg)); } public final void cdqq() { - emitByte(Prefix.REXW); + rexw(); emitByte(0x99); } public final void cmovq(ConditionFlag cc, Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x0F); emitByte(0x40 | cc.getValue()); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void setb(ConditionFlag cc, Register dst) { - int encode = prefixAndEncode(dst.encoding, true); + prefix(dst, true); emitByte(0x0F); emitByte(0x90 | cc.getValue()); - emitByte(0xC0 | encode); + emitModRM(0, dst); } public final void cmovq(ConditionFlag cc, Register dst, AMD64Address src) { @@ -3436,42 +2825,32 @@ } public final void cvtdq2pd(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0xE6); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void cvtsi2sdq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.CPU); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, dst, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x2A); - emitByte(0xC0 | encode); + SSEOp.CVTSI2SD.emit(this, QWORD, dst, src); } public final void cvttsd2siq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.CPU) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x2C); - emitByte(0xC0 | encode); + SSEOp.CVTTSD2SI.emit(this, QWORD, dst, src); } public final void cvttpd2dq(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, PD, P_0F, false); emitByte(0xE6); - emitByte(0xC0 | encode); + emitModRM(dst, src); } - protected final void decq(Register dst) { + public final void decq(Register dst) { // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); emitByte(0xFF); - emitByte(0xC8 | encode); + emitModRM(1, dst); } public final void decq(AMD64Address dst) { @@ -3479,18 +2858,18 @@ } public final void imulq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x0F); emitByte(0xAF); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void incq(Register dst) { // Don't use it directly. Use Macroincrementq() instead. // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); emitByte(0xFF); - emitByte(0xC0 | encode); + emitModRM(0, dst); } public final void incq(AMD64Address dst) { @@ -3498,115 +2877,80 @@ } public final void movq(Register dst, long imm64) { - int encode = prefixqAndEncode(dst.encoding); - emitByte(0xB8 | encode); + movq(dst, imm64, false); + } + + public final void movq(Register dst, long imm64, boolean annotateImm) { + int insnPos = position(); + prefixq(dst); + emitByte(0xB8 + encode(dst)); + int immPos = position(); emitLong(imm64); + int nextInsnPos = position(); + if (annotateImm && codePatchingAnnotationConsumer != null) { + codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(insnPos, immPos, nextInsnPos - immPos, nextInsnPos)); + } } public final void movslq(Register dst, int imm32) { - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); emitByte(0xC7); - emitByte(0xC0 | encode); + emitModRM(0, dst); emitInt(imm32); } public final void movdq(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6E); - emitOperandHelper(dst, src, 0); + AMD64RMOp.MOVQ.emit(this, QWORD, dst, src); } public final void movdq(AMD64Address dst, Register src) { - assert src.getRegisterCategory().equals(AMD64.XMM); - // swap src/dst to get correct prefix - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x7E); - emitOperandHelper(src, dst, 0); + AMD64MROp.MOVQ.emit(this, QWORD, dst, src); } public final void movdq(Register dst, Register src) { - if (dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.CPU)) { - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6E); - emitByte(0xC0 | encode); - } else if (src.getRegisterCategory().equals(AMD64.XMM) && dst.getRegisterCategory().equals(AMD64.CPU)) { - // swap src/dst to get correct prefix - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ true, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x7E); - emitByte(0xC0 | encode); + if (dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU)) { + AMD64RMOp.MOVQ.emit(this, QWORD, dst, src); + } else if (src.getRegisterCategory().equals(XMM) && dst.getRegisterCategory().equals(CPU)) { + AMD64MROp.MOVQ.emit(this, QWORD, dst, src); } else { throw new InternalError("should not reach here"); } } public final void movdl(Register dst, Register src) { - if (dst.getRegisterCategory().equals(AMD64.XMM) && src.getRegisterCategory().equals(AMD64.CPU)) { - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6E); - emitByte(0xC0 | encode); - } else if (src.getRegisterCategory().equals(AMD64.XMM) && dst.getRegisterCategory().equals(AMD64.CPU)) { - // swap src/dst to get correct prefix - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x7E); - emitByte(0xC0 | encode); + if (dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(CPU)) { + AMD64RMOp.MOVD.emit(this, DWORD, dst, src); + } else if (src.getRegisterCategory().equals(XMM) && dst.getRegisterCategory().equals(CPU)) { + AMD64MROp.MOVD.emit(this, DWORD, dst, src); } else { throw new InternalError("should not reach here"); } } public final void movdl(Register dst, AMD64Address src) { - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6E); - emitOperandHelper(dst, src, 0); + AMD64RMOp.MOVD.emit(this, DWORD, dst, src); } public final void movddup(Register dst, Register src) { assert supports(CPUFeature.SSE3); - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, SD, P_0F, false); emitByte(0x12); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void movdqu(Register dst, AMD64Address src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x6F); emitOperandHelper(dst, src, 0); } public final void movdqu(Register dst, Register src) { - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); + assert dst.getRegisterCategory().equals(XMM) && src.getRegisterCategory().equals(XMM); + simdPrefix(dst, Register.None, src, SS, P_0F, false); emitByte(0x6F); - emitByte(0xC0 | encode); - } - - public final void vmovdqu(Register dst, AMD64Address src) { - assert supports(CPUFeature.AVX); - assert dst.getRegisterCategory().equals(AMD64.XMM); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x6F); - emitOperandHelper(dst, src, 0); - } - - public final void vzeroupper() { - assert supports(CPUFeature.AVX); - AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target); - vexPrefixAndEncode(AMD64.xmm0, AMD64.xmm0, AMD64.xmm0, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes); - emitByte(0x77); + emitModRM(dst, src); } public final void movslq(AMD64Address dst, int imm32) { @@ -3623,15 +2967,15 @@ } public final void movslq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x63); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void negq(Register dst) { - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); emitByte(0xF7); - emitByte(0xD8 | encode); + emitModRM(3, dst); } public final void orq(Register dst, Register src) { @@ -3640,40 +2984,42 @@ public final void shlq(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); if (imm8 == 1) { emitByte(0xD1); - emitByte(0xE0 | encode); + emitModRM(4, dst); } else { emitByte(0xC1); - emitByte(0xE0 | encode); + emitModRM(4, dst); emitByte(imm8); } } public final void shlq(Register dst) { - int encode = prefixqAndEncode(dst.encoding); + // Multiply dst by 2, CL times. + prefixq(dst); emitByte(0xD3); - emitByte(0xE0 | encode); + emitModRM(4, dst); } public final void shrq(Register dst, int imm8) { assert isShiftCount(imm8 >> 1) : "illegal shift count"; - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); if (imm8 == 1) { emitByte(0xD1); - emitByte(0xE8 | encode); + emitModRM(5, dst); } else { emitByte(0xC1); - emitByte(0xE8 | encode); + emitModRM(5, dst); emitByte(imm8); } } public final void shrq(Register dst) { - int encode = prefixqAndEncode(dst.encoding); + prefixq(dst); emitByte(0xD3); - emitByte(0xE8 | encode); + // Unsigned divide dst by 2, CL times. + emitModRM(5, dst); } public final void sbbq(Register dst, Register src) { @@ -3698,16 +3044,16 @@ } public final void testq(Register dst, Register src) { - int encode = prefixqAndEncode(dst.encoding, src.encoding); + prefixq(dst, src); emitByte(0x85); - emitByte(0xC0 | encode); + emitModRM(dst, src); } public final void btrq(Register src, int imm8) { - int encode = prefixqAndEncode(src.encoding); + prefixq(src); emitByte(0x0F); emitByte(0xBA); - emitByte(0xF0 | encode); + emitModRM(6, src); emitByte(imm8); } @@ -3778,7 +3124,7 @@ // the code where this idiom is used, in particular the // orderAccess code. lock(); - addl(new AMD64Address(rsp, 0), 0); // Assert the lock# signal here + addl(new AMD64Address(AMD64.rsp, 0), 0); // Assert the lock# signal here } } } @@ -3842,18 +3188,15 @@ * responsible to add the call address to the appropriate patching tables. */ public final void call() { - if (codePatchingAnnotationConsumer != null) { - int pos = position(); - codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(pos, pos + 1, 4, pos + 5)); - } + annotatePatchingImmediate(1, 4); emitByte(0xE8); emitInt(0); } public final void call(Register src) { - int encode = prefixAndEncode(src.encoding); + prefix(src); emitByte(0xFF); - emitByte(0xD0 | encode); + emitModRM(2, src); } public final void int3() { @@ -3965,7 +3308,7 @@ @Override public AMD64Address getPlaceholder(int instructionStartPosition) { - return new AMD64Address(rip, Register.None, Scale.Times1, 0, instructionStartPosition); + return new AMD64Address(AMD64.rip, Register.None, Scale.Times1, 0, instructionStartPosition); } private void prefetchPrefix(AMD64Address src) { @@ -4034,6 +3377,93 @@ emitByte(0x0f); emitByte(0xae); emitByte(0xe8); - + } + + public final void vptest(Register dst, Register src) { + VexRMOp.VPTEST.emit(this, AVXSize.YMM, dst, src); + } + + public final void vpxor(Register dst, Register nds, Register src) { + VexRVMOp.VPXOR.emit(this, AVXSize.YMM, dst, nds, src); + } + + public final void vpxor(Register dst, Register nds, AMD64Address src) { + VexRVMOp.VPXOR.emit(this, AVXSize.YMM, dst, nds, src); + } + + public final void vmovdqu(Register dst, AMD64Address src) { + VexMoveOp.VMOVDQU.emit(this, AVXSize.YMM, dst, src); + } + + public final void vpmovzxbw(Register dst, AMD64Address src) { + VexRMOp.VPMOVZXBW.emit(this, AVXSize.YMM, dst, src); + } + + public final void vzeroupper() { + emitVEX(L128, P_, M_0F, W0, 0, 0); + emitByte(0x77); + } + + // This instruction produces ZF or CF flags + public final void kortestq(Register src1, Register src2) { + assert supports(CPUFeature.AVX512BW); + assert src1.getRegisterCategory().equals(MASK) && src2.getRegisterCategory().equals(MASK); + vexPrefix(src1, Register.None, src2, AVXSize.XMM, P_, M_0F, W1); + emitByte(0x98); + emitModRM(src1, src2); + } + + public final void kmovq(Register dst, Register src) { + assert supports(CPUFeature.AVX512BW); + assert dst.getRegisterCategory().equals(MASK) || dst.getRegisterCategory().equals(CPU); + assert src.getRegisterCategory().equals(MASK) || src.getRegisterCategory().equals(CPU); + assert !(dst.getRegisterCategory().equals(CPU) && src.getRegisterCategory().equals(CPU)); + + if (dst.getRegisterCategory().equals(MASK)) { + if (src.getRegisterCategory().equals(MASK)) { + // kmovq(KRegister dst, KRegister src) + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_, M_0F, W1); + emitByte(0x90); + emitModRM(dst, src); + } else { + // kmovq(KRegister dst, Register src) + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1); + emitByte(0x92); + emitModRM(dst, src); + } + } else { + if (src.getRegisterCategory().equals(MASK)) { + // kmovq(Register dst, KRegister src) + vexPrefix(dst, Register.None, src, AVXSize.XMM, P_F2, M_0F, W1); + emitByte(0x93); + emitModRM(dst, src); + } else { + throw GraalError.shouldNotReachHere(); + } + } + } + + public final void evmovdqu64(Register dst, AMD64Address src) { + assert supports(CPUFeature.AVX512F); + assert dst.getRegisterCategory().equals(XMM); + evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_F3, M_0F, W1, Z0, B0); + emitByte(0x6F); + emitEVEXOperandHelper(dst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + public final void evpmovzxbw(Register dst, AMD64Address src) { + assert supports(CPUFeature.AVX512BW); + assert dst.getRegisterCategory().equals(XMM); + evexPrefix(dst, Register.None, Register.None, src, AVXSize.ZMM, P_66, M_0F38, WIG, Z0, B0); + emitByte(0x30); + emitEVEXOperandHelper(dst, src, 0, EVEXTuple.HVM.getDisp8ScalingFactor(AVXSize.ZMM)); + } + + public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src) { + assert supports(CPUFeature.AVX512BW); + assert kdst.getRegisterCategory().equals(MASK) && nds.getRegisterCategory().equals(XMM); + evexPrefix(kdst, Register.None, nds, src, AVXSize.ZMM, P_66, M_0F, WIG, Z0, B0); + emitByte(0x74); + emitEVEXOperandHelper(kdst, src, 0, EVEXTuple.FVM.getDisp8ScalingFactor(AVXSize.ZMM)); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64BaseAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,1077 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.asm.amd64; + +import static jdk.vm.ci.amd64.AMD64.MASK; +import static jdk.vm.ci.amd64.AMD64.XMM; +import static jdk.vm.ci.amd64.AMD64.r12; +import static jdk.vm.ci.amd64.AMD64.r13; +import static jdk.vm.ci.amd64.AMD64.rbp; +import static jdk.vm.ci.amd64.AMD64.rsp; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.B1; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.L512; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.EVEXPrefixConfig.Z1; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L128; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.L256; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.LIG; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F38; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.M_0F3A; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_66; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F2; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.P_F3; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W0; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.W1; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.VEXPrefixConfig.WIG; +import static org.graalvm.compiler.core.common.NumUtil.isByte; + +import org.graalvm.compiler.asm.Assembler; +import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; +import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; +import org.graalvm.compiler.debug.GraalError; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.amd64.AMD64.CPUFeature; +import jdk.vm.ci.amd64.AMD64Kind; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.PlatformKind; + +/** + * This class implements an assembler that can encode most X86 instructions. + */ +public abstract class AMD64BaseAssembler extends Assembler { + + private final SIMDEncoder simdEncoder; + + /** + * Constructs an assembler for the AMD64 architecture. + */ + public AMD64BaseAssembler(TargetDescription target) { + super(target); + + if (supports(CPUFeature.AVX)) { + simdEncoder = new VEXEncoderImpl(); + } else { + simdEncoder = new SSEEncoderImpl(); + } + } + + /** + * The x86 operand sizes. + */ + public enum OperandSize { + BYTE(1, AMD64Kind.BYTE) { + @Override + protected void emitImmediate(AMD64BaseAssembler asm, int imm) { + assert imm == (byte) imm; + asm.emitByte(imm); + } + + @Override + protected int immediateSize() { + return 1; + } + }, + + WORD(2, AMD64Kind.WORD, 0x66) { + @Override + protected void emitImmediate(AMD64BaseAssembler asm, int imm) { + assert imm == (short) imm; + asm.emitShort(imm); + } + + @Override + protected int immediateSize() { + return 2; + } + }, + + DWORD(4, AMD64Kind.DWORD) { + @Override + protected void emitImmediate(AMD64BaseAssembler asm, int imm) { + asm.emitInt(imm); + } + + @Override + protected int immediateSize() { + return 4; + } + }, + + QWORD(8, AMD64Kind.QWORD) { + @Override + protected void emitImmediate(AMD64BaseAssembler asm, int imm) { + asm.emitInt(imm); + } + + @Override + protected int immediateSize() { + return 4; + } + }, + + SS(4, AMD64Kind.SINGLE, 0xF3, true), + + SD(8, AMD64Kind.DOUBLE, 0xF2, true), + + PS(16, AMD64Kind.V128_SINGLE, true), + + PD(16, AMD64Kind.V128_DOUBLE, 0x66, true); + + private final int sizePrefix; + private final int bytes; + private final boolean xmm; + private final AMD64Kind kind; + + OperandSize(int bytes, AMD64Kind kind) { + this(bytes, kind, 0); + } + + OperandSize(int bytes, AMD64Kind kind, int sizePrefix) { + this(bytes, kind, sizePrefix, false); + } + + OperandSize(int bytes, AMD64Kind kind, boolean xmm) { + this(bytes, kind, 0, xmm); + } + + OperandSize(int bytes, AMD64Kind kind, int sizePrefix, boolean xmm) { + this.sizePrefix = sizePrefix; + this.bytes = bytes; + this.kind = kind; + this.xmm = xmm; + } + + public int getSizePrefix() { + return sizePrefix; + } + + public int getBytes() { + return bytes; + } + + public boolean isXmmType() { + return xmm; + } + + public AMD64Kind getKind() { + return kind; + } + + public static OperandSize get(PlatformKind kind) { + for (OperandSize operandSize : OperandSize.values()) { + if (operandSize.kind.equals(kind)) { + return operandSize; + } + } + throw GraalError.shouldNotReachHere("Unexpected kind: " + kind.toString()); + } + + /** + * Emit an immediate of this size. Note that immediate {@link #QWORD} operands are encoded + * as sign-extended 32-bit values. + * + * @param asm + * @param imm + */ + protected void emitImmediate(AMD64BaseAssembler asm, int imm) { + throw new UnsupportedOperationException(); + } + + protected int immediateSize() { + throw new UnsupportedOperationException(); + } + } + + public abstract static class OperandDataAnnotation extends CodeAnnotation { + /** + * The position (bytes from the beginning of the method) of the operand. + */ + public final int operandPosition; + /** + * The size of the operand, in bytes. + */ + public final int operandSize; + /** + * The position (bytes from the beginning of the method) of the next instruction. On AMD64, + * RIP-relative operands are relative to this position. + */ + public final int nextInstructionPosition; + + OperandDataAnnotation(int instructionPosition, int operandPosition, int operandSize, int nextInstructionPosition) { + super(instructionPosition); + + this.operandPosition = operandPosition; + this.operandSize = operandSize; + this.nextInstructionPosition = nextInstructionPosition; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " instruction [" + instructionPosition + ", " + nextInstructionPosition + "[ operand at " + operandPosition + " size " + operandSize; + } + } + + /** + * Annotation that stores additional information about the displacement of a + * {@link Assembler#getPlaceholder placeholder address} that needs patching. + */ + protected static class AddressDisplacementAnnotation extends OperandDataAnnotation { + AddressDisplacementAnnotation(int instructionPosition, int operandPosition, int operandSize, int nextInstructionPosition) { + super(instructionPosition, operandPosition, operandSize, nextInstructionPosition); + } + } + + /** + * Annotation that stores additional information about the immediate operand, e.g., of a call + * instruction, that needs patching. + */ + protected static class ImmediateOperandAnnotation extends OperandDataAnnotation { + ImmediateOperandAnnotation(int instructionPosition, int operandPosition, int operandSize, int nextInstructionPosition) { + super(instructionPosition, operandPosition, operandSize, nextInstructionPosition); + } + } + + protected void annotatePatchingImmediate(int operandOffset, int operandSize) { + if (codePatchingAnnotationConsumer != null) { + int pos = position(); + codePatchingAnnotationConsumer.accept(new ImmediateOperandAnnotation(pos, pos + operandOffset, operandSize, pos + operandOffset + operandSize)); + } + } + + public final boolean supports(CPUFeature feature) { + return ((AMD64) target.arch).getFeatures().contains(feature); + } + + protected static int encode(Register r) { + assert r.encoding >= 0 && (r.getRegisterCategory().equals(XMM) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding; + return r.encoding & 0x7; + } + + private static final int MinEncodingNeedsRex = 8; + + /** + * Constants for X86 prefix bytes. + */ + private static class Prefix { + private static final int REX = 0x40; + private static final int REXB = 0x41; + private static final int REXX = 0x42; + private static final int REXXB = 0x43; + private static final int REXR = 0x44; + private static final int REXRB = 0x45; + private static final int REXRX = 0x46; + private static final int REXRXB = 0x47; + private static final int REXW = 0x48; + private static final int REXWB = 0x49; + private static final int REXWX = 0x4A; + private static final int REXWXB = 0x4B; + private static final int REXWR = 0x4C; + private static final int REXWRB = 0x4D; + private static final int REXWRX = 0x4E; + private static final int REXWRXB = 0x4F; + } + + protected final void rexw() { + emitByte(Prefix.REXW); + } + + protected final void prefix(Register reg) { + prefix(reg, false); + } + + protected final void prefix(Register reg, boolean byteinst) { + int regEnc = reg.encoding; + if (regEnc >= 8) { + emitByte(Prefix.REXB); + } else if (byteinst && regEnc >= 4) { + emitByte(Prefix.REX); + } + } + + protected final void prefixq(Register reg) { + if (reg.encoding < 8) { + emitByte(Prefix.REXW); + } else { + emitByte(Prefix.REXWB); + } + } + + protected final void prefix(Register dst, Register src) { + prefix(dst, false, src, false); + } + + protected final void prefix(Register dst, boolean dstIsByte, Register src, boolean srcIsByte) { + int dstEnc = dst.encoding; + int srcEnc = src.encoding; + if (dstEnc < 8) { + if (srcEnc >= 8) { + emitByte(Prefix.REXB); + } else if ((srcIsByte && srcEnc >= 4) || (dstIsByte && dstEnc >= 4)) { + emitByte(Prefix.REX); + } + } else { + if (srcEnc < 8) { + emitByte(Prefix.REXR); + } else { + emitByte(Prefix.REXRB); + } + } + } + + /** + * Creates prefix for the operands. If the given operands exceed 3 bits, the 4th bit is encoded + * in the prefix. + */ + protected final void prefixq(Register reg, Register rm) { + int regEnc = reg.encoding; + int rmEnc = rm.encoding; + if (regEnc < 8) { + if (rmEnc < 8) { + emitByte(Prefix.REXW); + } else { + emitByte(Prefix.REXWB); + } + } else { + if (rmEnc < 8) { + emitByte(Prefix.REXWR); + } else { + emitByte(Prefix.REXWRB); + } + } + } + + private static boolean needsRex(Register reg) { + return reg.encoding >= MinEncodingNeedsRex; + } + + protected final void prefix(AMD64Address adr) { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXXB); + } else { + emitByte(Prefix.REXB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXX); + } + } + } + + protected final void prefixq(AMD64Address adr) { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWXB); + } else { + emitByte(Prefix.REXWB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWX); + } else { + emitByte(Prefix.REXW); + } + } + } + + protected void prefixb(AMD64Address adr, Register reg) { + prefix(adr, reg, true); + } + + protected void prefix(AMD64Address adr, Register reg) { + prefix(adr, reg, false); + } + + protected void prefix(AMD64Address adr, Register reg, boolean byteinst) { + if (reg.encoding < 8) { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXXB); + } else { + emitByte(Prefix.REXB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXX); + } else if (byteinst && reg.encoding >= 4) { + emitByte(Prefix.REX); + } + } + } else { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXRXB); + } else { + emitByte(Prefix.REXRB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXRX); + } else { + emitByte(Prefix.REXR); + } + } + } + } + + protected void prefixq(AMD64Address adr, Register src) { + if (src.encoding < 8) { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWXB); + } else { + emitByte(Prefix.REXWB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWX); + } else { + emitByte(Prefix.REXW); + } + } + } else { + if (needsRex(adr.getBase())) { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWRXB); + } else { + emitByte(Prefix.REXWRB); + } + } else { + if (needsRex(adr.getIndex())) { + emitByte(Prefix.REXWRX); + } else { + emitByte(Prefix.REXWR); + } + } + } + } + + /** + * Get RXB bits for register-register instruction. In that encoding, ModRM.rm contains a + * register index. The R bit extends the ModRM.reg field and the B bit extends the ModRM.rm + * field. The X bit must be 0. + */ + protected static int getRXB(Register reg, Register rm) { + int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; + rxb |= (rm == null ? 0 : rm.encoding & 0x08) >> 3; + return rxb; + } + + /** + * Get RXB bits for register-memory instruction. The R bit extends the ModRM.reg field. There + * are two cases for the memory operand:
+ * ModRM.rm contains the base register: In that case, B extends the ModRM.rm field and X = 0. + *
+ * There is an SIB byte: In that case, X extends SIB.index and B extends SIB.base. + */ + protected static int getRXB(Register reg, AMD64Address rm) { + int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; + if (!rm.getIndex().equals(Register.None)) { + rxb |= (rm.getIndex().encoding & 0x08) >> 2; + } + if (!rm.getBase().equals(Register.None)) { + rxb |= (rm.getBase().encoding & 0x08) >> 3; + } + return rxb; + } + + /** + * Emit the ModR/M byte for one register operand and an opcode extension in the R field. + *

+ * Format: [ 11 reg r/m ] + */ + protected final void emitModRM(int reg, Register rm) { + assert (reg & 0x07) == reg; + emitByte(0xC0 | (reg << 3) | (rm.encoding & 0x07)); + } + + /** + * Emit the ModR/M byte for two register operands. + *

+ * Format: [ 11 reg r/m ] + */ + protected final void emitModRM(Register reg, Register rm) { + emitModRM(reg.encoding & 0x07, rm); + } + + /** + * Emits the ModR/M byte and optionally the SIB byte for one register and one memory operand. + * + * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte + */ + protected final void emitOperandHelper(Register reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize) { + assert !reg.equals(Register.None); + emitOperandHelper(encode(reg), addr, force4Byte, additionalInstructionSize, 1); + } + + protected final void emitOperandHelper(int reg, AMD64Address addr, int additionalInstructionSize) { + emitOperandHelper(reg, addr, false, additionalInstructionSize, 1); + } + + protected final void emitOperandHelper(Register reg, AMD64Address addr, int additionalInstructionSize) { + assert !reg.equals(Register.None); + emitOperandHelper(encode(reg), addr, false, additionalInstructionSize, 1); + } + + protected final void emitEVEXOperandHelper(Register reg, AMD64Address addr, int additionalInstructionSize, int evexDisp8Scale) { + assert !reg.equals(Register.None); + emitOperandHelper(encode(reg), addr, false, additionalInstructionSize, evexDisp8Scale); + } + + /** + * Emits the ModR/M byte and optionally the SIB byte for one memory operand and an opcode + * extension in the R field. + * + * @param force4Byte use 4 byte encoding for displacements that would normally fit in a byte + * @param additionalInstructionSize the number of bytes that will be emitted after the operand, + * so that the start position of the next instruction can be computed even though + * this instruction has not been completely emitted yet. + * @param evexDisp8Scale the scaling factor for computing the compressed displacement of + * EVEX-encoded instructions. This scaling factor only matters when the emitted + * instruction uses one-byte-displacement form. + */ + private void emitOperandHelper(int reg, AMD64Address addr, boolean force4Byte, int additionalInstructionSize, int evexDisp8Scale) { + assert (reg & 0x07) == reg; + int regenc = reg << 3; + + Register base = addr.getBase(); + Register index = addr.getIndex(); + + Scale scale = addr.getScale(); + int disp = addr.getDisplacement(); + + if (base.equals(AMD64.rip)) { // also matches addresses returned by getPlaceholder() + // [00 000 101] disp32 + assert index.equals(Register.None) : "cannot use RIP relative addressing with index register"; + emitByte(0x05 | regenc); + if (codePatchingAnnotationConsumer != null && addr.instructionStartPosition >= 0) { + codePatchingAnnotationConsumer.accept(new AddressDisplacementAnnotation(addr.instructionStartPosition, position(), 4, position() + 4 + additionalInstructionSize)); + } + emitInt(disp); + } else if (base.isValid()) { + boolean overriddenForce4Byte = force4Byte; + int baseenc = base.isValid() ? encode(base) : 0; + + if (index.isValid()) { + int indexenc = encode(index) << 3; + // [base + indexscale + disp] + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { + // [base + indexscale] + // [00 reg 100][ss index base] + assert !index.equals(rsp) : "illegal addressing mode"; + emitByte(0x04 | regenc); + emitByte(scale.log2 << 6 | indexenc | baseenc); + } else { + if (evexDisp8Scale > 1 && !overriddenForce4Byte) { + if (disp % evexDisp8Scale == 0) { + int newDisp = disp / evexDisp8Scale; + if (isByte(newDisp)) { + disp = newDisp; + assert isByte(disp) && !overriddenForce4Byte; + } + } else { + overriddenForce4Byte = true; + } + } + if (isByte(disp) && !overriddenForce4Byte) { + // [base + indexscale + imm8] + // [01 reg 100][ss index base] imm8 + assert !index.equals(rsp) : "illegal addressing mode"; + emitByte(0x44 | regenc); + emitByte(scale.log2 << 6 | indexenc | baseenc); + emitByte(disp & 0xFF); + } else { + // [base + indexscale + disp32] + // [10 reg 100][ss index base] disp32 + assert !index.equals(rsp) : "illegal addressing mode"; + emitByte(0x84 | regenc); + emitByte(scale.log2 << 6 | indexenc | baseenc); + emitInt(disp); + } + } + } else if (base.equals(rsp) || base.equals(r12)) { + // [rsp + disp] + if (disp == 0) { + // [rsp] + // [00 reg 100][00 100 100] + emitByte(0x04 | regenc); + emitByte(0x24); + } else { + if (evexDisp8Scale > 1 && !overriddenForce4Byte) { + if (disp % evexDisp8Scale == 0) { + int newDisp = disp / evexDisp8Scale; + if (isByte(newDisp)) { + disp = newDisp; + assert isByte(disp) && !overriddenForce4Byte; + } + } else { + overriddenForce4Byte = true; + } + } + if (isByte(disp) && !overriddenForce4Byte) { + // [rsp + imm8] + // [01 reg 100][00 100 100] disp8 + emitByte(0x44 | regenc); + emitByte(0x24); + emitByte(disp & 0xFF); + } else { + // [rsp + imm32] + // [10 reg 100][00 100 100] disp32 + emitByte(0x84 | regenc); + emitByte(0x24); + emitInt(disp); + } + } + } else { + // [base + disp] + assert !base.equals(rsp) && !base.equals(r12) : "illegal addressing mode"; + if (disp == 0 && !base.equals(rbp) && !base.equals(r13)) { + // [base] + // [00 reg base] + emitByte(0x00 | regenc | baseenc); + } else { + if (evexDisp8Scale > 1 && !overriddenForce4Byte) { + if (disp % evexDisp8Scale == 0) { + int newDisp = disp / evexDisp8Scale; + if (isByte(newDisp)) { + disp = newDisp; + assert isByte(disp) && !overriddenForce4Byte; + } + } else { + overriddenForce4Byte = true; + } + } + if (isByte(disp) && !overriddenForce4Byte) { + // [base + disp8] + // [01 reg base] disp8 + emitByte(0x40 | regenc | baseenc); + emitByte(disp & 0xFF); + } else { + // [base + disp32] + // [10 reg base] disp32 + emitByte(0x80 | regenc | baseenc); + emitInt(disp); + } + } + } + } else { + if (index.isValid()) { + int indexenc = encode(index) << 3; + // [indexscale + disp] + // [00 reg 100][ss index 101] disp32 + assert !index.equals(rsp) : "illegal addressing mode"; + emitByte(0x04 | regenc); + emitByte(scale.log2 << 6 | indexenc | 0x05); + emitInt(disp); + } else { + // [disp] ABSOLUTE + // [00 reg 100][00 100 101] disp32 + emitByte(0x04 | regenc); + emitByte(0x25); + emitInt(disp); + } + } + } + + private interface SIMDEncoder { + + void simdPrefix(Register xreg, Register nds, AMD64Address adr, int sizePrefix, int opcodeEscapePrefix, boolean isRexW); + + void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW); + + } + + private class SSEEncoderImpl implements SIMDEncoder { + + @Override + public void simdPrefix(Register xreg, Register nds, AMD64Address adr, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { + if (sizePrefix > 0) { + emitByte(sizePrefix); + } + if (isRexW) { + prefixq(adr, xreg); + } else { + prefix(adr, xreg); + } + if (opcodeEscapePrefix > 0xFF) { + emitShort(opcodeEscapePrefix); + } else if (opcodeEscapePrefix > 0) { + emitByte(opcodeEscapePrefix); + } + } + + @Override + public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { + if (sizePrefix > 0) { + emitByte(sizePrefix); + } + if (isRexW) { + prefixq(dst, src); + } else { + prefix(dst, src); + } + if (opcodeEscapePrefix > 0xFF) { + emitShort(opcodeEscapePrefix); + } else if (opcodeEscapePrefix > 0) { + emitByte(opcodeEscapePrefix); + } + } + } + + public static final class VEXPrefixConfig { + public static final int L128 = 0; + public static final int L256 = 1; + public static final int LIG = 0; + + public static final int W0 = 0; + public static final int W1 = 1; + public static final int WIG = 0; + + public static final int P_ = 0x0; + public static final int P_66 = 0x1; + public static final int P_F3 = 0x2; + public static final int P_F2 = 0x3; + + public static final int M_0F = 0x1; + public static final int M_0F38 = 0x2; + public static final int M_0F3A = 0x3; + + private VEXPrefixConfig() { + } + } + + private class VEXEncoderImpl implements SIMDEncoder { + + private int sizePrefixToPP(int sizePrefix) { + switch (sizePrefix) { + case 0x66: + return P_66; + case 0xF2: + return P_F2; + case 0xF3: + return P_F3; + default: + return P_; + } + } + + private int opcodeEscapePrefixToMMMMM(int opcodeEscapePrefix) { + switch (opcodeEscapePrefix) { + case 0x0F: + return M_0F; + case 0x380F: + return M_0F38; + case 0x3A0F: + return M_0F3A; + default: + return 0; + } + } + + @Override + public void simdPrefix(Register reg, Register nds, AMD64Address rm, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { + emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0); + } + + @Override + public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) { + emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0); + } + } + + protected final void simdPrefix(Register xreg, Register nds, AMD64Address adr, OperandSize size, int overriddenSizePrefix, int opcodeEscapePrefix, boolean isRexW) { + simdEncoder.simdPrefix(xreg, nds, adr, overriddenSizePrefix != 0 ? overriddenSizePrefix : size.sizePrefix, opcodeEscapePrefix, isRexW); + } + + protected final void simdPrefix(Register xreg, Register nds, AMD64Address adr, OperandSize size, int opcodeEscapePrefix, boolean isRexW) { + simdEncoder.simdPrefix(xreg, nds, adr, size.sizePrefix, opcodeEscapePrefix, isRexW); + } + + protected final void simdPrefix(Register dst, Register nds, Register src, OperandSize size, int overriddenSizePrefix, int opcodeEscapePrefix, boolean isRexW) { + simdEncoder.simdPrefix(dst, nds, src, overriddenSizePrefix != 0 ? overriddenSizePrefix : size.sizePrefix, opcodeEscapePrefix, isRexW); + } + + protected final void simdPrefix(Register dst, Register nds, Register src, OperandSize size, int opcodeEscapePrefix, boolean isRexW) { + simdEncoder.simdPrefix(dst, nds, src, size.sizePrefix, opcodeEscapePrefix, isRexW); + } + + /** + * Low-level function to encode and emit the VEX prefix. + *

+ * 2 byte form: [1100 0101] [R vvvv L pp]
+ * 3 byte form: [1100 0100] [RXB m-mmmm] [W vvvv L pp] + *

+ * The RXB and vvvv fields are stored in 1's complement in the prefix encoding. This function + * performs the 1s complement conversion, the caller is expected to pass plain unencoded + * arguments. + *

+ * The pp field encodes an extension to the opcode:
+ * 00: no extension
+ * 01: 66
+ * 10: F3
+ * 11: F2 + *

+ * The m-mmmm field encodes the leading bytes of the opcode:
+ * 00001: implied 0F leading opcode byte (default in 2-byte encoding)
+ * 00010: implied 0F 38 leading opcode bytes
+ * 00011: implied 0F 3A leading opcode bytes + *

+ * This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the + * m-mmmm field. + */ + protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv) { + assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support"; + + assert l == L128 || l == L256 || l == LIG : "invalid value for VEX.L"; + assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp"; + assert mmmmm == M_0F || mmmmm == M_0F38 || mmmmm == M_0F3A : "invalid value for VEX.m-mmmm"; + assert w == W0 || w == W1 || w == WIG : "invalid value for VEX.W"; + + assert (rxb & 0x07) == rxb : "invalid value for VEX.RXB"; + assert (vvvv & 0x0F) == vvvv : "invalid value for VEX.vvvv"; + + int rxb1s = rxb ^ 0x07; + int vvvv1s = vvvv ^ 0x0F; + if ((rxb & 0x03) == 0 && w == WIG && mmmmm == M_0F) { + // 2 byte encoding + int byte2 = 0; + byte2 |= (rxb1s & 0x04) << 5; + byte2 |= vvvv1s << 3; + byte2 |= l << 2; + byte2 |= pp; + + emitByte(0xC5); + emitByte(byte2); + } else { + // 3 byte encoding + int byte2 = 0; + byte2 = (rxb1s & 0x07) << 5; + byte2 |= mmmmm; + + int byte3 = 0; + byte3 |= w << 7; + byte3 |= vvvv1s << 3; + byte3 |= l << 2; + byte3 |= pp; + + emitByte(0xC4); + emitByte(byte2); + emitByte(byte3); + } + } + + private static int getLFlag(AVXSize size) { + switch (size) { + case XMM: + return L128; + case YMM: + return L256; + case ZMM: + return L512; + default: + return LIG; + } + } + + public final void vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w) { + emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0); + } + + public final void vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w) { + emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0); + } + + protected static final class EVEXPrefixConfig { + public static final int L512 = 2; + + public static final int Z0 = 0x0; + public static final int Z1 = 0x1; + + public static final int B0 = 0x0; + public static final int B1 = 0x1; + + private EVEXPrefixConfig() { + } + } + + private static final int NOT_SUPPORTED_VECTOR_LENGTH = -1; + + /** + * EVEX-encoded instructions use a compressed displacement scheme by multiplying disp8 with a + * scaling factor N depending on the tuple type and the vector length. + * + * Reference: Intel Software Developer's Manual Volume 2, Section 2.6.5 + */ + protected enum EVEXTuple { + FV_NO_BROADCAST_32BIT(16, 32, 64), + FV_BROADCAST_32BIT(4, 4, 4), + FV_NO_BROADCAST_64BIT(16, 32, 64), + FV_BROADCAST_64BIT(8, 8, 8), + HV_NO_BROADCAST_32BIT(8, 16, 32), + HV_BROADCAST_32BIT(4, 4, 4), + FVM(16, 32, 64), + T1S_8BIT(1, 1, 1), + T1S_16BIT(2, 2, 2), + T1S_32BIT(4, 4, 4), + T1S_64BIT(8, 8, 8), + T1F_32BIT(4, 4, 4), + T1F_64BIT(8, 8, 8), + T2_32BIT(8, 8, 8), + T2_64BIT(NOT_SUPPORTED_VECTOR_LENGTH, 16, 16), + T4_32BIT(NOT_SUPPORTED_VECTOR_LENGTH, 16, 16), + T4_64BIT(NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH, 32), + T8_32BIT(NOT_SUPPORTED_VECTOR_LENGTH, NOT_SUPPORTED_VECTOR_LENGTH, 32), + HVM(8, 16, 32), + QVM(4, 8, 16), + OVM(2, 4, 8), + M128(16, 16, 16), + DUP(8, 32, 64); + + private final int scalingFactorVL128; + private final int scalingFactorVL256; + private final int scalingFactorVL512; + + EVEXTuple(int scalingFactorVL128, int scalingFactorVL256, int scalingFactorVL512) { + this.scalingFactorVL128 = scalingFactorVL128; + this.scalingFactorVL256 = scalingFactorVL256; + this.scalingFactorVL512 = scalingFactorVL512; + } + + private static int verifyScalingFactor(int scalingFactor) { + if (scalingFactor == NOT_SUPPORTED_VECTOR_LENGTH) { + throw GraalError.shouldNotReachHere("Invalid scaling factor."); + } + return scalingFactor; + } + + public int getDisp8ScalingFactor(AVXSize size) { + switch (size) { + case XMM: + return verifyScalingFactor(scalingFactorVL128); + case YMM: + return verifyScalingFactor(scalingFactorVL256); + case ZMM: + return verifyScalingFactor(scalingFactorVL512); + default: + throw GraalError.shouldNotReachHere("Unsupported vector size."); + } + } + } + + /** + * Low-level function to encode and emit the EVEX prefix. + *

+ * 62 [0 1 1 0 0 0 1 0]
+ * P1 [R X B R'0 0 m m]
+ * P2 [W v v v v 1 p p]
+ * P3 [z L'L b V'a a a] + *

+ * The pp field encodes an extension to the opcode:
+ * 00: no extension
+ * 01: 66
+ * 10: F3
+ * 11: F2 + *

+ * The mm field encodes the leading bytes of the opcode:
+ * 01: implied 0F leading opcode byte
+ * 10: implied 0F 38 leading opcode bytes
+ * 11: implied 0F 3A leading opcode bytes + *

+ * The z field encodes the merging mode (merge or zero). + *

+ * The b field encodes the source broadcast or data rounding modes. + *

+ * The aaa field encodes the operand mask register. + */ + private void emitEVEX(int l, int pp, int mm, int w, int rxb, int reg, int vvvvv, int z, int b, int aaa) { + assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX512F) : "emitting EVEX prefix on a CPU without AVX512 support"; + + assert l == L128 || l == L256 || l == L512 || l == LIG : "invalid value for EVEX.L'L"; + assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for EVEX.pp"; + assert mm == M_0F || mm == M_0F38 || mm == M_0F3A : "invalid value for EVEX.mm"; + assert w == W0 || w == W1 || w == WIG : "invalid value for EVEX.W"; + + assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB"; + assert (reg & 0x1F) == reg : "invalid value for EVEX.R'"; + assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.vvvvv"; + + assert z == Z0 || z == Z1 : "invalid value for EVEX.z"; + assert b == B0 || b == B1 : "invalid value for EVEX.b"; + assert (aaa & 0x07) == aaa : "invalid value for EVEX.aaa"; + + emitByte(0x62); + int p1 = 0; + p1 |= ((rxb ^ 0x07) & 0x07) << 5; + p1 |= reg < 16 ? 0x10 : 0; + p1 |= mm; + emitByte(p1); + + int p2 = 0; + p2 |= w << 7; + p2 |= ((vvvvv ^ 0x0F) & 0x0F) << 3; + p2 |= 0x4; + p2 |= pp; + emitByte(p2); + + int p3 = 0; + p3 |= z << 7; + p3 |= l << 5; + p3 |= b << 4; + p3 |= vvvvv < 16 ? 0x08 : 0; + p3 |= aaa; + emitByte(p3); + } + + private static int getRXBForEVEX(Register reg, Register rm) { + int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1; + rxb |= (rm == null ? 0 : rm.encoding & 0x018) >> 3; + return rxb; + } + + /** + * Helper method for emitting EVEX prefix in the form of RRRR. + */ + protected final void evexPrefix(Register dst, Register mask, Register nds, Register src, AVXSize size, int pp, int mm, int w, int z, int b) { + assert !mask.isValid() || mask.getRegisterCategory().equals(MASK); + emitEVEX(getLFlag(size), pp, mm, w, getRXBForEVEX(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0); + } + + /** + * Helper method for emitting EVEX prefix in the form of RRRM. Because the memory addressing in + * EVEX-encoded instructions employ a compressed displacement scheme when using disp8 form, the + * user of this API should make sure to encode the operands using + * {@link #emitEVEXOperandHelper(Register, AMD64Address, int, int)}. + */ + protected final void evexPrefix(Register dst, Register mask, Register nds, AMD64Address src, AVXSize size, int pp, int mm, int w, int z, int b) { + assert !mask.isValid() || mask.getRegisterCategory().equals(MASK); + emitEVEX(getLFlag(size), pp, mm, w, getRXB(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0); + } + +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64InstructionAttr.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64InstructionAttr.java Fri Aug 17 11:56:59 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package org.graalvm.compiler.asm.amd64; - -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; -import jdk.vm.ci.code.TargetDescription; - -/** - * Attributes for instructions for SSE through EVEX, also including address components. - */ -public class AMD64InstructionAttr { - AMD64InstructionAttr( - int inVectorLen, - boolean inRexVexW, - boolean inLegacyMode, - boolean inNoRegMask, - boolean inUsesVl, - TargetDescription target) { - avxVectorLen = inVectorLen; - rexVexW = inRexVexW; - this.target = target; - legacyMode = (!supports(CPUFeature.AVX512F)) ? true : inLegacyMode; - noRegMask = inNoRegMask; - usesVl = inUsesVl; - rexVexWReverted = false; - tupleType = 0; - inputSizeInBits = 0; - isEvexInstruction = false; - evexEncoding = 0; - isClearContext = false; - isExtendedContext = false; - } - - private TargetDescription target; - private int avxVectorLen; - private boolean rexVexW; - private boolean rexVexWReverted; - private boolean legacyMode; - private boolean noRegMask; - private boolean usesVl; - private int tupleType; - private int inputSizeInBits; - private boolean isEvexInstruction; - private int evexEncoding; - private boolean isClearContext; - private boolean isExtendedContext; - - public int getVectorLen() { - return avxVectorLen; - } - - public boolean isRexVexW() { - return rexVexW; - } - - public boolean isRexVexWReverted() { - return rexVexWReverted; - } - - public boolean isLegacyMode() { - return legacyMode; - } - - public boolean isNoRegMask() { - return noRegMask; - } - - public boolean usesVl() { - return usesVl; - } - - public int getTupleType() { - return tupleType; - } - - public int getInputSize() { - return inputSizeInBits; - } - - public boolean isEvexInstruction() { - return isEvexInstruction; - } - - public int getEvexEncoding() { - return evexEncoding; - } - - public boolean isClearContext() { - return isClearContext; - } - - public boolean isExtendedContext() { - return isExtendedContext; - } - - /** - * Set the vector length of a given instruction. - * - * @param vectorLen - */ - public void setVectorLen(int vectorLen) { - avxVectorLen = vectorLen; - } - - /** - * In EVEX it is possible in blended code generation to revert the encoding width for AVX. - */ - public void setRexVexWReverted() { - rexVexWReverted = true; - } - - /** - * Alter the current encoding width. - * - * @param state - */ - public void setRexVexW(boolean state) { - rexVexW = state; - } - - /** - * Alter the current instructions legacy mode. Blended code generation will use this. - */ - public void setLegacyMode() { - legacyMode = true; - } - - /** - * During emit or during definition of an instruction, mark if it is EVEX. - */ - public void setIsEvexInstruction() { - isEvexInstruction = true; - } - - /** - * Set the current encoding attributes to be used in address calculations for EVEX. - * - * @param value - */ - public void setEvexEncoding(int value) { - evexEncoding = value; - } - - /** - * Use clear context for this instruction in EVEX, defaults is merge(false). - */ - public void setIsClearContext() { - isClearContext = true; - } - - /** - * Set the address attributes for configuring displacement calculations in EVEX. - */ - public void setAddressAttributes(int inTupleType, int inInputSizeInBits) { - if (supports(CPUFeature.AVX512F)) { - tupleType = inTupleType; - inputSizeInBits = inInputSizeInBits; - } - } - - private boolean supports(CPUFeature feature) { - return ((AMD64) target.arch).getFeatures().contains(feature); - } -} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,16 +24,10 @@ package org.graalvm.compiler.asm.amd64; -import static jdk.vm.ci.amd64.AMD64.rax; -import static jdk.vm.ci.amd64.AMD64.rcx; -import static jdk.vm.ci.amd64.AMD64.rdx; -import static jdk.vm.ci.amd64.AMD64.rsp; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIncDec; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmLoadAndClearUpper; import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll; -import org.graalvm.compiler.asm.Label; -import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; import org.graalvm.compiler.core.common.NumUtil; import jdk.vm.ci.amd64.AMD64; @@ -280,7 +274,6 @@ movl(dst, (int) (src & 0xFFFFFFFF)); movl(high, (int) (src >> 32)); } - } public final void setl(ConditionFlag cc, Register dst) { @@ -344,433 +337,4 @@ addq(AMD64.rsp, AMD64Kind.DOUBLE.getSizeInBytes()); } - // IndexOf for constant substrings with size >= 8 chars - // which don't need to be loaded through stack. - public void stringIndexofC8(Register str1, Register str2, - Register cnt1, Register cnt2, - int intCnt2, Register result, - Register vec, Register tmp) { - // assert(UseSSE42Intrinsics, "SSE4.2 is required"); - - // This method uses pcmpestri inxtruction with bound registers - // inputs: - // xmm - substring - // rax - substring length (elements count) - // mem - scanned string - // rdx - string length (elements count) - // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) - // outputs: - // rcx - matched index in string - assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; - - Label reloadSubstr = new Label(); - Label scanToSubstr = new Label(); - Label scanSubstr = new Label(); - Label retFound = new Label(); - Label retNotFound = new Label(); - Label exit = new Label(); - Label foundSubstr = new Label(); - Label matchSubstrHead = new Label(); - Label reloadStr = new Label(); - Label foundCandidate = new Label(); - - // Note, inline_string_indexOf() generates checks: - // if (substr.count > string.count) return -1; - // if (substr.count == 0) return 0; - assert intCnt2 >= 8 : "this code isused only for cnt2 >= 8 chars"; - - // Load substring. - movdqu(vec, new AMD64Address(str2, 0)); - movl(cnt2, intCnt2); - movq(result, str1); // string addr - - if (intCnt2 > 8) { - jmpb(scanToSubstr); - - // Reload substr for rescan, this code - // is executed only for large substrings (> 8 chars) - bind(reloadSubstr); - movdqu(vec, new AMD64Address(str2, 0)); - negq(cnt2); // Jumped here with negative cnt2, convert to positive - - bind(reloadStr); - // We came here after the beginning of the substring was - // matched but the rest of it was not so we need to search - // again. Start from the next element after the previous match. - - // cnt2 is number of substring reminding elements and - // cnt1 is number of string reminding elements when cmp failed. - // Restored cnt1 = cnt1 - cnt2 + int_cnt2 - subl(cnt1, cnt2); - addl(cnt1, intCnt2); - movl(cnt2, intCnt2); // Now restore cnt2 - - decrementl(cnt1, 1); // Shift to next element - cmpl(cnt1, cnt2); - jccb(ConditionFlag.Negative, retNotFound); // Left less then substring - - addq(result, 2); - - } // (int_cnt2 > 8) - - // Scan string for start of substr in 16-byte vectors - bind(scanToSubstr); - pcmpestri(vec, new AMD64Address(result, 0), 0x0d); - jccb(ConditionFlag.Below, foundCandidate); // CF == 1 - subl(cnt1, 8); - jccb(ConditionFlag.LessEqual, retNotFound); // Scanned full string - cmpl(cnt1, cnt2); - jccb(ConditionFlag.Negative, retNotFound); // Left less then substring - addq(result, 16); - jmpb(scanToSubstr); - - // Found a potential substr - bind(foundCandidate); - // Matched whole vector if first element matched (tmp(rcx) == 0). - if (intCnt2 == 8) { - jccb(ConditionFlag.Overflow, retFound); // OF == 1 - } else { // int_cnt2 > 8 - jccb(ConditionFlag.Overflow, foundSubstr); - } - // After pcmpestri tmp(rcx) contains matched element index - // Compute start addr of substr - leaq(result, new AMD64Address(result, tmp, Scale.Times2, 0)); - - // Make sure string is still long enough - subl(cnt1, tmp); - cmpl(cnt1, cnt2); - if (intCnt2 == 8) { - jccb(ConditionFlag.GreaterEqual, scanToSubstr); - } else { // int_cnt2 > 8 - jccb(ConditionFlag.GreaterEqual, matchSubstrHead); - } - // Left less then substring. - - bind(retNotFound); - movl(result, -1); - jmpb(exit); - - if (intCnt2 > 8) { - // This code is optimized for the case when whole substring - // is matched if its head is matched. - bind(matchSubstrHead); - pcmpestri(vec, new AMD64Address(result, 0), 0x0d); - // Reload only string if does not match - jccb(ConditionFlag.NoOverflow, reloadStr); // OF == 0 - - Label contScanSubstr = new Label(); - // Compare the rest of substring (> 8 chars). - bind(foundSubstr); - // First 8 chars are already matched. - negq(cnt2); - addq(cnt2, 8); - - bind(scanSubstr); - subl(cnt1, 8); - cmpl(cnt2, -8); // Do not read beyond substring - jccb(ConditionFlag.LessEqual, contScanSubstr); - // Back-up strings to avoid reading beyond substring: - // cnt1 = cnt1 - cnt2 + 8 - addl(cnt1, cnt2); // cnt2 is negative - addl(cnt1, 8); - movl(cnt2, 8); - negq(cnt2); - bind(contScanSubstr); - if (intCnt2 < 1024 * 1024 * 1024) { - movdqu(vec, new AMD64Address(str2, cnt2, Scale.Times2, intCnt2 * 2)); - pcmpestri(vec, new AMD64Address(result, cnt2, Scale.Times2, intCnt2 * 2), 0x0d); - } else { - // calculate index in register to avoid integer overflow (int_cnt2*2) - movl(tmp, intCnt2); - addq(tmp, cnt2); - movdqu(vec, new AMD64Address(str2, tmp, Scale.Times2, 0)); - pcmpestri(vec, new AMD64Address(result, tmp, Scale.Times2, 0), 0x0d); - } - // Need to reload strings pointers if not matched whole vector - jcc(ConditionFlag.NoOverflow, reloadSubstr); // OF == 0 - addq(cnt2, 8); - jcc(ConditionFlag.Negative, scanSubstr); - // Fall through if found full substring - - } // (int_cnt2 > 8) - - bind(retFound); - // Found result if we matched full small substring. - // Compute substr offset - subq(result, str1); - shrl(result, 1); // index - bind(exit); - - } // string_indexofC8 - - // Small strings are loaded through stack if they cross page boundary. - public void stringIndexOf(Register str1, Register str2, - Register cnt1, Register cnt2, - int intCnt2, Register result, - Register vec, Register tmp, int vmPageSize) { - // - // int_cnt2 is length of small (< 8 chars) constant substring - // or (-1) for non constant substring in which case its length - // is in cnt2 register. - // - // Note, inline_string_indexOf() generates checks: - // if (substr.count > string.count) return -1; - // if (substr.count == 0) return 0; - // - assert intCnt2 == -1 || (0 < intCnt2 && intCnt2 < 8) : "should be != 0"; - - // This method uses pcmpestri instruction with bound registers - // inputs: - // xmm - substring - // rax - substring length (elements count) - // mem - scanned string - // rdx - string length (elements count) - // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) - // outputs: - // rcx - matched index in string - assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; - - Label reloadSubstr = new Label(); - Label scanToSubstr = new Label(); - Label scanSubstr = new Label(); - Label adjustStr = new Label(); - Label retFound = new Label(); - Label retNotFound = new Label(); - Label cleanup = new Label(); - Label foundSubstr = new Label(); - Label foundCandidate = new Label(); - - int wordSize = 8; - // We don't know where these strings are located - // and we can't read beyond them. Load them through stack. - Label bigStrings = new Label(); - Label checkStr = new Label(); - Label copySubstr = new Label(); - Label copyStr = new Label(); - - movq(tmp, rsp); // save old SP - - if (intCnt2 > 0) { // small (< 8 chars) constant substring - if (intCnt2 == 1) { // One char - movzwl(result, new AMD64Address(str2, 0)); - movdl(vec, result); // move 32 bits - } else if (intCnt2 == 2) { // Two chars - movdl(vec, new AMD64Address(str2, 0)); // move 32 bits - } else if (intCnt2 == 4) { // Four chars - movq(vec, new AMD64Address(str2, 0)); // move 64 bits - } else { // cnt2 = { 3, 5, 6, 7 } - // Array header size is 12 bytes in 32-bit VM - // + 6 bytes for 3 chars == 18 bytes, - // enough space to load vec and shift. - movdqu(vec, new AMD64Address(str2, (intCnt2 * 2) - 16)); - psrldq(vec, 16 - (intCnt2 * 2)); - } - } else { // not constant substring - cmpl(cnt2, 8); - jccb(ConditionFlag.AboveEqual, bigStrings); // Both strings are big enough - - // We can read beyond string if str+16 does not cross page boundary - // since heaps are aligned and mapped by pages. - assert vmPageSize < 1024 * 1024 * 1024 : "default page should be small"; - movl(result, str2); // We need only low 32 bits - andl(result, (vmPageSize - 1)); - cmpl(result, (vmPageSize - 16)); - jccb(ConditionFlag.BelowEqual, checkStr); - - // Move small strings to stack to allow load 16 bytes into vec. - subq(rsp, 16); - int stackOffset = wordSize - 2; - push(cnt2); - - bind(copySubstr); - movzwl(result, new AMD64Address(str2, cnt2, Scale.Times2, -2)); - movw(new AMD64Address(rsp, cnt2, Scale.Times2, stackOffset), result); - decrementl(cnt2, 1); - jccb(ConditionFlag.NotZero, copySubstr); - - pop(cnt2); - movq(str2, rsp); // New substring address - } // non constant - - bind(checkStr); - cmpl(cnt1, 8); - jccb(ConditionFlag.AboveEqual, bigStrings); - - // Check cross page boundary. - movl(result, str1); // We need only low 32 bits - andl(result, (vmPageSize - 1)); - cmpl(result, (vmPageSize - 16)); - jccb(ConditionFlag.BelowEqual, bigStrings); - - subq(rsp, 16); - int stackOffset = -2; - if (intCnt2 < 0) { // not constant - push(cnt2); - stackOffset += wordSize; - } - movl(cnt2, cnt1); - - bind(copyStr); - movzwl(result, new AMD64Address(str1, cnt2, Scale.Times2, -2)); - movw(new AMD64Address(rsp, cnt2, Scale.Times2, stackOffset), result); - decrementl(cnt2, 1); - jccb(ConditionFlag.NotZero, copyStr); - - if (intCnt2 < 0) { // not constant - pop(cnt2); - } - movq(str1, rsp); // New string address - - bind(bigStrings); - // Load substring. - if (intCnt2 < 0) { // -1 - movdqu(vec, new AMD64Address(str2, 0)); - push(cnt2); // substr count - push(str2); // substr addr - push(str1); // string addr - } else { - // Small (< 8 chars) constant substrings are loaded already. - movl(cnt2, intCnt2); - } - push(tmp); // original SP - // Finished loading - - // ======================================================== - // Start search - // - - movq(result, str1); // string addr - - if (intCnt2 < 0) { // Only for non constant substring - jmpb(scanToSubstr); - - // SP saved at sp+0 - // String saved at sp+1*wordSize - // Substr saved at sp+2*wordSize - // Substr count saved at sp+3*wordSize - - // Reload substr for rescan, this code - // is executed only for large substrings (> 8 chars) - bind(reloadSubstr); - movq(str2, new AMD64Address(rsp, 2 * wordSize)); - movl(cnt2, new AMD64Address(rsp, 3 * wordSize)); - movdqu(vec, new AMD64Address(str2, 0)); - // We came here after the beginning of the substring was - // matched but the rest of it was not so we need to search - // again. Start from the next element after the previous match. - subq(str1, result); // Restore counter - shrl(str1, 1); - addl(cnt1, str1); - decrementl(cnt1); // Shift to next element - cmpl(cnt1, cnt2); - jccb(ConditionFlag.Negative, retNotFound); // Left less then substring - - addq(result, 2); - } // non constant - - // Scan string for start of substr in 16-byte vectors - bind(scanToSubstr); - assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; - pcmpestri(vec, new AMD64Address(result, 0), 0x0d); - jccb(ConditionFlag.Below, foundCandidate); // CF == 1 - subl(cnt1, 8); - jccb(ConditionFlag.LessEqual, retNotFound); // Scanned full string - cmpl(cnt1, cnt2); - jccb(ConditionFlag.Negative, retNotFound); // Left less then substring - addq(result, 16); - - bind(adjustStr); - cmpl(cnt1, 8); // Do not read beyond string - jccb(ConditionFlag.GreaterEqual, scanToSubstr); - // Back-up string to avoid reading beyond string. - leaq(result, new AMD64Address(result, cnt1, Scale.Times2, -16)); - movl(cnt1, 8); - jmpb(scanToSubstr); - - // Found a potential substr - bind(foundCandidate); - // After pcmpestri tmp(rcx) contains matched element index - - // Make sure string is still long enough - subl(cnt1, tmp); - cmpl(cnt1, cnt2); - jccb(ConditionFlag.GreaterEqual, foundSubstr); - // Left less then substring. - - bind(retNotFound); - movl(result, -1); - jmpb(cleanup); - - bind(foundSubstr); - // Compute start addr of substr - leaq(result, new AMD64Address(result, tmp, Scale.Times2)); - - if (intCnt2 > 0) { // Constant substring - // Repeat search for small substring (< 8 chars) - // from new point without reloading substring. - // Have to check that we don't read beyond string. - cmpl(tmp, 8 - intCnt2); - jccb(ConditionFlag.Greater, adjustStr); - // Fall through if matched whole substring. - } else { // non constant - assert intCnt2 == -1 : "should be != 0"; - - addl(tmp, cnt2); - // Found result if we matched whole substring. - cmpl(tmp, 8); - jccb(ConditionFlag.LessEqual, retFound); - - // Repeat search for small substring (<= 8 chars) - // from new point 'str1' without reloading substring. - cmpl(cnt2, 8); - // Have to check that we don't read beyond string. - jccb(ConditionFlag.LessEqual, adjustStr); - - Label checkNext = new Label(); - Label contScanSubstr = new Label(); - Label retFoundLong = new Label(); - // Compare the rest of substring (> 8 chars). - movq(str1, result); - - cmpl(tmp, cnt2); - // First 8 chars are already matched. - jccb(ConditionFlag.Equal, checkNext); - - bind(scanSubstr); - pcmpestri(vec, new AMD64Address(str1, 0), 0x0d); - // Need to reload strings pointers if not matched whole vector - jcc(ConditionFlag.NoOverflow, reloadSubstr); // OF == 0 - - bind(checkNext); - subl(cnt2, 8); - jccb(ConditionFlag.LessEqual, retFoundLong); // Found full substring - addq(str1, 16); - addq(str2, 16); - subl(cnt1, 8); - cmpl(cnt2, 8); // Do not read beyond substring - jccb(ConditionFlag.GreaterEqual, contScanSubstr); - // Back-up strings to avoid reading beyond substring. - leaq(str2, new AMD64Address(str2, cnt2, Scale.Times2, -16)); - leaq(str1, new AMD64Address(str1, cnt2, Scale.Times2, -16)); - subl(cnt1, cnt2); - movl(cnt2, 8); - addl(cnt1, 8); - bind(contScanSubstr); - movdqu(vec, new AMD64Address(str2, 0)); - jmpb(scanSubstr); - - bind(retFoundLong); - movq(str1, new AMD64Address(rsp, wordSize)); - } // non constant - - bind(retFound); - // Compute substr offset - subq(result, str1); - shrl(result, 1); // index - - bind(cleanup); - pop(rsp); // restore SP - - } - } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64VectorAssembler.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64VectorAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,853 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. - * 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 org.graalvm.compiler.asm.amd64; - -import java.util.EnumSet; - -import org.graalvm.compiler.core.common.calc.Condition; -import org.graalvm.compiler.debug.GraalError; - -import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; - -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; -import jdk.vm.ci.amd64.AMD64Kind; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.Register.RegisterCategory; -import jdk.vm.ci.code.TargetDescription; - -/** - * This class extends the AMD64 assembler with functions that emit instructions from the AVX - * extension. - */ -public class AMD64VectorAssembler extends AMD64MacroAssembler { - - public AMD64VectorAssembler(TargetDescription target) { - super(target); - assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); - } - - private static final int L128 = 0; - private static final int L256 = 1; - private static final int LIG = 0; - - private static final int W0 = 0; - private static final int W1 = 1; - private static final int WIG = 0; - - private static final int P_ = 0x0; - private static final int P_66 = 0x1; - private static final int P_F3 = 0x2; - private static final int P_F2 = 0x3; - - private static final int M_0F = 0x1; - private static final int M_0F38 = 0x2; - private static final int M_0F3A = 0x3; - - /** - * Low-level function to encode and emit the VEX prefix. - *

- * 2 byte form: [1100 0101] [R vvvv L pp]
- * 3 byte form: [1100 0100] [RXB m-mmmm] [W vvvv L pp] - *

- * The RXB and vvvv fields are stored in 1's complement in the prefix encoding. This function - * performs the 1s complement conversion, the caller is expected to pass plain unencoded - * arguments. - *

- * The pp field encodes an extension to the opcode:
- * 00: no extension
- * 01: 66
- * 10: F3
- * 11: F2 - *

- * The m-mmmm field encodes the leading bytes of the opcode:
- * 00001: implied 0F leading opcode byte (default in 2-byte encoding)
- * 00010: implied 0F 38 leading opcode bytes
- * 00011: implied 0F 3A leading opcode bytes - *

- * This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the - * m-mmmm field. - */ - private void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv) { - assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support"; - - assert l == L128 || l == L256 || l == LIG : "invalid value for VEX.L"; - assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp"; - assert mmmmm == M_0F || mmmmm == M_0F38 || mmmmm == M_0F3A : "invalid value for VEX.m-mmmm"; - assert w == W0 || w == W1 || w == WIG : "invalid value for VEX.W"; - - assert (rxb & 0x07) == rxb : "invalid value for VEX.RXB"; - assert (vvvv & 0x0F) == vvvv : "invalid value for VEX.vvvv"; - - int rxb1s = rxb ^ 0x07; - int vvvv1s = vvvv ^ 0x0F; - if ((rxb & 0x03) == 0 && w == WIG && mmmmm == M_0F) { - // 2 byte encoding - int byte2 = 0; - byte2 |= (rxb1s & 0x04) << 5; - byte2 |= vvvv1s << 3; - byte2 |= l << 2; - byte2 |= pp; - - emitByte(0xC5); - emitByte(byte2); - } else { - // 3 byte encoding - int byte2 = 0; - byte2 = (rxb1s & 0x07) << 5; - byte2 |= mmmmm; - - int byte3 = 0; - byte3 |= w << 7; - byte3 |= vvvv1s << 3; - byte3 |= l << 2; - byte3 |= pp; - - emitByte(0xC4); - emitByte(byte2); - emitByte(byte3); - } - } - - private static int getLFlag(AVXSize size) { - switch (size) { - case XMM: - return L128; - case YMM: - return L256; - default: - return LIG; - } - } - - /** - * Emit instruction with VEX prefix and two register operands. - *

- * Format: [VEX] [Opcode] [ModR/M] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, Register rm) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), 0); - emitByte(op); - emitModRM(reg, rm); - } - - /** - * Emit instruction with VEX prefix and three register operands. - *

- * Format: [VEX] [Opcode] [ModR/M] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, Register vvvv, Register rm) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), vvvv.encoding()); - emitByte(op); - emitModRM(reg, rm); - } - - /** - * Emit instruction with VEX prefix and four register operands. - *

- * Format: [VEX] [Opcode] [ModR/M] [Imm8[7:4]] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, Register vvvv, Register rm, Register imm8) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), vvvv.encoding()); - emitByte(op); - emitModRM(reg, rm); - emitByte(imm8.encoding() << 4); - } - - /** - * Emit instruction with VEX prefix and three register operands and one memory operand. - *

- * Format: [VEX] [Opcode] [ModR/M] [Imm8[7:4]] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, Register vvvv, AMD64Address rm, Register imm8, int additionalInstructionSize) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), vvvv.encoding()); - emitByte(op); - emitOperandHelper(reg, rm, additionalInstructionSize); - emitByte(imm8.encoding() << 4); - } - - /** - * Emit instruction with VEX prefix and two register operands and an opcode extension in the r - * field. - *

- * Format: [VEX] [Opcode] [ModR/M] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, int r, Register vvvv, Register rm) { - emitVEX(l, pp, mmmmm, w, getRXB(null, rm), vvvv.encoding()); - emitByte(op); - emitModRM(r, rm); - } - - /** - * Emit instruction with VEX prefix, one register operand and one memory operand. - *

- * Format: [VEX] [Opcode] [ModR/M] [SIB] [Disp] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, AMD64Address rm, int additionalInstructionSize) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), 0); - emitByte(op); - emitOperandHelper(reg, rm, additionalInstructionSize); - } - - /** - * Emit instruction with VEX prefix, two register operands and one memory operand. - *

- * Format: [VEX] [Opcode] [ModR/M] [SIB] [Disp] - */ - private void emitVexOp(int l, int pp, int mmmmm, int w, int op, Register reg, Register vvvv, AMD64Address rm, int additionalInstructionSize) { - emitVEX(l, pp, mmmmm, w, getRXB(reg, rm), vvvv.encoding()); - emitByte(op); - emitOperandHelper(reg, rm, additionalInstructionSize); - } - - private static final OpAssertion AVX1 = new OpAssertion(CPUFeature.AVX, CPUFeature.AVX); - private static final OpAssertion AVX1_2 = new OpAssertion(CPUFeature.AVX, CPUFeature.AVX2); - private static final OpAssertion AVX2 = new OpAssertion(CPUFeature.AVX2, CPUFeature.AVX2); - - private static final OpAssertion AVX1_128ONLY = new OpAssertion(CPUFeature.AVX, null); - private static final OpAssertion AVX1_256ONLY = new OpAssertion(null, CPUFeature.AVX); - private static final OpAssertion AVX2_256ONLY = new OpAssertion(null, CPUFeature.AVX2); - - private static final OpAssertion XMM_CPU = new OpAssertion(CPUFeature.AVX, null, AMD64.XMM, null, AMD64.CPU, null); - private static final OpAssertion XMM_XMM_CPU = new OpAssertion(CPUFeature.AVX, null, AMD64.XMM, AMD64.XMM, AMD64.CPU, null); - private static final OpAssertion CPU_XMM = new OpAssertion(CPUFeature.AVX, null, AMD64.CPU, null, AMD64.XMM, null); - - private static final class OpAssertion { - private final CPUFeature avx128feature; - private final CPUFeature avx256feature; - - private final RegisterCategory rCategory; - private final RegisterCategory vCategory; - private final RegisterCategory mCategory; - private final RegisterCategory imm8Category; - - private OpAssertion(CPUFeature avx128feature, CPUFeature avx256feature) { - this(avx128feature, avx256feature, AMD64.XMM, AMD64.XMM, AMD64.XMM, AMD64.XMM); - } - - private OpAssertion(CPUFeature avx128feature, CPUFeature avx256feature, RegisterCategory rCategory, RegisterCategory vCategory, RegisterCategory mCategory, RegisterCategory imm8Category) { - this.avx128feature = avx128feature; - this.avx256feature = avx256feature; - this.rCategory = rCategory; - this.vCategory = vCategory; - this.mCategory = mCategory; - this.imm8Category = imm8Category; - } - - public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m) { - return check(arch, size, r, v, m, null); - } - - public boolean check(AMD64 arch, AVXSize size, Register r, Register v, Register m, Register imm8) { - switch (size) { - case XMM: - assert avx128feature != null && arch.getFeatures().contains(avx128feature) : "emitting illegal 128 bit instruction"; - break; - case YMM: - assert avx256feature != null && arch.getFeatures().contains(avx256feature) : "emitting illegal 256 bit instruction"; - break; - } - if (r != null) { - assert r.getRegisterCategory().equals(rCategory); - } - if (v != null) { - assert v.getRegisterCategory().equals(vCategory); - } - if (m != null) { - assert m.getRegisterCategory().equals(mCategory); - } - if (imm8 != null) { - assert imm8.getRegisterCategory().equals(imm8Category); - } - return true; - } - - public boolean supports(EnumSet features, AVXSize avxSize) { - switch (avxSize) { - case XMM: - return features.contains(avx128feature); - case YMM: - return features.contains(avx256feature); - default: - throw GraalError.shouldNotReachHere(); - } - } - } - - /** - * Base class for VEX-encoded instructions. - */ - private static class VexOp { - protected final int pp; - protected final int mmmmm; - protected final int w; - protected final int op; - - private final String opcode; - protected final OpAssertion assertion; - - protected VexOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - this.pp = pp; - this.mmmmm = mmmmm; - this.w = w; - this.op = op; - this.opcode = opcode; - this.assertion = assertion; - } - - public boolean isSupported(AMD64VectorAssembler vasm, AMD64Kind kind) { - return assertion.supports(((AMD64) vasm.target.arch).getFeatures(), AVXKind.getRegisterSize(kind)); - } - - @Override - public String toString() { - return opcode; - } - } - - /** - * VEX-encoded instructions with an operand order of RM, but the M operand must be a register. - */ - public static class VexRROp extends VexOp { - // @formatter:off - public static final VexRROp VMASKMOVDQU = new VexRROp("VMASKMOVDQU", P_66, M_0F, WIG, 0xF7, AVX1_128ONLY); - // @formatter:on - - protected VexRROp(String opcode, int pp, int mmmmm, int w, int op) { - this(opcode, pp, mmmmm, w, op, AVX1); - } - - protected VexRROp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src) { - assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src); - } - } - - /** - * VEX-encoded instructions with an operand order of RM. - */ - public static class VexRMOp extends VexRROp { - // @formatter:off - public static final VexRMOp VCVTTSS2SI = new VexRMOp("VCVTTSS2SI", P_F3, M_0F, W0, 0x2C, CPU_XMM); - public static final VexRMOp VCVTTSS2SQ = new VexRMOp("VCVTTSS2SQ", P_F3, M_0F, W1, 0x2C, CPU_XMM); - public static final VexRMOp VCVTTSD2SI = new VexRMOp("VCVTTSD2SI", P_F2, M_0F, W0, 0x2C, CPU_XMM); - public static final VexRMOp VCVTTSD2SQ = new VexRMOp("VCVTTSD2SQ", P_F2, M_0F, W1, 0x2C, CPU_XMM); - public static final VexRMOp VCVTPS2PD = new VexRMOp("VCVTPS2PD", P_, M_0F, WIG, 0x5A); - public static final VexRMOp VCVTPD2PS = new VexRMOp("VCVTPD2PS", P_66, M_0F, WIG, 0x5A); - public static final VexRMOp VCVTDQ2PS = new VexRMOp("VCVTDQ2PS", P_, M_0F, WIG, 0x5B); - public static final VexRMOp VCVTTPS2DQ = new VexRMOp("VCVTTPS2DQ", P_F3, M_0F, WIG, 0x5B); - public static final VexRMOp VCVTTPD2DQ = new VexRMOp("VCVTTPD2DQ", P_66, M_0F, WIG, 0xE6); - public static final VexRMOp VCVTDQ2PD = new VexRMOp("VCVTDQ2PD", P_F3, M_0F, WIG, 0xE6); - public static final VexRMOp VBROADCASTSS = new VexRMOp("VBROADCASTSS", P_66, M_0F38, W0, 0x18); - public static final VexRMOp VBROADCASTSD = new VexRMOp("VBROADCASTSD", P_66, M_0F38, W0, 0x19, AVX1_256ONLY); - public static final VexRMOp VBROADCASTF128 = new VexRMOp("VBROADCASTF128", P_66, M_0F38, W0, 0x1A, AVX1_256ONLY); - public static final VexRMOp VBROADCASTI128 = new VexRMOp("VBROADCASTI128", P_66, M_0F38, W0, 0x5A, AVX2_256ONLY); - public static final VexRMOp VPBROADCASTB = new VexRMOp("VPBROADCASTB", P_66, M_0F38, W0, 0x78, AVX2); - public static final VexRMOp VPBROADCASTW = new VexRMOp("VPBROADCASTW", P_66, M_0F38, W0, 0x79, AVX2); - public static final VexRMOp VPBROADCASTD = new VexRMOp("VPBROADCASTD", P_66, M_0F38, W0, 0x58, AVX2); - public static final VexRMOp VPBROADCASTQ = new VexRMOp("VPBROADCASTQ", P_66, M_0F38, W0, 0x59, AVX2); - public static final VexRMOp VPMOVSXBW = new VexRMOp("VPMOVSXBW", P_66, M_0F38, WIG, 0x20); - public static final VexRMOp VPMOVSXBD = new VexRMOp("VPMOVSXBD", P_66, M_0F38, WIG, 0x21); - public static final VexRMOp VPMOVSXBQ = new VexRMOp("VPMOVSXBQ", P_66, M_0F38, WIG, 0x22); - public static final VexRMOp VPMOVSXWD = new VexRMOp("VPMOVSXWD", P_66, M_0F38, WIG, 0x23); - public static final VexRMOp VPMOVSXWQ = new VexRMOp("VPMOVSXWQ", P_66, M_0F38, WIG, 0x24); - public static final VexRMOp VPMOVSXDQ = new VexRMOp("VPMOVSXDQ", P_66, M_0F38, WIG, 0x25); - public static final VexRMOp VPMOVZXBW = new VexRMOp("VPMOVZXBW", P_66, M_0F38, WIG, 0x30); - public static final VexRMOp VPMOVZXBD = new VexRMOp("VPMOVZXBD", P_66, M_0F38, WIG, 0x31); - public static final VexRMOp VPMOVZXBQ = new VexRMOp("VPMOVZXBQ", P_66, M_0F38, WIG, 0x32); - public static final VexRMOp VPMOVZXWD = new VexRMOp("VPMOVZXWD", P_66, M_0F38, WIG, 0x33); - public static final VexRMOp VPMOVZXWQ = new VexRMOp("VPMOVZXWQ", P_66, M_0F38, WIG, 0x34); - public static final VexRMOp VPMOVZXDQ = new VexRMOp("VPMOVZXDQ", P_66, M_0F38, WIG, 0x35); - public static final VexRMOp VSQRTPD = new VexRMOp("VSQRTPD", P_66, M_0F, WIG, 0x51); - public static final VexRMOp VSQRTPS = new VexRMOp("VSQRTPS", P_, M_0F, WIG, 0x51); - public static final VexRMOp VSQRTSD = new VexRMOp("VSQRTSD", P_F2, M_0F, WIG, 0x51); - public static final VexRMOp VSQRTSS = new VexRMOp("VSQRTSS", P_F3, M_0F, WIG, 0x51); - public static final VexRMOp VUCOMISS = new VexRMOp("VUCOMISS", P_, M_0F, WIG, 0x2E); - public static final VexRMOp VUCOMISD = new VexRMOp("VUCOMISD", P_66, M_0F, WIG, 0x2E); - // @formatter:on - - protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op) { - this(opcode, pp, mmmmm, w, op, AVX1); - } - - protected VexRMOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, AMD64Address src) { - assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src, 0); - } - } - - /** - * VEX-encoded move instructions. - *

- * These instructions have two opcodes: op is the forward move instruction with an operand order - * of RM, and opReverse is the reverse move instruction with an operand order of MR. - */ - public static final class VexMoveOp extends VexRMOp { - // @formatter:off - public static final VexMoveOp VMOVDQA = new VexMoveOp("VMOVDQA", P_66, M_0F, WIG, 0x6F, 0x7F); - public static final VexMoveOp VMOVDQU = new VexMoveOp("VMOVDQU", P_F3, M_0F, WIG, 0x6F, 0x7F); - public static final VexMoveOp VMOVAPS = new VexMoveOp("VMOVAPS", P_, M_0F, WIG, 0x28, 0x29); - public static final VexMoveOp VMOVAPD = new VexMoveOp("VMOVAPD", P_66, M_0F, WIG, 0x28, 0x29); - public static final VexMoveOp VMOVUPS = new VexMoveOp("VMOVUPS", P_, M_0F, WIG, 0x10, 0x11); - public static final VexMoveOp VMOVUPD = new VexMoveOp("VMOVUPD", P_66, M_0F, WIG, 0x10, 0x11); - public static final VexMoveOp VMOVSS = new VexMoveOp("VMOVSS", P_F3, M_0F, WIG, 0x10, 0x11); - public static final VexMoveOp VMOVSD = new VexMoveOp("VMOVSD", P_F2, M_0F, WIG, 0x10, 0x11); - public static final VexMoveOp VMOVD = new VexMoveOp("VMOVD", P_66, M_0F, W0, 0x6E, 0x7E, XMM_CPU); - public static final VexMoveOp VMOVQ = new VexMoveOp("VMOVQ", P_66, M_0F, W1, 0x6E, 0x7E, XMM_CPU); - // @formatter:on - - private final int opReverse; - - private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) { - this(opcode, pp, mmmmm, w, op, opReverse, AVX1); - } - - private VexMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - this.opReverse = opReverse; - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, AMD64Address dst, Register src) { - assert assertion.check((AMD64) asm.target.arch, size, src, null, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, opReverse, src, dst, 0); - } - - public void emitReverse(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src) { - assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, opReverse, src, dst); - } - } - - public interface VexRRIOp { - void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src, int imm8); - } - - /** - * VEX-encoded instructions with an operand order of RMI. - */ - public static final class VexRMIOp extends VexOp implements VexRRIOp { - // @formatter:off - public static final VexRMIOp VPERMQ = new VexRMIOp("VPERMQ", P_66, M_0F3A, W1, 0x00, AVX2_256ONLY); - public static final VexRMIOp VPSHUFLW = new VexRMIOp("VPSHUFLW", P_F2, M_0F, WIG, 0x70, AVX1_2); - public static final VexRMIOp VPSHUFHW = new VexRMIOp("VPSHUFHW", P_F3, M_0F, WIG, 0x70, AVX1_2); - public static final VexRMIOp VPSHUFD = new VexRMIOp("VPSHUFD", P_66, M_0F, WIG, 0x70, AVX1_2); - // @formatter:on - - private VexRMIOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - @Override - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, dst, null, src); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src); - asm.emitByte(imm8); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, AMD64Address src, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, dst, null, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src, 1); - asm.emitByte(imm8); - } - } - - /** - * VEX-encoded instructions with an operand order of MRI. - */ - public static final class VexMRIOp extends VexOp implements VexRRIOp { - // @formatter:off - public static final VexMRIOp VEXTRACTF128 = new VexMRIOp("VEXTRACTF128", P_66, M_0F3A, W0, 0x19, AVX1_256ONLY); - public static final VexMRIOp VEXTRACTI128 = new VexMRIOp("VEXTRACTI128", P_66, M_0F3A, W0, 0x39, AVX2_256ONLY); - public static final VexMRIOp VPEXTRB = new VexMRIOp("VPEXTRB", P_66, M_0F3A, W0, 0x14, XMM_CPU); - public static final VexMRIOp VPEXTRW = new VexMRIOp("VPEXTRW", P_66, M_0F3A, W0, 0x15, XMM_CPU); - public static final VexMRIOp VPEXTRD = new VexMRIOp("VPEXTRD", P_66, M_0F3A, W0, 0x16, XMM_CPU); - public static final VexMRIOp VPEXTRQ = new VexMRIOp("VPEXTRQ", P_66, M_0F3A, W1, 0x16, XMM_CPU); - // @formatter:on - - private VexMRIOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - @Override - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, src, null, dst); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, src, dst); - asm.emitByte(imm8); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, AMD64Address dst, Register src, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, src, null, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, src, dst, 1); - asm.emitByte(imm8); - } - } - - /** - * VEX-encoded instructions with an operand order of RVMR. - */ - public static class VexRVMROp extends VexOp { - // @formatter:off - public static final VexRVMROp VPBLENDVB = new VexRVMROp("VPBLENDVB", P_66, M_0F3A, W0, 0x4C, AVX1_2); - public static final VexRVMROp VPBLENDVPS = new VexRVMROp("VPBLENDVPS", P_66, M_0F3A, W0, 0x4A, AVX1); - public static final VexRVMROp VPBLENDVPD = new VexRVMROp("VPBLENDVPD", P_66, M_0F3A, W0, 0x4B, AVX1); - // @formatter:on - - protected VexRVMROp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register mask, Register src1, Register src2) { - assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, src2); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2, mask); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register mask, Register src1, AMD64Address src2) { - assert assertion.check((AMD64) asm.target.arch, size, dst, mask, src1, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2, mask, 0); - } - } - - /** - * VEX-encoded instructions with an operand order of RVM. - */ - public static class VexRVMOp extends VexOp { - // @formatter:off - public static final VexRVMOp VANDPS = new VexRVMOp("VANDPS", P_, M_0F, WIG, 0x54); - public static final VexRVMOp VANDPD = new VexRVMOp("VANDPD", P_66, M_0F, WIG, 0x54); - public static final VexRVMOp VORPS = new VexRVMOp("VORPS", P_, M_0F, WIG, 0x56); - public static final VexRVMOp VORPD = new VexRVMOp("VORPD", P_66, M_0F, WIG, 0x56); - public static final VexRVMOp VADDPS = new VexRVMOp("VADDPS", P_, M_0F, WIG, 0x58); - public static final VexRVMOp VADDPD = new VexRVMOp("VADDPD", P_66, M_0F, WIG, 0x58); - public static final VexRVMOp VADDSS = new VexRVMOp("VADDSS", P_F3, M_0F, WIG, 0x58); - public static final VexRVMOp VADDSD = new VexRVMOp("VADDSD", P_F2, M_0F, WIG, 0x58); - public static final VexRVMOp VXORPS = new VexRVMOp("VXORPS", P_, M_0F, WIG, 0x57); - public static final VexRVMOp VXORPD = new VexRVMOp("VXORPD", P_66, M_0F, WIG, 0x57); - public static final VexRVMOp VMULPS = new VexRVMOp("VMULPS", P_, M_0F, WIG, 0x59); - public static final VexRVMOp VMULPD = new VexRVMOp("VMULPD", P_66, M_0F, WIG, 0x59); - public static final VexRVMOp VMULSS = new VexRVMOp("VMULSS", P_F3, M_0F, WIG, 0x59); - public static final VexRVMOp VMULSD = new VexRVMOp("VMULSD", P_F2, M_0F, WIG, 0x59); - public static final VexRVMOp VSUBPS = new VexRVMOp("VSUBPS", P_, M_0F, WIG, 0x5C); - public static final VexRVMOp VSUBPD = new VexRVMOp("VSUBPD", P_66, M_0F, WIG, 0x5C); - public static final VexRVMOp VSUBSS = new VexRVMOp("VSUBSS", P_F3, M_0F, WIG, 0x5C); - public static final VexRVMOp VSUBSD = new VexRVMOp("VSUBSD", P_F2, M_0F, WIG, 0x5C); - public static final VexRVMOp VDIVPS = new VexRVMOp("VDIVPS", P_, M_0F, WIG, 0x5E); - public static final VexRVMOp VDIVPD = new VexRVMOp("VDIVPD", P_66, M_0F, WIG, 0x5E); - public static final VexRVMOp VDIVSS = new VexRVMOp("VDIVPS", P_F3, M_0F, WIG, 0x5E); - public static final VexRVMOp VDIVSD = new VexRVMOp("VDIVPD", P_F2, M_0F, WIG, 0x5E); - public static final VexRVMOp VADDSUBPS = new VexRVMOp("VADDSUBPS", P_F2, M_0F, WIG, 0xD0); - public static final VexRVMOp VADDSUBPD = new VexRVMOp("VADDSUBPD", P_66, M_0F, WIG, 0xD0); - public static final VexRVMOp VPAND = new VexRVMOp("VPAND", P_66, M_0F, WIG, 0xDB, AVX1_2); - public static final VexRVMOp VPOR = new VexRVMOp("VPOR", P_66, M_0F, WIG, 0xEB, AVX1_2); - public static final VexRVMOp VPXOR = new VexRVMOp("VPXOR", P_66, M_0F, WIG, 0xEF, AVX1_2); - public static final VexRVMOp VPADDB = new VexRVMOp("VPADDB", P_66, M_0F, WIG, 0xFC, AVX1_2); - public static final VexRVMOp VPADDW = new VexRVMOp("VPADDW", P_66, M_0F, WIG, 0xFD, AVX1_2); - public static final VexRVMOp VPADDD = new VexRVMOp("VPADDD", P_66, M_0F, WIG, 0xFE, AVX1_2); - public static final VexRVMOp VPADDQ = new VexRVMOp("VPADDQ", P_66, M_0F, WIG, 0xD4, AVX1_2); - public static final VexRVMOp VPMULHUW = new VexRVMOp("VPMULHUW", P_66, M_0F, WIG, 0xE4, AVX1_2); - public static final VexRVMOp VPMULHW = new VexRVMOp("VPMULHW", P_66, M_0F, WIG, 0xE5, AVX1_2); - public static final VexRVMOp VPMULLW = new VexRVMOp("VPMULLW", P_66, M_0F, WIG, 0xD5, AVX1_2); - public static final VexRVMOp VPMULLD = new VexRVMOp("VPMULLD", P_66, M_0F38, WIG, 0x40, AVX1_2); - public static final VexRVMOp VPSUBB = new VexRVMOp("VPSUBB", P_66, M_0F, WIG, 0xF8, AVX1_2); - public static final VexRVMOp VPSUBW = new VexRVMOp("VPSUBW", P_66, M_0F, WIG, 0xF9, AVX1_2); - public static final VexRVMOp VPSUBD = new VexRVMOp("VPSUBD", P_66, M_0F, WIG, 0xFA, AVX1_2); - public static final VexRVMOp VPSUBQ = new VexRVMOp("VPSUBQ", P_66, M_0F, WIG, 0xFB, AVX1_2); - public static final VexRVMOp VPSHUFB = new VexRVMOp("VPSHUFB", P_66, M_0F38, WIG, 0x00, AVX1_2); - public static final VexRVMOp VCVTSD2SS = new VexRVMOp("VCVTSD2SS", P_F2, M_0F, WIG, 0x5A); - public static final VexRVMOp VCVTSS2SD = new VexRVMOp("VCVTSS2SD", P_F3, M_0F, WIG, 0x5A); - public static final VexRVMOp VCVTSI2SD = new VexRVMOp("VCVTSI2SD", P_F2, M_0F, W0, 0x2A, XMM_XMM_CPU); - public static final VexRVMOp VCVTSQ2SD = new VexRVMOp("VCVTSQ2SD", P_F2, M_0F, W1, 0x2A, XMM_XMM_CPU); - public static final VexRVMOp VCVTSI2SS = new VexRVMOp("VCVTSI2SS", P_F3, M_0F, W0, 0x2A, XMM_XMM_CPU); - public static final VexRVMOp VCVTSQ2SS = new VexRVMOp("VCVTSQ2SS", P_F3, M_0F, W1, 0x2A, XMM_XMM_CPU); - public static final VexRVMOp VPCMPEQB = new VexRVMOp("VPCMPEQB", P_66, M_0F, WIG, 0x74, AVX1_2); - public static final VexRVMOp VPCMPEQW = new VexRVMOp("VPCMPEQW", P_66, M_0F, WIG, 0x75, AVX1_2); - public static final VexRVMOp VPCMPEQD = new VexRVMOp("VPCMPEQD", P_66, M_0F, WIG, 0x76, AVX1_2); - public static final VexRVMOp VPCMPEQQ = new VexRVMOp("VPCMPEQQ", P_66, M_0F38, WIG, 0x76, AVX1_2); - public static final VexRVMOp VPCMPGTB = new VexRVMOp("VPCMPGTB", P_66, M_0F, WIG, 0x64, AVX1_2); - public static final VexRVMOp VPCMPGTW = new VexRVMOp("VPCMPGTW", P_66, M_0F, WIG, 0x65, AVX1_2); - public static final VexRVMOp VPCMPGTD = new VexRVMOp("VPCMPGTD", P_66, M_0F, WIG, 0x66, AVX1_2); - public static final VexRVMOp VPCMPGTQ = new VexRVMOp("VPCMPGTQ", P_66, M_0F38, WIG, 0x37, AVX1_2); - // @formatter:on - - private VexRVMOp(String opcode, int pp, int mmmmm, int w, int op) { - this(opcode, pp, mmmmm, w, op, AVX1); - } - - protected VexRVMOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, Register src2) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2, 0); - } - } - - /** - * VEX-encoded shift instructions with an operand order of either RVM or VMI. - */ - public static final class VexShiftOp extends VexRVMOp implements VexRRIOp { - // @formatter:off - public static final VexShiftOp VPSRLW = new VexShiftOp("VPSRLW", P_66, M_0F, WIG, 0xD1, 0x71, 2); - public static final VexShiftOp VPSRLD = new VexShiftOp("VPSRLD", P_66, M_0F, WIG, 0xD2, 0x72, 2); - public static final VexShiftOp VPSRLQ = new VexShiftOp("VPSRLQ", P_66, M_0F, WIG, 0xD3, 0x73, 2); - public static final VexShiftOp VPSRAW = new VexShiftOp("VPSRAW", P_66, M_0F, WIG, 0xE1, 0x71, 4); - public static final VexShiftOp VPSRAD = new VexShiftOp("VPSRAD", P_66, M_0F, WIG, 0xE2, 0x72, 4); - public static final VexShiftOp VPSLLW = new VexShiftOp("VPSLLW", P_66, M_0F, WIG, 0xF1, 0x71, 6); - public static final VexShiftOp VPSLLD = new VexShiftOp("VPSLLD", P_66, M_0F, WIG, 0xF2, 0x72, 6); - public static final VexShiftOp VPSLLQ = new VexShiftOp("VPSLLQ", P_66, M_0F, WIG, 0xF3, 0x73, 6); - // @formatter:on - - private final int immOp; - private final int r; - - private VexShiftOp(String opcode, int pp, int mmmmm, int w, int op, int immOp, int r) { - super(opcode, pp, mmmmm, w, op, AVX1_2); - this.immOp = immOp; - this.r = r; - } - - @Override - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, null, dst, src); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, immOp, r, dst, src); - asm.emitByte(imm8); - } - } - - public static final class VexMaskMoveOp extends VexOp { - // @formatter:off - public static final VexMaskMoveOp VMASKMOVPS = new VexMaskMoveOp("VMASKMOVPS", P_66, M_0F38, W0, 0x2C, 0x2E); - public static final VexMaskMoveOp VMASKMOVPD = new VexMaskMoveOp("VMASKMOVPD", P_66, M_0F38, W0, 0x2D, 0x2F); - public static final VexMaskMoveOp VPMASKMOVD = new VexMaskMoveOp("VPMASKMOVD", P_66, M_0F38, W0, 0x8C, 0x8E, AVX2); - public static final VexMaskMoveOp VPMASKMOVQ = new VexMaskMoveOp("VPMASKMOVQ", P_66, M_0F38, W1, 0x8C, 0x8E, AVX2); - // @formatter:on - - private final int opReverse; - - private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse) { - this(opcode, pp, mmmmm, w, op, opReverse, AVX1); - } - - private VexMaskMoveOp(String opcode, int pp, int mmmmm, int w, int op, int opReverse, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - this.opReverse = opReverse; - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register mask, AMD64Address src) { - assert assertion.check((AMD64) asm.target.arch, size, dst, mask, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, mask, src, 0); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, AMD64Address dst, Register mask, Register src) { - assert assertion.check((AMD64) asm.target.arch, size, src, mask, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, opReverse, src, mask, dst, 0); - } - } - - /** - * VEX-encoded instructions with an operand order of RVMI. - */ - public static final class VexRVMIOp extends VexOp { - // @formatter:off - public static final VexRVMIOp VSHUFPS = new VexRVMIOp("VSHUFPS", P_, M_0F, WIG, 0xC6); - public static final VexRVMIOp VSHUFPD = new VexRVMIOp("VSHUFPD", P_66, M_0F, WIG, 0xC6); - public static final VexRVMIOp VINSERTF128 = new VexRVMIOp("VINSERTF128", P_66, M_0F3A, W0, 0x18, AVX1_256ONLY); - public static final VexRVMIOp VINSERTI128 = new VexRVMIOp("VINSERTI128", P_66, M_0F3A, W0, 0x38, AVX2_256ONLY); - // @formatter:on - - private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op) { - this(opcode, pp, mmmmm, w, op, AVX1); - } - - private VexRVMIOp(String opcode, int pp, int mmmmm, int w, int op, OpAssertion assertion) { - super(opcode, pp, mmmmm, w, op, assertion); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, Register src2, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); - assert (imm8 & 0xFF) == imm8; - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2); - asm.emitByte(imm8); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, int imm8) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); - assert (imm8 & 0xFF) == imm8; - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2, 1); - asm.emitByte(imm8); - } - } - - /** - * VEX-encoded comparison operation with an operand order of RVMI. The immediate operand is a - * comparison operator. - */ - public static final class VexFloatCompareOp extends VexOp { - // @formatter:off - public static final VexFloatCompareOp VCMPPS = new VexFloatCompareOp("VCMPPS", P_, M_0F, WIG, 0xC2); - public static final VexFloatCompareOp VCMPPD = new VexFloatCompareOp("VCMPPD", P_66, M_0F, WIG, 0xC2); - public static final VexFloatCompareOp VCMPSS = new VexFloatCompareOp("VCMPSS", P_F2, M_0F, WIG, 0xC2); - public static final VexFloatCompareOp VCMPSD = new VexFloatCompareOp("VCMPSD", P_F2, M_0F, WIG, 0xC2); - // @formatter:on - - public enum Predicate { - EQ_OQ(0x00), - LT_OS(0x01), - LE_OS(0x02), - UNORD_Q(0x03), - NEQ_UQ(0x04), - NLT_US(0x05), - NLE_US(0x06), - ORD_Q(0x07), - EQ_UQ(0x08), - NGE_US(0x09), - NGT_US(0x0a), - FALSE_OQ(0x0b), - NEQ_OQ(0x0c), - GE_OS(0x0d), - GT_OS(0x0e), - TRUE_UQ(0x0f), - EQ_OS(0x10), - LT_OQ(0x11), - LE_OQ(0x12), - UNORD_S(0x13), - NEQ_US(0x14), - NLT_UQ(0x15), - NLE_UQ(0x16), - ORD_S(0x17), - EQ_US(0x18), - NGE_UQ(0x19), - NGT_UQ(0x1a), - FALSE_OS(0x1b), - NEQ_OS(0x1c), - GE_OQ(0x1d), - GT_OQ(0x1e), - TRUE_US(0x1f); - - private int imm8; - - Predicate(int imm8) { - this.imm8 = imm8; - } - - public static Predicate getPredicate(Condition condition, boolean unorderedIsTrue) { - if (unorderedIsTrue) { - switch (condition) { - case EQ: - return EQ_UQ; - case NE: - return NEQ_UQ; - case LT: - return NGE_UQ; - case LE: - return NGT_UQ; - case GT: - return NLE_UQ; - case GE: - return NLT_UQ; - default: - throw GraalError.shouldNotReachHere(); - } - } else { - switch (condition) { - case EQ: - return EQ_OQ; - case NE: - return NEQ_OQ; - case LT: - return LT_OQ; - case LE: - return LE_OQ; - case GT: - return GT_OQ; - case GE: - return GE_OQ; - default: - throw GraalError.shouldNotReachHere(); - } - } - } - } - - private VexFloatCompareOp(String opcode, int pp, int mmmmm, int w, int op) { - super(opcode, pp, mmmmm, w, op, AVX1); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, Register src2, Predicate p) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, src2); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2); - asm.emitByte(p.imm8); - } - - public void emit(AMD64VectorAssembler asm, AVXSize size, Register dst, Register src1, AMD64Address src2, Predicate p) { - assert assertion.check((AMD64) asm.target.arch, size, dst, src1, null); - asm.emitVexOp(getLFlag(size), pp, mmmmm, w, op, dst, src1, src2, 1); - asm.emitByte(p.imm8); - } - } - - @Override - public void movflt(Register dst, Register src) { - VexMoveOp.VMOVAPS.emit(this, AVXSize.XMM, dst, src); - } - - @Override - public void movflt(Register dst, AMD64Address src) { - VexMoveOp.VMOVSS.emit(this, AVXSize.XMM, dst, src); - } - - @Override - public void movflt(AMD64Address dst, Register src) { - VexMoveOp.VMOVSS.emit(this, AVXSize.XMM, dst, src); - } - - @Override - public void movdbl(Register dst, Register src) { - VexMoveOp.VMOVAPD.emit(this, AVXSize.XMM, dst, src); - } - - @Override - public void movdbl(Register dst, AMD64Address src) { - VexMoveOp.VMOVSD.emit(this, AVXSize.XMM, dst, src); - } - - @Override - public void movdbl(AMD64Address dst, Register src) { - VexMoveOp.VMOVSD.emit(this, AVXSize.XMM, dst, src); - } -} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AVXKind.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AVXKind.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AVXKind.java Fri Aug 17 13:20:53 2018 -0700 @@ -28,6 +28,7 @@ import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.QWORD; import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.XMM; import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.YMM; +import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.ZMM; import jdk.vm.ci.meta.Value; import org.graalvm.compiler.debug.GraalError; @@ -43,7 +44,8 @@ DWORD, QWORD, XMM, - YMM; + YMM, + ZMM; public int getBytes() { switch (this) { @@ -55,6 +57,8 @@ return 16; case YMM: return 32; + case ZMM: + return 64; default: return 0; } @@ -84,6 +88,8 @@ return XMM; case 32: return YMM; + case 64: + return ZMM; default: throw GraalError.shouldNotReachHere("unsupported kind: " + kind); } @@ -91,7 +97,10 @@ public static AVXSize getRegisterSize(AMD64Kind kind) { assert kind.isXMM() : "unexpected kind " + kind; - if (kind.getSizeInBytes() > 16) { + int size = kind.getSizeInBytes(); + if (size > 32) { + return ZMM; + } else if (size > 16) { return YMM; } else { return XMM; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.sparc/src/org/graalvm/compiler/asm/sparc/SPARCAssembler.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.sparc/src/org/graalvm/compiler/asm/sparc/SPARCAssembler.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.sparc/src/org/graalvm/compiler/asm/sparc/SPARCAssembler.java Fri Aug 17 13:20:53 2018 -0700 @@ -1173,7 +1173,7 @@ public static final Sethi SETHI = new Sethi(); public static final FMOVcc FMOVSCC = new FMOVcc(OpfLow.Fmovscc); public static final FMOVcc FMOVDCC = new FMOVcc(OpfLow.Fmovdcc); - public static final MOVicc MOVicc = new MOVicc(); + public static final MOVicc MOVICC = new MOVicc(); public static final OpfOp OPF = new OpfOp(); public static final Op3Op OP3 = new Op3Op(); public static final SPARCOp LDST = new SPARCOp(Ops.LdstOp); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -53,14 +53,14 @@ import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift.SAR; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift.SHL; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift.SHR; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.BYTE; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PS; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.BYTE; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue; import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant; @@ -82,11 +82,9 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MROp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.FloatConvert; @@ -112,12 +110,10 @@ import org.graalvm.compiler.lir.gen.LIRGenerator; import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.RegisterValue; -import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.JavaConstant; @@ -174,8 +170,6 @@ public Variable emitNegate(Value inputVal) { AllocatableValue input = asAllocatable(inputVal); Variable result = getLIRGen().newVariable(LIRKind.combine(input)); - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) input.getPlatformKind()) { case DWORD: getLIRGen().append(new AMD64Unary.MOp(NEG, DWORD, result, input)); @@ -184,18 +178,10 @@ getLIRGen().append(new AMD64Unary.MOp(NEG, QWORD, result, input)); break; case SINGLE: - if (isAvx) { - getLIRGen().append(new AMD64Binary.DataThreeOp(AVXOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16)); - } else { - getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16)); - } + getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PS, result, input, JavaConstant.forFloat(Float.intBitsToFloat(0x80000000)), 16)); break; case DOUBLE: - if (isAvx) { - getLIRGen().append(new AMD64Binary.DataThreeOp(AVXOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16)); - } else { - getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16)); - } + getLIRGen().append(new AMD64Binary.DataTwoOp(SSEOp.XOR, PD, result, input, JavaConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)), 16)); break; default: throw GraalError.shouldNotReachHere(input.getPlatformKind().toString()); @@ -240,16 +226,6 @@ } } - private Variable emitBinary(LIRKind resultKind, AMD64RRMOp op, OperandSize size, boolean commutative, Value a, Value b) { - if (isJavaConstant(b)) { - return emitBinaryConst(resultKind, op, size, asAllocatable(a), asJavaConstant(b)); - } else if (commutative && isJavaConstant(a)) { - return emitBinaryConst(resultKind, op, size, asAllocatable(b), asJavaConstant(a)); - } else { - return emitBinaryVar(resultKind, op, size, commutative, asAllocatable(a), asAllocatable(b)); - } - } - private Variable emitBinaryConst(LIRKind resultKind, AMD64BinaryArithmetic op, OperandSize size, boolean commutative, AllocatableValue a, ConstantValue b, boolean setFlags) { long value = b.getJavaConstant().asLong(); if (NumUtil.isInt(value)) { @@ -296,12 +272,6 @@ return result; } - private Variable emitBinaryConst(LIRKind resultKind, AMD64RRMOp op, OperandSize size, AllocatableValue a, JavaConstant b) { - Variable result = getLIRGen().newVariable(resultKind); - getLIRGen().append(new AMD64Binary.DataThreeOp(op, size, result, a, b)); - return result; - } - private Variable emitBinaryVar(LIRKind resultKind, AMD64RMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) { Variable result = getLIRGen().newVariable(resultKind); if (commutative) { @@ -312,16 +282,6 @@ return result; } - private Variable emitBinaryVar(LIRKind resultKind, AMD64RRMOp op, OperandSize size, boolean commutative, AllocatableValue a, AllocatableValue b) { - Variable result = getLIRGen().newVariable(resultKind); - if (commutative) { - getLIRGen().append(new AMD64Binary.CommutativeThreeOp(op, size, result, a, b)); - } else { - getLIRGen().append(new AMD64Binary.ThreeOp(op, size, result, a, b)); - } - return result; - } - @Override protected boolean isNumericInteger(PlatformKind kind) { return ((AMD64Kind) kind).isInteger(); @@ -336,8 +296,6 @@ @Override public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: if (isJavaConstant(b) && !setFlags) { @@ -356,17 +314,9 @@ } return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.ADD, SS, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b); - } + return emitBinary(resultKind, SSEOp.ADD, SS, true, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.ADD, SD, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b); - } + return emitBinary(resultKind, SSEOp.ADD, SD, true, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -374,25 +324,15 @@ @Override public Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: return emitBinary(resultKind, SUB, DWORD, false, a, b, setFlags); case QWORD: return emitBinary(resultKind, SUB, QWORD, false, a, b, setFlags); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.SUB, SS, false, a, b); - } else { - return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b); - } + return emitBinary(resultKind, SSEOp.SUB, SS, false, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.SUB, SD, false, a, b); - } else { - return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b); - } + return emitBinary(resultKind, SSEOp.SUB, SD, false, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -430,25 +370,15 @@ @Override public Variable emitMul(Value a, Value b, boolean setFlags) { LIRKind resultKind = LIRKind.combine(a, b); - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: return emitIMUL(DWORD, a, b); case QWORD: return emitIMUL(QWORD, a, b); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.MUL, SS, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.MUL, SS, true, a, b); - } + return emitBinary(resultKind, SSEOp.MUL, SS, true, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.MUL, SD, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.MUL, SD, true, a, b); - } + return emitBinary(resultKind, SSEOp.MUL, SD, true, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -495,12 +425,6 @@ return result; } - public Value emitBinaryMemory(AMD64RRMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) { - Variable result = getLIRGen().newVariable(LIRKind.combine(a)); - getLIRGen().append(new AMD64Binary.MemoryThreeOp(op, size, result, a, location, state)); - return result; - } - protected Value emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, AMD64AddressValue address, LIRFrameState state) { Variable result = getLIRGen().newVariable(LIRKind.value(kind)); getLIRGen().append(new AMD64Unary.MemoryOp(op, size, result, address, state)); @@ -578,8 +502,6 @@ @Override public Value emitDiv(Value a, Value b, LIRFrameState state) { - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); LIRKind resultKind = LIRKind.combine(a, b); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: @@ -589,17 +511,9 @@ AMD64MulDivOp lop = emitIDIV(QWORD, a, b, state); return getLIRGen().emitMove(lop.getQuotient()); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.DIV, SS, false, a, b); - } else { - return emitBinary(resultKind, SSEOp.DIV, SS, false, a, b); - } + return emitBinary(resultKind, SSEOp.DIV, SS, false, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.DIV, SD, false, a, b); - } else { - return emitBinary(resultKind, SSEOp.DIV, SD, false, a, b); - } + return emitBinary(resultKind, SSEOp.DIV, SD, false, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -664,25 +578,15 @@ @Override public Variable emitAnd(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: return emitBinary(resultKind, AND, DWORD, true, a, b, false); case QWORD: return emitBinary(resultKind, AND, QWORD, true, a, b, false); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.AND, PS, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.AND, PS, true, a, b); - } + return emitBinary(resultKind, SSEOp.AND, PS, true, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.AND, PD, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.AND, PD, true, a, b); - } + return emitBinary(resultKind, SSEOp.AND, PD, true, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -691,25 +595,15 @@ @Override public Variable emitOr(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: return emitBinary(resultKind, OR, DWORD, true, a, b, false); case QWORD: return emitBinary(resultKind, OR, QWORD, true, a, b, false); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.OR, PS, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.OR, PS, true, a, b); - } + return emitBinary(resultKind, SSEOp.OR, PS, true, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.OR, PD, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.OR, PD, true, a, b); - } + return emitBinary(resultKind, SSEOp.OR, PD, true, a, b); default: throw GraalError.shouldNotReachHere(); } @@ -718,25 +612,15 @@ @Override public Variable emitXor(Value a, Value b) { LIRKind resultKind = LIRKind.combine(a, b); - TargetDescription target = getLIRGen().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); switch ((AMD64Kind) a.getPlatformKind()) { case DWORD: return emitBinary(resultKind, XOR, DWORD, true, a, b, false); case QWORD: return emitBinary(resultKind, XOR, QWORD, true, a, b, false); case SINGLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.XOR, PS, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b); - } + return emitBinary(resultKind, SSEOp.XOR, PS, true, a, b); case DOUBLE: - if (isAvx) { - return emitBinary(resultKind, AVXOp.XOR, PD, true, a, b); - } else { - return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b); - } + return emitBinary(resultKind, SSEOp.XOR, PD, true, a, b); default: throw GraalError.shouldNotReachHere(); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -29,10 +29,10 @@ import static jdk.vm.ci.code.ValueUtil.isAllocatableValue; import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.CMP; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.PS; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.PS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.lir.LIRValueUtil.asConstant; import static org.graalvm.compiler.lir.LIRValueUtil.asConstantValue; @@ -45,7 +45,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; @@ -66,6 +66,7 @@ import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool; import org.graalvm.compiler.lir.amd64.AMD64ArrayCompareToOp; import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp; +import org.graalvm.compiler.lir.amd64.AMD64ArrayIndexOfOp; import org.graalvm.compiler.lir.amd64.AMD64Binary; import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer; import org.graalvm.compiler.lir.amd64.AMD64ByteSwapOp; @@ -566,6 +567,13 @@ } @Override + public Variable emitArrayIndexOf(JavaKind kind, Value arrayPointer, Value arrayLength, Value charValue) { + Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD)); + append(new AMD64ArrayIndexOfOp(kind, getVMPageSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), asAllocatable(charValue))); + return result; + } + + @Override public void emitReturn(JavaKind kind, Value input) { AllocatableValue operand = Value.ILLEGAL; if (input != null) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64MoveFactoryBase.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,8 +25,8 @@ package org.graalvm.compiler.core.amd64; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.WORD; import jdk.internal.vm.compiler.collections.EconomicMap; import jdk.internal.vm.compiler.collections.Equivalence; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java Fri Aug 17 13:20:53 2018 -0700 @@ -33,17 +33,15 @@ import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.calc.CanonicalCondition; @@ -80,10 +78,7 @@ import org.graalvm.compiler.nodes.memory.WriteNode; import org.graalvm.compiler.nodes.util.GraphUtil; -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.vm.ci.amd64.AMD64Kind; -import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.PlatformKind; @@ -390,23 +385,12 @@ getState(access)); } - private ComplexMatchResult binaryRead(AMD64RRMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) { - return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), - getState(access)); - } - @MatchRule("(Add value Read=access)") @MatchRule("(Add value FloatingRead=access)") public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - TargetDescription target = getLIRGeneratorTool().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); - if (isAvx) { - return binaryRead(AVXOp.ADD, size, value, access); - } else { - return binaryRead(SSEOp.ADD, size, value, access); - } + return binaryRead(SSEOp.ADD, size, value, access); } else { return binaryRead(ADD.getRMOpcode(size), size, value, access); } @@ -417,13 +401,7 @@ public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - TargetDescription target = getLIRGeneratorTool().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); - if (isAvx) { - return binaryRead(AVXOp.SUB, size, value, access); - } else { - return binaryRead(SSEOp.SUB, size, value, access); - } + return binaryRead(SSEOp.SUB, size, value, access); } else { return binaryRead(SUB.getRMOpcode(size), size, value, access); } @@ -434,13 +412,7 @@ public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) { OperandSize size = getMemorySize(access); if (size.isXmmType()) { - TargetDescription target = getLIRGeneratorTool().target(); - boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX); - if (isAvx) { - return binaryRead(AVXOp.MUL, size, value, access); - } else { - return binaryRead(SSEOp.MUL, size, value, access); - } + return binaryRead(SSEOp.MUL, size, value, access); } else { return binaryRead(AMD64RMOp.IMUL, size, value, access); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java Fri Aug 17 13:20:53 2018 -0700 @@ -110,6 +110,11 @@ return (short) v; } + public static int safeToInt(long v) { + assert isInt(v); + return (int) v; + } + public static int roundUp(int number, int mod) { return ((number + mod - 1) / mod) * mod; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/IntList.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/IntList.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/IntList.java Fri Aug 17 13:20:53 2018 -0700 @@ -147,9 +147,9 @@ /** * Adjusts the {@linkplain #size() size} of this int list. * - * If {@code newSize < size()}, the size is changed to {@code newSize}. If - * {@code newSize > size()}, sufficient 0 elements are {@linkplain #add(int) added} until - * {@code size() == newSize}. + * If {@code newSize > size()}, sufficient 0 elements are {@linkplain #add(int) added} until + * {@code size() == newSize}. If {@code newSize < size()}, the size is changed to + * {@code newSize}. * * @param newSize the new size of this int list */ diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,7 +27,7 @@ import static org.graalvm.compiler.asm.sparc.SPARCAssembler.FMOVDCC; import static org.graalvm.compiler.asm.sparc.SPARCAssembler.FMOVSCC; -import static org.graalvm.compiler.asm.sparc.SPARCAssembler.MOVicc; +import static org.graalvm.compiler.asm.sparc.SPARCAssembler.MOVICC; import static org.graalvm.compiler.asm.sparc.SPARCAssembler.CC.Fcc0; import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Subcc; import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fcmpd; @@ -287,7 +287,7 @@ } else if (valueKind.isInteger()) { actualTrueValue = loadSimm11(trueValue); actualFalseValue = loadSimm11(falseValue); - cmove = MOVicc; + cmove = MOVICC; } else { throw GraalError.shouldNotReachHere(); } @@ -368,7 +368,7 @@ Variable result = newVariable(trueValue.getValueKind()); ConditionFlag flag = SPARCControlFlow.fromCondition(true, Condition.EQ, false); CC cc = CC.forKind(left.getPlatformKind()); - append(new CondMoveOp(MOVicc, cc, flag, loadSimm11(trueValue), loadSimm11(falseValue), result)); + append(new CondMoveOp(MOVICC, cc, flag, loadSimm11(trueValue), loadSimm11(falseValue), result)); return result; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Fri Aug 17 13:20:53 2018 -0700 @@ -142,7 +142,30 @@ } protected boolean shouldLoadClass(String className) { - return !className.equals("module-info") && !className.startsWith("META-INF.versions."); + if (className.equals("module-info") || className.startsWith("META-INF.versions.")) { + return false; + } + if (!Java8OrEarlier) { + // @formatter:off + /* + * Work around to prevent: + * + * org.graalvm.compiler.debug.GraalError: java.lang.IllegalAccessError: class org.graalvm.compiler.serviceprovider.GraalServices$Lazy (in module + * jdk.internal.vm.compiler) cannot access class java.lang.management.ManagementFactory (in module java.management) because module + * jdk.internal.vm.compiler does not read module java.management + * at jdk.internal.vm.compiler/org.graalvm.compiler.debug.GraalError.shouldNotReachHere(GraalError.java:55) + * at org.graalvm.compiler.core.test.CheckGraalInvariants$InvariantsTool.handleClassLoadingException(CheckGraalInvariants.java:149) + * at org.graalvm.compiler.core.test.CheckGraalInvariants.initializeClasses(CheckGraalInvariants.java:321) + * at org.graalvm.compiler.core.test.CheckGraalInvariants.runTest(CheckGraalInvariants.java:239) + * + * which occurs because JDK8 overlays are in modular jars. They are never used normally. + */ + // @formatter:on + if (className.equals("org.graalvm.compiler.serviceprovider.GraalServices$Lazy")) { + return false; + } + } + return true; } protected void handleClassLoadingException(Throwable t) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConcreteSubtypeTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConcreteSubtypeTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConcreteSubtypeTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,12 +24,9 @@ package org.graalvm.compiler.core.test; -import jdk.vm.ci.meta.Assumptions.Assumption; -import jdk.vm.ci.meta.Assumptions.ConcreteSubtype; - import org.junit.Test; -import org.graalvm.compiler.nodes.StructuredGraph; +import jdk.vm.ci.meta.Assumptions.ConcreteSubtype; /** * Ensure that abstract classes with a single implementor are properly optimized and that loading a @@ -57,12 +54,6 @@ object.check(); } - @Override - protected void checkGraph(Assumption expectedAssumption, StructuredGraph graph) { - super.checkGraph(expectedAssumption, graph); - assertTrue(graph.isTrivial()); - } - /** * Test that {@link #callAbstractType} gets compiled into an empty method with a * {@link ConcreteSubtype} assumption on {@link AbstractBase} and {@link Subclass}. Then ensures diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/EnumValuesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/EnumValuesTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.core.test; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +public class EnumValuesTest extends GraalCompilerTest { + + private static final int NANOS_INDEX = Arrays.asList(TimeUnit.values()).indexOf(TimeUnit.NANOSECONDS); + + @SuppressWarnings("unused") + public static void iterateUnits() { + for (TimeUnit unit : TimeUnit.values()) { + // nop + } + } + + public static void empty() { + } + + @Test + public void test0() { + assertEquals(getFinalGraph("empty"), getFinalGraph("iterateUnits")); + } + + public static TimeUnit getNanosValues() { + return TimeUnit.values()[NANOS_INDEX]; + } + + public static TimeUnit getNanos() { + return TimeUnit.NANOSECONDS; + } + + @Test + public void test1() { + assertEquals(getFinalGraph("getNanos"), getFinalGraph("getNanosValues")); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -63,6 +63,7 @@ public static final class WithFinalizerAAAA extends NoFinalizerYetAAAA { + @SuppressWarnings("deprecation") @Override protected void finalize() throws Throwable { super.finalize(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1063,6 +1063,20 @@ } } + protected StructuredGraph getFinalGraph(String method) { + return getFinalGraph(getResolvedJavaMethod(method)); + } + + protected StructuredGraph getFinalGraph(ResolvedJavaMethod method) { + StructuredGraph graph = parseForCompile(method); + applyFrontEnd(graph); + return graph; + } + + protected void applyFrontEnd(StructuredGraph graph) { + GraalCompiler.emitFrontEnd(getProviders(), getBackend(), graph, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, graph.getProfilingInfo(), createSuites(graph.getOptions())); + } + protected StructuredGraph lastCompiledGraph; protected SpeculationLog getSpeculationLog() { @@ -1108,6 +1122,7 @@ return methodMap.get(javaMethod); } + @SuppressWarnings("deprecation") protected Object invoke(ResolvedJavaMethod javaMethod, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { Executable method = lookupMethod(javaMethod); Assert.assertTrue(method != null); @@ -1443,13 +1458,4 @@ protected boolean isArchitecture(String name) { return name.equals(backend.getTarget().arch.getName()); } - - /** - * This method should be called in "timeout" tests which JUnit runs in a different thread. - */ - public static void initializeForTimeout() { - // timeout tests run in a separate thread which needs the DebugEnvironment to be - // initialized - // DebugEnvironment.ensureInitialized(getInitialOptions()); - } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,6 +25,7 @@ package org.graalvm.compiler.core.test; import java.util.HashMap; +import java.util.List; import org.graalvm.compiler.core.phases.HighTier; import org.graalvm.compiler.core.phases.MidTier; @@ -36,7 +37,9 @@ import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.OptimisticOptimizations; import org.graalvm.compiler.phases.tiers.MidTierContext; +import org.graalvm.compiler.test.SubprocessUtil; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; public class HashCodeTest extends GraalCompilerTest { @@ -141,6 +144,11 @@ @Test public void test08() { + // This test requires profiling information which does not work reliable across platforms + // when running with -Xcomp + List commandLine = SubprocessUtil.getVMCommandLine(); + Assume.assumeTrue(commandLine != null); + Assume.assumeFalse(commandLine.contains("-Xcomp")); initialize(Appendable.class); checkForGuardedIntrinsicPattern("hashCodeInterface"); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashMapGetTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashMapGetTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashMapGetTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -48,7 +48,7 @@ map.put(i, i); mapGet(map, i); } - test(get, null, map, new Integer(0)); + test(get, null, map, 0); for (IfNode ifNode : lastCompiledGraph.getNodes(IfNode.TYPE)) { LogicNode condition = ifNode.condition(); if (ifNode.getTrueSuccessorProbability() < 0.4 && condition instanceof ObjectEqualsNode) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InterfaceMethodHandleTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -98,8 +98,8 @@ } @Test - public void testInvokeInterface02() throws InstantiationException, IllegalAccessException, ClassNotFoundException { - test("invokeInterfaceHandle", loader.findClass(NAME).newInstance()); + public void testInvokeInterface02() throws Exception { + test("invokeInterfaceHandle", loader.findClass(NAME).getDeclaredConstructor().newInstance()); } public static Object invokeInterfaceHandle2(I o, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) throws Throwable { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvocationPluginsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/InvocationPluginsTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.core.test; + +import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.LateRegistration; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; +import org.junit.Test; + +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class InvocationPluginsTest extends GraalCompilerTest { + + private static void assertNotIsEmpty(InvocationPlugins invocationPlugins) { + InvocationPlugins childInvocationPlugins = new InvocationPlugins(invocationPlugins); + assertFalse(invocationPlugins.isEmpty()); + assertFalse(childInvocationPlugins.isEmpty()); + + invocationPlugins.closeRegistration(); + assertFalse(invocationPlugins.isEmpty()); + assertFalse(childInvocationPlugins.isEmpty()); + } + + @Test + public void testIsEmptyWithNormalRegistration() { + InvocationPlugins invocationPlugins = new InvocationPlugins(); + assertTrue(invocationPlugins.isEmpty()); + + Registration r = new Registration(invocationPlugins, Class.class); + r.register1("isAnonymousClass", Receiver.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { + return false; + } + }); + + assertNotIsEmpty(invocationPlugins); + } + + @Test + public void testIsEmptyWithDeferredRegistration() { + InvocationPlugins invocationPlugins = new InvocationPlugins(); + assertTrue(invocationPlugins.isEmpty()); + invocationPlugins.defer(new Runnable() { + + @Override + public void run() { + Registration r = new Registration(invocationPlugins, Class.class); + r.register1("isAnonymousClass", Receiver.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { + return false; + } + }); + } + }); + + assertNotIsEmpty(invocationPlugins); + } + + @Test + public void testIsEmptyWithLateRegistration() { + InvocationPlugins invocationPlugins = new InvocationPlugins(); + assertTrue(invocationPlugins.isEmpty()); + + try (LateRegistration lr = new LateRegistration(invocationPlugins, Class.class)) { + lr.register(new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { + return false; + } + }, "isAnonymousClass", Receiver.class); + } + assertNotIsEmpty(invocationPlugins); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -60,14 +60,16 @@ longArrayBaseOffset = UNSAFE.arrayBaseOffset(long[].class); } + private static final long ARRAY_LONG_BASE_OFFSET = Unsafe.ARRAY_LONG_BASE_OFFSET; + public static long test1Snippet(double a) { final Object m = Memory; if (a > 0) { - UNSAFE.putDouble(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, a); + UNSAFE.putDouble(m, ARRAY_LONG_BASE_OFFSET, a); } else { - SideEffectL = UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); + SideEffectL = UNSAFE.getLong(m, ARRAY_LONG_BASE_OFFSET); } - return UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); + return UNSAFE.getLong(m, ARRAY_LONG_BASE_OFFSET); } public static class A { @@ -80,14 +82,14 @@ if (c != 0) { long[][] r = a.o; phi = r; - UNSAFE.putDouble(r, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, 12d); + UNSAFE.putDouble(r, ARRAY_LONG_BASE_OFFSET, 12d); } else { long[][] r = a.p; phi = r; - UNSAFE.putLong(r, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, 123); + UNSAFE.putLong(r, ARRAY_LONG_BASE_OFFSET, 123); } GraalDirectives.controlFlowAnchor(); - SideEffectD = UNSAFE.getDouble(phi, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); + SideEffectD = UNSAFE.getDouble(phi, ARRAY_LONG_BASE_OFFSET); return phi; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EscapeAnalysisTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -57,6 +57,7 @@ testEscapeAnalysis("test1Snippet", JavaConstant.forInt(101), false); } + @SuppressWarnings("deprecation") public static int test1Snippet() { Integer x = new Integer(101); return x.intValue(); @@ -87,6 +88,7 @@ testEscapeAnalysis("testMonitorSnippet", JavaConstant.forInt(0), false); } + @SuppressWarnings("deprecation") public static int testMonitorSnippet() { Integer x = new Integer(0); Double y = new Double(0); @@ -110,6 +112,7 @@ * This test case differs from the last one in that it requires inlining within a synchronized * region. */ + @SuppressWarnings("deprecation") public static int testMonitor2Snippet() { Integer x = new Integer(0); Double y = new Double(0); @@ -331,6 +334,7 @@ public volatile Object field; + @SuppressWarnings("deprecation") public int testChangeHandlingSnippet(int a) { Object obj; Integer one = 1; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PEAAssertionsTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -45,6 +45,7 @@ public static Object field; + @SuppressWarnings("deprecation") public static void snippet1(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -55,6 +56,7 @@ test("snippet1", 1); } + @SuppressWarnings("deprecation") public static void snippet2(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -66,6 +68,7 @@ test("snippet2", 1); } + @SuppressWarnings("deprecation") public static void snippet3(int i) { Integer object = new Integer(i); field = object; @@ -77,6 +80,7 @@ test("snippet3", 1); } + @SuppressWarnings("deprecation") public static void snippetHere1(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualizedHere(object); @@ -87,6 +91,7 @@ test("snippetHere1", 1); } + @SuppressWarnings("deprecation") public static void snippetHere2(int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualizedHere(object); @@ -98,6 +103,7 @@ test("snippetHere2", 1); } + @SuppressWarnings("deprecation") public static void snippetHere3(int i) { Integer object = new Integer(i); field = object; @@ -130,6 +136,7 @@ test("snippetBoxing2", 1); } + @SuppressWarnings("deprecation") public static void snippetControlFlow1(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -144,6 +151,7 @@ test("snippetControlFlow1", true, 1); } + @SuppressWarnings("deprecation") public static void snippetControlFlow2(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -160,6 +168,7 @@ test("snippetControlFlow2", true, 1); } + @SuppressWarnings("deprecation") public static void snippetControlFlow3(boolean b, int i) { Integer object = new Integer(i); GraalDirectives.ensureVirtualized(object); @@ -177,6 +186,7 @@ test("snippetControlFlow3", true, 1); } + @SuppressWarnings("deprecation") public static void snippetControlFlow4(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -192,6 +202,7 @@ test("snippetControlFlow4", true, 1); } + @SuppressWarnings("deprecation") public static void snippetControlFlow5(boolean b, int i) { Integer object = new Integer(i); if (b) { @@ -212,6 +223,7 @@ Object b; } + @SuppressWarnings("deprecation") public static void snippetIndirect1(boolean b, int i) { Integer object = new Integer(i); TestClass t = new TestClass(); @@ -230,6 +242,7 @@ test("snippetIndirect1", true, 1); } + @SuppressWarnings("deprecation") public static void snippetIndirect2(boolean b, int i) { Integer object = new Integer(i); TestClass t = new TestClass(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisIterationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisIterationTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.core.test.ea; + +import java.lang.ref.WeakReference; +import java.util.List; + +import org.graalvm.compiler.nodes.extended.BoxNode; +import org.graalvm.compiler.nodes.extended.UnboxNode; +import org.graalvm.compiler.nodes.java.StoreFieldNode; +import org.graalvm.compiler.nodes.virtual.CommitAllocationNode; +import org.graalvm.compiler.phases.common.CanonicalizerPhase; +import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; +import org.junit.Assert; +import org.junit.Test; + +public class PartialEscapeAnalysisIterationTest extends EATestBase { + + // remember boxing nodes from before PEA + private List boxNodes; + + @Override + protected void canonicalizeGraph() { + super.canonicalizeGraph(); + boxNodes = graph.getNodes().filter(BoxNode.class).snapshot(); + } + + private static final class AllocatedObject { + private int value; + + AllocatedObject(int value) { + this.value = value; + } + + AllocatedObject() { + // empty + } + } + + public static volatile Object obj1; + public static volatile Double object1 = (double) 123; + public static volatile AllocatedObject object2 = new AllocatedObject(123); + + public static String moveIntoBranchBox(int id) { + Double box = object1 + 1; + if (id == 0) { + obj1 = new WeakReference<>(box); + } + return "value"; + } + + public static String moveIntoBranch(int id) { + AllocatedObject box = new AllocatedObject(object2.value + 1); + if (id == 0) { + obj1 = new WeakReference<>(box); + } + return "value"; + } + + @Test + public void testJMHBlackholePattern() { + /* + * The overall number of allocations in this methods does not change during PEA, but the + * effects still need to be applied since they move the allocation between blocks. + */ + + // test with a boxing object + prepareGraph("moveIntoBranchBox", false); + Assert.assertEquals(1, graph.getNodes().filter(UnboxNode.class).count()); + Assert.assertEquals(1, graph.getNodes().filter(BoxNode.class).count()); + // the boxing needs to be moved into the branch + Assert.assertTrue(graph.getNodes().filter(BoxNode.class).first().next() instanceof StoreFieldNode); + + // test with a normal object + prepareGraph("moveIntoBranch", false); + Assert.assertEquals(1, graph.getNodes().filter(CommitAllocationNode.class).count()); + // the allocation needs to be moved into the branch + Assert.assertTrue(graph.getNodes().filter(CommitAllocationNode.class).first().next() instanceof StoreFieldNode); + } + + public static String noLoopIterationBox(int id) { + Double box = object1 + 1; + for (int i = 0; i < 100; i++) { + if (id == i) { + obj1 = new WeakReference<>(box); + } + } + return "value"; + } + + public static String noLoopIteration(int id) { + AllocatedObject box = new AllocatedObject(object2.value + 1); + for (int i = 0; i < 100; i++) { + if (id == i) { + obj1 = new WeakReference<>(box); + } + } + return "value"; + } + + public static String noLoopIterationEmpty(int id) { + AllocatedObject box = new AllocatedObject(); + for (int i = 0; i < 100; i++) { + if (id == i) { + obj1 = new WeakReference<>(box); + } + } + return "value"; + } + + @Test + public void testNoLoopIteration() { + /* + * PEA should not apply any effects on this method, since it cannot move the allocation into + * the branch anyway (it needs to stay outside the loop). + */ + + // test with a boxing object + prepareGraph("noLoopIterationBox", true); + Assert.assertEquals(1, boxNodes.size()); + Assert.assertTrue(boxNodes.get(0).isAlive()); + + // test with a normal object (needs one iteration to replace NewInstance with + // CommitAllocation) + for (String name : new String[]{"noLoopIterationEmpty", "noLoopIteration"}) { + prepareGraph(name, false); + List allocations = graph.getNodes().filter(CommitAllocationNode.class).snapshot(); + new PartialEscapePhase(true, false, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context); + Assert.assertEquals(1, allocations.size()); + Assert.assertTrue(allocations.get(0).isAlive()); + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -118,6 +118,7 @@ testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class); } + @SuppressWarnings("deprecation") public static Object test3Snippet(int a) { if (a < 0) { TestObject obj = new TestObject(1, 2); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/InliningTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -480,7 +480,7 @@ private static final class StaticFinalFields { - private static final Number NumberStaticFinalField = new Integer(1); + private static final Number NumberStaticFinalField = Integer.valueOf(1); private static final SuperClass SuperClassStaticFinalField = new SubClassA(2); private static final FinalSubClass FinalSubClassStaticFinalField = new FinalSubClass(3); private static final SingleImplementorInterface SingleImplementorStaticFinalField = new SubClassA(4); @@ -492,7 +492,7 @@ private static final class FinalFields { - private final Number numberFinalField = new Integer(1); + private final Number numberFinalField = Integer.valueOf(1); private final SuperClass superClassFinalField = new SubClassA(2); private final FinalSubClass finalSubClassFinalField = new FinalSubClass(3); private final SingleImplementorInterface singleImplementorFinalField = new SubClassA(4); @@ -504,7 +504,7 @@ private static final class Fields { - private Number numberField = new Integer(1); + private Number numberField = Integer.valueOf(1); private SuperClass superClassField = new SubClassA(2); private FinalSubClass finalSubClassField = new FinalSubClass(3); private SingleImplementorInterface singleImplementorField = new SubClassA(4); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,10 @@ import org.graalvm.compiler.phases.tiers.PhaseContext; import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase; import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; + +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import jdk.vm.ci.meta.ResolvedJavaMethod; import sun.misc.Unsafe; @@ -57,7 +60,8 @@ public static int[] Memory = new int[]{0}; public static void recursiveLoopMethodUnsafeLoad(int a) { - if (UNSAFE.getInt(Memory, (long) Unsafe.ARRAY_INT_BASE_OFFSET) == 0) { + long arrayIntBaseOffset = Unsafe.ARRAY_INT_BASE_OFFSET; + if (UNSAFE.getInt(Memory, arrayIntBaseOffset) == 0) { return; } for (int i = 0; i < a; i++) { @@ -87,17 +91,19 @@ private static int InliningCountLowerBound = 1; private static int InliningCountUpperBound = 32; - @Test(timeout = 120_000) + @Rule public TestRule timeout = createTimeoutSeconds(120); + + @Test public void inlineDirectRecursiveLoopCallUnsafeLoad() { testAndTime("recursiveLoopMethodUnsafeLoad"); } - @Test(timeout = 120_000) + @Test public void inlineDirectRecursiveLoopCallFieldLoad() { testAndTime("recursiveLoopMethodFieldLoad"); } - @Test(timeout = 120_000) + @Test public void inlineDirectRecursiveLoopCallNoReads() { testAndTime("recursiveLoopMethod"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Fri Aug 17 13:20:53 2018 -0700 @@ -120,6 +120,7 @@ assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class)); } + @SuppressWarnings("deprecation") static void test03Entry() { Data data = new Data(); data.f = new Integer(42); @@ -147,6 +148,7 @@ assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class)); } + @SuppressWarnings("deprecation") static void test04Entry() { Data data = null; for (int i = 0; i < 2; i++) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java Fri Aug 17 13:20:53 2018 -0700 @@ -84,6 +84,8 @@ */ ExitVM; + private static final ExceptionAction[] VALUES = values(); + /** * Gets the action that is one level less verbose than this action, bottoming out at the * least verbose action. @@ -91,7 +93,7 @@ ExceptionAction quieter() { assert ExceptionAction.Silent.ordinal() == 0; int index = Math.max(ordinal() - 1, 0); - return values()[index]; + return VALUES[index]; } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Fri Aug 17 13:20:53 2018 -0700 @@ -71,7 +71,6 @@ import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractEndNode; import org.graalvm.compiler.nodes.AbstractMergeNode; -import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizingNode; import org.graalvm.compiler.nodes.DirectCallTargetNode; import org.graalvm.compiler.nodes.FixedNode; @@ -284,13 +283,6 @@ return values.toArray(new Value[values.size()]); } - /** - * @return {@code true} if object constant to stack moves are supported. - */ - protected boolean allowObjectConstantToStackMove() { - return true; - } - private Value[] createPhiOut(AbstractMergeNode merge, AbstractEndNode pred) { List values = new ArrayList<>(); for (PhiNode phi : merge.valuePhis()) { @@ -303,7 +295,7 @@ * new Variable. */ value = gen.emitMove(value); - } else if (!allowObjectConstantToStackMove() && node instanceof ConstantNode && !LIRKind.isValue(value)) { + } else if (node.isConstant() && !gen.getSpillMoveFactory().allowConstantToStackMove(node.asConstant()) && !LIRKind.isValue(value)) { /* * Some constants are not allowed as inputs for PHIs in certain backends. Explicitly * create a copy of this value to force it into a register. The new variable is only diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TimerKeyImpl.java Fri Aug 17 13:20:53 2018 -0700 @@ -109,7 +109,7 @@ return TimeUnit.NANOSECONDS; } - final class Timer extends CloseableCounter implements DebugCloseable { + static final class Timer extends CloseableCounter implements DebugCloseable { final DebugContext debug; Timer(AccumulatedKey counter, DebugContext debug) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphSnippetTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -31,6 +31,7 @@ import org.junit.Test; public class GraphSnippetTest { + @SuppressWarnings("deprecation") @Test public void dumpTheFile() throws Exception { Class snippets = null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Fri Aug 17 13:20:53 2018 -0700 @@ -1216,7 +1216,8 @@ // More strict node-type-specific check if (performConsistencyCheck) { - node.verifySourcePosition(); + // Disabled due to GR-10445. + // node.verifySourcePosition(); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeCallerOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeCallerOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeCallerOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotEpilogueOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotEpilogueOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotEpilogueOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -29,6 +29,7 @@ import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall; import static jdk.vm.ci.meta.Value.ILLEGAL; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRESS; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE_ONLY_AFTER_EXCEPTION; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF; import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C; @@ -75,15 +76,15 @@ RegisterValue exception = r0.asValue(LIRKind.reference(word)); RegisterValue exceptionPc = r3.asValue(LIRKind.value(word)); CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc); - register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, exceptionCc, null, NOT_REEXECUTABLE, any())); - register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, null, NOT_REEXECUTABLE, any())); + register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, REEXECUTABLE_ONLY_AFTER_EXCEPTION, exceptionCc, null, any())); + register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, REEXECUTABLE_ONLY_AFTER_EXCEPTION, exceptionCc, null, any())); // These stubs do callee saving if (config.useCRC32Intrinsics) { - registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } if (config.useCRC32CIntrinsics) { - registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } super.initialize(providers, options); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotReturnOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotReturnOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotReturnOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotUnwindOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotUnwindOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotUnwindOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/CompressedNullCheckTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/CompressedNullCheckTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/CompressedNullCheckTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -76,7 +76,7 @@ @Test public void implicit() { - testImplicit(new Integer(1)); + testImplicit(Integer.valueOf(1)); } @Test @@ -86,7 +86,7 @@ @Test public void explicit() { - testExplicit(new Integer(1)); + testExplicit(Integer.valueOf(1)); } @Test diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -225,7 +225,7 @@ public void test() { HotSpotProviders providers = (HotSpotProviders) getProviders(); HotSpotForeignCallsProviderImpl foreignCalls = (HotSpotForeignCallsProviderImpl) providers.getForeignCalls(); - HotSpotForeignCallLinkage linkage = foreignCalls.registerStubCall(TEST_STUB, true, HotSpotForeignCallLinkage.Transition.LEAF_NOFP); + HotSpotForeignCallLinkage linkage = foreignCalls.registerStubCall(TEST_STUB, HotSpotForeignCallLinkage.Transition.LEAF_NOFP, HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE); linkage.setCompiledStub(new TestStub(getInitialOptions(), providers, linkage)); runTest("testStub"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,14 +32,12 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry; -import jdk.vm.ci.amd64.AMD64.CPUFeature; import jdk.internal.vm.compiler.collections.EconomicSet; import org.graalvm.compiler.asm.Assembler; import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.core.amd64.AMD64NodeMatchRules; import org.graalvm.compiler.core.common.CompilationIdentifier; @@ -199,11 +197,7 @@ @Override protected Assembler createAssembler(FrameMap frameMap) { - if (((AMD64) getTarget().arch).getFeatures().contains(CPUFeature.AVX)) { - return new AMD64VectorAssembler(getTarget()); - } else { - return new AMD64MacroAssembler(getTarget()); - } + return new AMD64MacroAssembler(getTarget()); } @Override diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -31,6 +31,8 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER; import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRESS; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE_ONLY_AFTER_EXCEPTION; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP; @@ -87,23 +89,23 @@ RegisterValue exception = rax.asValue(LIRKind.reference(word)); RegisterValue exceptionPc = rdx.asValue(LIRKind.value(word)); CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc); - register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, exceptionCc, null, NOT_REEXECUTABLE, any())); - register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, exceptionCc, null, NOT_REEXECUTABLE, any())); + register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, exceptionCc, null, any())); + register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, exceptionCc, null, any())); - link(new AMD64MathStub(ARITHMETIC_LOG_STUB, options, providers, registerStubCall(ARITHMETIC_LOG_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_LOG10_STUB, options, providers, registerStubCall(ARITHMETIC_LOG10_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_SIN_STUB, options, providers, registerStubCall(ARITHMETIC_SIN_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_COS_STUB, options, providers, registerStubCall(ARITHMETIC_COS_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_TAN_STUB, options, providers, registerStubCall(ARITHMETIC_TAN_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_EXP_STUB, options, providers, registerStubCall(ARITHMETIC_EXP_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); - link(new AMD64MathStub(ARITHMETIC_POW_STUB, options, providers, registerStubCall(ARITHMETIC_POW_STUB, REEXECUTABLE, LEAF, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_LOG_STUB, options, providers, registerStubCall(ARITHMETIC_LOG_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_LOG10_STUB, options, providers, registerStubCall(ARITHMETIC_LOG10_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_SIN_STUB, options, providers, registerStubCall(ARITHMETIC_SIN_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_COS_STUB, options, providers, registerStubCall(ARITHMETIC_COS_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_TAN_STUB, options, providers, registerStubCall(ARITHMETIC_TAN_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_EXP_STUB, options, providers, registerStubCall(ARITHMETIC_EXP_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); + link(new AMD64MathStub(ARITHMETIC_POW_STUB, options, providers, registerStubCall(ARITHMETIC_POW_STUB, LEAF, REEXECUTABLE, NO_LOCATIONS))); if (config.useCRC32Intrinsics) { // This stub does callee saving - registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } if (config.useCRC32CIntrinsics) { - registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } super.initialize(providers, options); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackend.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -33,6 +33,7 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER; import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRESS; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE_ONLY_AFTER_EXCEPTION; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP; import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C; @@ -83,15 +84,16 @@ RegisterValue incomingExceptionPc = i1.asValue(LIRKind.value(word)); CallingConvention outgoingExceptionCc = new CallingConvention(0, ILLEGAL, outgoingException, outgoingExceptionPc); CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc); - register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, any())); - register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, any())); + register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, outgoingExceptionCc, incomingExceptionCc, any())); + register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, outgoingExceptionCc, + incomingExceptionCc, any())); if (config.useCRC32Intrinsics) { // This stub does callee saving - registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } if (config.useCRC32CIntrinsics) { - registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any()); + registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); } super.initialize(providers, options); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotReturnOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotReturnOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotReturnOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -274,7 +274,7 @@ @Test public void testCopyRows() { Object[][] rows = {{"a1", "a2", "a3", "a4"}, {"b1", "b2", "b3", "b4"}, {"c1", "c2", "c3", "c4"}}; - test("copyRows", rows, 4, new Integer(rows.length)); + test("copyRows", rows, 4, Integer.valueOf(rows.length)); } public static Object[][] copyRows(Object[][] rows, int rowSize, Integer rowCount) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Fri Aug 17 13:20:53 2018 -0700 @@ -343,14 +343,11 @@ add(toBeInvestigated, "java/lang/StringCoding.hasNegatives([BII)Z", "java/lang/StringCoding.implEncodeISOArray([BI[BII)I", - "java/lang/StringLatin1.equals([B[B)Z", - "java/lang/StringLatin1.indexOf([BI[BII)I", "java/lang/StringLatin1.indexOf([B[B)I", "java/lang/StringLatin1.inflate([BI[BII)V", "java/lang/StringLatin1.inflate([BI[CII)V", "java/lang/StringUTF16.compress([BI[BII)I", "java/lang/StringUTF16.compress([CI[BII)I", - "java/lang/StringUTF16.equals([B[B)Z", "java/lang/StringUTF16.getChar([BI)C", "java/lang/StringUTF16.getChars([BII[CI)V", "java/lang/StringUTF16.indexOf([BI[BII)I", @@ -360,6 +357,10 @@ "java/lang/StringUTF16.indexOfLatin1([B[B)I", "java/lang/StringUTF16.putChar([BII)V", "java/lang/StringUTF16.toBytes([CII)[B"); + // These are handled through an intrinsic for String.equals itself + add(ignore, + "java/lang/StringLatin1.equals([B[B)Z", + "java/lang/StringUTF16.equals([B[B)Z"); } if (isJDK10OrHigher()) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotMethodSubstitutionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -231,7 +231,7 @@ */ @Test public void testCast() { - test("testCastSnippet", 1, new Integer(1)); + test("testCastSnippet", 1, Integer.valueOf(1)); } /** diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotStackIntrospectionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,9 @@ import org.graalvm.compiler.test.GraalTest; import org.junit.Assume; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.code.InvalidInstalledCodeException; @@ -44,6 +46,8 @@ */ public class HotSpotStackIntrospectionTest extends HotSpotGraalCompilerTest { + @Rule public TestRule timeout = createTimeoutSeconds(20); + static StackIntrospection stackIntrospection = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getStackIntrospection(); static volatile int v; @@ -74,14 +78,14 @@ return a; } - @Test(timeout = 20000) + @Test public void run() throws InvalidInstalledCodeException { // The JDK9 bits are currently broken Assume.assumeTrue(GraalTest.Java8OrEarlier); test("testSnippet"); } - @Test(timeout = 20000) + @Test public void runSynchronized() throws InvalidInstalledCodeException { // The JDK9 bits are currently broken Assume.assumeTrue(GraalTest.Java8OrEarlier); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -177,7 +177,7 @@ */ @Test public void test6() throws Exception { - test2("testUnsafeLoad", UNSAFE, wr, new Long(referentOffset), null); + test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(referentOffset), null); } /** @@ -186,7 +186,7 @@ */ @Test public void test7() throws Exception { - test2("testUnsafeLoad", UNSAFE, con, new Long(referentOffset), null); + test2("testUnsafeLoad", UNSAFE, con, Long.valueOf(referentOffset), null); } /** @@ -196,7 +196,7 @@ */ @Test public void test8() throws Exception { - test2("testUnsafeLoad", UNSAFE, wr, new Long(config.useCompressedOops ? 20 : 32), null); + test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(config.useCompressedOops ? 20 : 32), null); } /** @@ -206,7 +206,7 @@ */ @Test public void test10() throws Exception { - test2("testUnsafeLoad", UNSAFE, wr, new Long(config.useCompressedOops ? 6 : 8), new Integer(config.useCompressedOops ? 6 : 8)); + test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(config.useCompressedOops ? 6 : 8), Integer.valueOf(config.useCompressedOops ? 6 : 8)); } /** @@ -216,7 +216,7 @@ */ @Test public void test9() throws Exception { - test2("testUnsafeLoad", UNSAFE, wr, new Long(config.useCompressedOops ? 10 : 16), new Integer(config.useCompressedOops ? 10 : 16)); + test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(config.useCompressedOops ? 10 : 16), Integer.valueOf(config.useCompressedOops ? 10 : 16)); } static Object[] src = new Object[1]; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java Fri Aug 17 13:20:53 2018 -0700 @@ -34,6 +34,7 @@ import java.util.stream.Collectors; import jdk.internal.vm.compiler.collections.EconomicMap; +import org.graalvm.compiler.core.common.SuppressFBWarnings; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.lir.phases.LIRPhase; @@ -168,6 +169,7 @@ /** * @return sorted list of {@link CompilerConfigurationFactory}s */ + @SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "false positive on dead store to `candidates`") private static List getAllCandidates() { List candidates = new ArrayList<>(); for (CompilerConfigurationFactory candidate : GraalServices.load(CompilerConfigurationFactory.class)) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri Aug 17 13:20:53 2018 -0700 @@ -575,8 +575,6 @@ public final boolean tlabStats = getFlag("TLABStats", Boolean.class); - public final boolean useFastTLABRefill = versioned.useFastTLABRefill; - // FIXME This is only temporary until the GC code is changed. public final boolean inlineContiguousAllocationSupported = getFieldValue("CompilerToVM::Data::_supports_inline_contig_alloc", Boolean.class); public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**"); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,6 +24,9 @@ package org.graalvm.compiler.hotspot; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; @@ -41,6 +44,20 @@ super(store); assert this instanceof GraalHotSpotVMConfig; versioned = new GraalHotSpotVMConfigVersioned(store); + assert checkVersioned(); + } + + private boolean checkVersioned() { + Class c = versioned.getClass(); + for (Field field : c.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (!Modifier.isStatic(modifiers)) { + // javac inlines non-static final fields which means + // versioned values are ignored in non-flattened Graal + assert !Modifier.isFinal(modifiers) : "Non-static field in " + c.getName() + " must not be final: " + field.getName(); + } + } + return true; } /** diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java Fri Aug 17 13:20:53 2018 -0700 @@ -48,45 +48,42 @@ } // JSK-8132287 - final boolean inlineNotify = initInlineNotify(); + boolean inlineNotify = initInlineNotify(); // JDK-8073583 - final boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class); + boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class); // JDK-8046936 - final int javaThreadReservedStackActivationOffset = getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address"); - final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2"); - final long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address"); - final long enableStackReservedZoneAddress = getAddress("SharedRuntime::enable_stack_reserved_zone"); + int javaThreadReservedStackActivationOffset = getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address"); + int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2"); + long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address"); + long enableStackReservedZoneAddress = getAddress("SharedRuntime::enable_stack_reserved_zone"); // JDK-8135085 - final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2"); + int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2"); // JDK-8151956 - final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*"); + int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*"); // JDK-8059606 - final int invocationCounterIncrement = getConstant("InvocationCounter::count_increment", Integer.class); - final int invocationCounterShift = getConstant("InvocationCounter::count_shift", Integer.class); + int invocationCounterIncrement = getConstant("InvocationCounter::count_increment", Integer.class); + int invocationCounterShift = getConstant("InvocationCounter::count_shift", Integer.class); // JDK-8195142 - final byte dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class); - final byte g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class); + byte dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class); + byte g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class); // JDK-8201318 - final int g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class); - final int g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class); - final int g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class); - final int g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class); - final int g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class); + int g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class); + int g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class); + int g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class); + int g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class); + int g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class); // JDK-8033552 - final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, "HeapWord* volatile*"); + long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, "HeapWord* volatile*"); // JDK-8015774 - final long codeCacheLowBound = getFieldValue("CodeCache::_low_bound", Long.class, "address"); - final long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class, "address"); - - // JDK-8205105 - boolean useFastTLABRefill = false; + long codeCacheLowBound = getFieldValue("CodeCache::_low_bound", Long.class, "address"); + long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class, "address"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java Fri Aug 17 13:20:53 2018 -0700 @@ -83,12 +83,48 @@ } /** + * Constants specifying when a foreign call or stub call is re-executable. + */ + enum Reexecutability { + /** + * Denotes a call that cannot be re-executed. If an exception is raised, the call is + * deoptimized and the exception is passed on to be dispatched. If the call can throw an + * exception it needs to have a precise frame state. + */ + NOT_REEXECUTABLE, + + /** + * Denotes a call that can only be re-executed if it returns with a pending exception. This + * type of call models a function that may throw exceptions before any side effects happen. + * In this case if an exception is raised the call may be deoptimized and reexecuted. It + * also means that while the call has side effects and may deoptimize it doesn't necessarily + * need to have a precise frame state. + */ + REEXECUTABLE_ONLY_AFTER_EXCEPTION, + + /** + * Denotes a call that can always be re-executed. If an exception is raised by the call it + * may be cleared, compiled code deoptimized and reexecuted. Since the call has no side + * effects it is assumed that the same exception will be thrown. + */ + REEXECUTABLE + } + + /** * Sentinel marker for a computed jump address. */ long JUMP_ADDRESS = 0xDEADDEADBEEFBEEFL; + /** + * Determines if the call has side effects. + */ boolean isReexecutable(); + /** + * Determines if the call returning a pending exception implies it is side-effect free. + */ + boolean isReexecutableOnlyAfterException(); + LocationIdentity[] getKilledLocations(); void setCompiledStub(Stub stub); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java Fri Aug 17 13:20:53 2018 -0700 @@ -90,7 +90,7 @@ */ private final LocationIdentity[] killedLocations; - private final boolean reexecutable; + private final Reexecutability reexecutability; /** * Creates a {@link HotSpotForeignCallLinkage}. @@ -102,17 +102,18 @@ * @param outgoingCcType outgoing (caller) calling convention type * @param incomingCcType incoming (callee) calling convention type (can be null) * @param transition specifies if this is a {@linkplain #needsDebugInfo() leaf} call - * @param reexecutable specifies if the call can be re-executed without (meaningful) side + * @param reexecutability specifies if the call can be re-executed without (meaningful) side * effects. Deoptimization will not return to a point before a call that cannot be * re-executed. * @param killedLocations the memory locations killed by the call */ public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, WordTypes wordTypes, HotSpotForeignCallsProvider foreignCalls, - ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, boolean reexecutable, + ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, Reexecutability reexecutability, LocationIdentity... killedLocations) { CallingConvention outgoingCc = createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, outgoingCcType); CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, incomingCcType); - HotSpotForeignCallLinkageImpl linkage = new HotSpotForeignCallLinkageImpl(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations); + HotSpotForeignCallLinkageImpl linkage = new HotSpotForeignCallLinkageImpl(descriptor, address, effect, transition, reexecutability, outgoingCc, incomingCc, + killedLocations); if (outgoingCcType == HotSpotCallingConventionType.NativeCall) { linkage.temporaries = foreignCalls.getNativeABICallerSaveRegisters(); } @@ -143,17 +144,17 @@ return javaType; } - public HotSpotForeignCallLinkageImpl(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention outgoingCallingConvention, - CallingConvention incomingCallingConvention, boolean reexecutable, LocationIdentity... killedLocations) { + public HotSpotForeignCallLinkageImpl(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, Reexecutability reexecutability, + CallingConvention outgoingCallingConvention, CallingConvention incomingCallingConvention, LocationIdentity... killedLocations) { super(address); this.descriptor = descriptor; this.address = address; this.effect = effect; this.transition = transition; + this.reexecutability = reexecutability; assert outgoingCallingConvention != null : "only incomingCallingConvention can be null"; this.outgoingCallingConvention = outgoingCallingConvention; this.incomingCallingConvention = incomingCallingConvention != null ? incomingCallingConvention : outgoingCallingConvention; - this.reexecutable = reexecutable; this.killedLocations = killedLocations; } @@ -174,7 +175,12 @@ @Override public boolean isReexecutable() { - return reexecutable; + return reexecutability == Reexecutability.REEXECUTABLE; + } + + @Override + public boolean isReexecutableOnlyAfterException() { + return reexecutability == Reexecutability.REEXECUTABLE_ONLY_AFTER_EXCEPTION; } @Override diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Fri Aug 17 13:20:53 2018 -0700 @@ -29,10 +29,6 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining; import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM; -import static org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC.CMS; -import static org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC.G1; -import static org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC.Parallel; -import static org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC.Serial; import java.util.ArrayList; import java.util.EnumMap; @@ -135,40 +131,6 @@ private final Map compilationProblemsPerAction; /** - * Constants denoting the GC algorithms available in HotSpot. - */ - public enum HotSpotGC { - Serial("UseSerialGC"), - Parallel("UseParallelGC", "UseParallelOldGC", "UseParNewGC"), - CMS("UseConcMarkSweepGC"), - G1("UseG1GC"), - Epsilon("UseEpsilonGC"), - Z("UseZGC"); - - HotSpotGC(String... flags) { - this.flags = flags; - } - - private final String[] flags; - - public boolean isSelected(GraalHotSpotVMConfig config) { - for (String flag : flags) { - final boolean notPresent = false; - if (config.getFlag(flag, Boolean.class, notPresent)) { - return true; - } - } - return false; - } - - } - - /** - * Set of GCs supported by Graal. - */ - private static final HotSpotGC[] SUPPORTED_GCS = {Serial, Parallel, CMS, G1}; - - /** * @param nameQualifier a qualifier to be added to this runtime's {@linkplain #getName() name} * @param compilerConfigurationFactory factory for the compiler configuration * {@link CompilerConfigurationFactory#selectFactory(String, OptionValues)} @@ -187,24 +149,7 @@ } OptionValues options = optionsRef.get(); - HotSpotGC selected = null; - for (HotSpotGC gc : SUPPORTED_GCS) { - if (gc.isSelected(config)) { - selected = gc; - break; - } - } - if (selected == null) { - for (HotSpotGC gc : HotSpotGC.values()) { - if (gc.isSelected(config)) { - selected = gc; - break; - } - } - String unsupportedGC = selected != null ? selected.name() : ""; - throw new GraalError(unsupportedGC + " garbage collector is not supported by Graal"); - } - garbageCollector = selected; + garbageCollector = getSelectedGC(); outputDirectory = new DiagnosticsOutputDirectory(options); compilationProblemsPerAction = new EnumMap<>(ExceptionAction.class); @@ -265,6 +210,54 @@ bootstrapJVMCI = config.getFlag("BootstrapJVMCI", Boolean.class); } + /** + * Constants denoting the GC algorithms available in HotSpot. + */ + public enum HotSpotGC { + // Supported GCs + Serial(true, "UseSerialGC"), + Parallel(true, "UseParallelGC", "UseParallelOldGC", "UseParNewGC"), + CMS(true, "UseConcMarkSweepGC"), + G1(true, "UseG1GC"), + + // Unsupported GCs + Epsilon(false, "UseEpsilonGC"), + Z(false, "UseZGC"); + + HotSpotGC(boolean supported, String... flags) { + this.supported = supported; + this.flags = flags; + } + + final boolean supported; + private final String[] flags; + + public boolean isSelected(GraalHotSpotVMConfig config) { + for (String flag : flags) { + final boolean notPresent = false; + if (config.getFlag(flag, Boolean.class, notPresent)) { + return true; + } + } + return false; + } + + } + + private HotSpotGC getSelectedGC() throws GraalError { + for (HotSpotGC gc : HotSpotGC.values()) { + if (gc.isSelected(config)) { + if (!gc.supported) { + throw new GraalError(gc.name() + " garbage collector is not supported by Graal"); + } + return gc; + } + } + // As of JDK 9, exactly one GC flag is guaranteed to be selected. + // On JDK 8, the default GC is Serial when no GC flag is true. + return HotSpotGC.Serial; + } + private HotSpotBackend registerBackend(HotSpotBackend backend) { Class arch = backend.getTarget().arch.getClass(); HotSpotBackend oldValue = backends.put(arch, backend); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerationResult.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Fri Aug 17 13:20:53 2018 -0700 @@ -39,7 +39,7 @@ class JVMCIVersionCheck { private static final int JVMCI8_MIN_MAJOR_VERSION = 0; - private static final int JVMCI8_MIN_MINOR_VERSION = 29; + private static final int JVMCI8_MIN_MINOR_VERSION = 46; private static void failVersionCheck(boolean exit, String reason, Object... args) { Formatter errorMessage = new Formatter().format(reason, args); @@ -52,7 +52,7 @@ if (System.getProperty("java.specification.version").compareTo("1.9") < 0) { errorMessage.format("Download the latest JVMCI JDK 8 from http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html"); } else { - errorMessage.format("Download the latest JDK 9 build from https://jdk9.java.net/download/"); + errorMessage.format("Download JDK 11 or later."); } String value = System.getenv("JVMCI_VERSION_CHECK"); if ("warn".equals(value)) { @@ -69,8 +69,9 @@ static void check(boolean exitOnFailure) { // Don't use regular expressions to minimize Graal startup time + String javaSpecVersion = System.getProperty("java.specification.version"); String vmVersion = System.getProperty("java.vm.version"); - if (System.getProperty("java.specification.version").compareTo("1.9") < 0) { + if (javaSpecVersion.compareTo("1.9") < 0) { int start = vmVersion.indexOf("-jvmci-"); if (start >= 0) { start += "-jvmci-".length(); @@ -107,18 +108,28 @@ } failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" + "Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion); + } else if (javaSpecVersion.compareTo("11") < 0) { + failVersionCheck(exitOnFailure, "Graal is not compatible with the JVMCI API in JDK 9 and 10.%n"); } else { if (vmVersion.contains("SNAPSHOT")) { - // The snapshot of http://hg.openjdk.java.net/jdk9/dev tip is expected to work return; } if (vmVersion.contains("internal")) { // Allow local builds return; } - if (vmVersion.startsWith("9-ea")) { - failVersionCheck(exitOnFailure, "This version of Graal is not compatible with JDK 9 Early Access builds.%n"); - return; + if (vmVersion.startsWith("11-ea+")) { + String buildString = vmVersion.substring("11-ea+".length()); + try { + int build = Integer.parseInt(buildString); + if (build < 20) { + failVersionCheck(exitOnFailure, "Graal requires build 20 or later of JDK 11 early access binary, got build %d.%n", build); + return; + } + } catch (NumberFormatException e) { + failVersionCheck(exitOnFailure, "Could not parse the JDK 11 early access build number from java.vm.version property: %s.%n", vmVersion); + return; + } } else { // Graal is compatible with all JDK versions as of 9 GA. } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/PrintStreamOptionKey.java Fri Aug 17 13:20:53 2018 -0700 @@ -31,6 +31,7 @@ import java.io.PrintStream; import java.util.List; +import org.graalvm.compiler.core.common.SuppressFBWarnings; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.serviceprovider.GraalServices; @@ -108,6 +109,7 @@ * Gets the print stream configured by this option. If no file is configured, the print stream * will output to HotSpot's {@link HotSpotJVMCIRuntime#getLogStream() log} stream. */ + @SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "false positive on dead store to `ps`") public PrintStream getStream(OptionValues options) { String nameTemplate = getValue(options); if (nameTemplate != null) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -669,6 +669,8 @@ runtimeCalls.put(BytecodeExceptionKind.NULL_POINTER, new ForeignCallDescriptor("createNullPointerException", NullPointerException.class)); runtimeCalls.put(BytecodeExceptionKind.OUT_OF_BOUNDS, new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class, int.class)); runtimeCalls.put(BytecodeExceptionKind.DIVISION_BY_ZERO, new ForeignCallDescriptor("createDivisionByZeroException", ArithmeticException.class)); + runtimeCalls.put(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW, new ForeignCallDescriptor("createIntegerExactOverflowException", ArithmeticException.class)); + runtimeCalls.put(BytecodeExceptionKind.LONG_EXACT_OVERFLOW, new ForeignCallDescriptor("createLongExactOverflowException", ArithmeticException.class)); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java Fri Aug 17 13:20:53 2018 -0700 @@ -36,6 +36,7 @@ import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl; @@ -102,14 +103,15 @@ * Creates and registers the details for linking a foreign call to a {@link Stub}. * * @param descriptor the signature of the call to the stub - * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side - * effects. Deoptimization will not return to a point before a stub call that cannot - * be re-executed. * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call + * @param reexecutability specifies if the stub call can be re-executed without (meaningful) + * side effects. Deoptimization will not return to a point before a stub call that + * cannot be re-executed. * @param killedLocations the memory locations killed by the stub call */ - public HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) { - return register(HotSpotForeignCallLinkageImpl.create(metaAccess, codeCache, wordTypes, this, descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, + public HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, Transition transition, Reexecutability reexecutability, + LocationIdentity... killedLocations) { + return register(HotSpotForeignCallLinkageImpl.create(metaAccess, codeCache, wordTypes, this, descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutability, killedLocations)); } @@ -122,17 +124,17 @@ * @param effect specifies if the call destroys or preserves all registers (apart from * temporaries which are always destroyed) * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call - * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) + * @param reexecutability specifies if the foreign call can be re-executed without (meaningful) * side effects. Deoptimization will not return to a point before a foreign call that * cannot be re-executed. * @param killedLocations the memory locations killed by the foreign call */ public HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition, - boolean reexecutable, LocationIdentity... killedLocations) { + Reexecutability reexecutability, LocationIdentity... killedLocations) { Class resultType = descriptor.getResultType(); assert address != 0; assert transition != SAFEPOINT || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor; - return register(HotSpotForeignCallLinkageImpl.create(metaAccess, codeCache, wordTypes, this, descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations)); + return register(HotSpotForeignCallLinkageImpl.create(metaAccess, codeCache, wordTypes, this, descriptor, address, effect, outgoingCcType, null, transition, reexecutability, killedLocations)); } /** @@ -143,14 +145,14 @@ * @param prependThread true if the JavaThread value for the current thread is to be prepended * to the arguments for the call to {@code address} * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call - * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) + * @param reexecutability specifies if the foreign call can be re-executed without (meaningful) * side effects. Deoptimization will not return to a point before a foreign call that * cannot be re-executed. * @param killedLocations the memory locations killed by the foreign call */ - public void linkForeignCall(OptionValues options, HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable, - LocationIdentity... killedLocations) { - ForeignCallStub stub = new ForeignCallStub(options, jvmciRuntime, providers, address, descriptor, prependThread, transition, reexecutable, killedLocations); + public void linkForeignCall(OptionValues options, HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, + Reexecutability reexecutability, LocationIdentity... killedLocations) { + ForeignCallStub stub = new ForeignCallStub(options, jvmciRuntime, providers, address, descriptor, prependThread, transition, reexecutability, killedLocations); HotSpotForeignCallLinkage linkage = stub.getLinkage(); HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage(); linkage.setCompiledStub(stub); @@ -161,9 +163,6 @@ public static final boolean PREPEND_THREAD = true; public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD; - public static final boolean REEXECUTABLE = true; - public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE; - public static final LocationIdentity[] NO_LOCATIONS = {}; @Override diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -59,6 +59,9 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER; import static org.graalvm.compiler.hotspot.HotSpotBackend.VM_ERROR; import static org.graalvm.compiler.hotspot.HotSpotBackend.WRONG_METHOD_HANDLER; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE_ONLY_AFTER_EXCEPTION; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF; @@ -114,6 +117,8 @@ import org.graalvm.compiler.hotspot.stubs.CreateExceptionStub; import org.graalvm.compiler.hotspot.stubs.DivisionByZeroExceptionStub; import org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub; +import org.graalvm.compiler.hotspot.stubs.IntegerExactOverflowExceptionStub; +import org.graalvm.compiler.hotspot.stubs.LongExactOverflowExceptionStub; import org.graalvm.compiler.hotspot.stubs.NewArrayStub; import org.graalvm.compiler.hotspot.stubs.NewInstanceStub; import org.graalvm.compiler.hotspot.stubs.NullPointerExceptionStub; @@ -271,7 +276,7 @@ registerForeignCall(ARITHMETIC_FREM, c.fremAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(ARITHMETIC_DREM, c.dremAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any()); + registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any()); registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, any()); @@ -287,33 +292,35 @@ registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS); registerForeignCall(ASSERTION_VM_MESSAGE_C, c.vmMessageAddress, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - link(new NewInstanceStub(options, providers, registerStubCall(NEW_INSTANCE, REEXECUTABLE, SAFEPOINT, TLAB_TOP_LOCATION, TLAB_END_LOCATION))); - link(new NewArrayStub(options, providers, registerStubCall(NEW_ARRAY, REEXECUTABLE, SAFEPOINT, TLAB_TOP_LOCATION, TLAB_END_LOCATION))); + link(new NewInstanceStub(options, providers, registerStubCall(NEW_INSTANCE, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION))); + link(new NewArrayStub(options, providers, registerStubCall(NEW_ARRAY, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION))); link(new ExceptionHandlerStub(options, providers, foreignCalls.get(EXCEPTION_HANDLER))); - link(new UnwindExceptionToCallerStub(options, providers, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, SAFEPOINT, any()))); - link(new VerifyOopStub(options, providers, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF_NOFP, NO_LOCATIONS))); + link(new UnwindExceptionToCallerStub(options, providers, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()))); + link(new VerifyOopStub(options, providers, registerStubCall(VERIFY_OOP, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS))); EnumMap exceptionRuntimeCalls = DefaultHotSpotLoweringProvider.RuntimeCalls.runtimeCalls; - link(new ArrayStoreExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.ARRAY_STORE), REEXECUTABLE, SAFEPOINT, any()))); - link(new ClassCastExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.CLASS_CAST), REEXECUTABLE, SAFEPOINT, any()))); - link(new NullPointerExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.NULL_POINTER), REEXECUTABLE, SAFEPOINT, any()))); - link(new OutOfBoundsExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.OUT_OF_BOUNDS), REEXECUTABLE, SAFEPOINT, any()))); - link(new DivisionByZeroExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.DIVISION_BY_ZERO), REEXECUTABLE, SAFEPOINT, any()))); + link(new ArrayStoreExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.ARRAY_STORE), SAFEPOINT, REEXECUTABLE, any()))); + link(new ClassCastExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.CLASS_CAST), SAFEPOINT, REEXECUTABLE, any()))); + link(new NullPointerExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.NULL_POINTER), SAFEPOINT, REEXECUTABLE, any()))); + link(new OutOfBoundsExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.OUT_OF_BOUNDS), SAFEPOINT, REEXECUTABLE, any()))); + link(new DivisionByZeroExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.DIVISION_BY_ZERO), SAFEPOINT, REEXECUTABLE, any()))); + link(new IntegerExactOverflowExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW), SAFEPOINT, REEXECUTABLE, any()))); + link(new LongExactOverflowExceptionStub(options, providers, registerStubCall(exceptionRuntimeCalls.get(BytecodeExceptionKind.LONG_EXACT_OVERFLOW), SAFEPOINT, REEXECUTABLE, any()))); - linkForeignCall(options, providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, MARK_WORD_LOCATION); - linkForeignCall(options, providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); - linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); - linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, NOT_REEXECUTABLE, any()); + linkForeignCall(options, providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, MARK_WORD_LOCATION); + linkForeignCall(options, providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); + linkForeignCall(options, providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); + linkForeignCall(options, providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, STACK_INSPECTABLE_LEAF, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); linkForeignCall(options, providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, TLAB_TOP_LOCATION, TLAB_END_LOCATION); - linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); - linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); + linkForeignCall(options, providers, NOTIFY, c.notifyAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); + linkForeignCall(options, providers, NOTIFY_ALL, c.notifyAllAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); linkForeignCall(options, providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE); linkForeignCall(options, providers, DYNAMIC_NEW_INSTANCE, c.dynamicNewInstanceAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE); linkForeignCall(options, providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(options, providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF_NOFP, NOT_REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(options, providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NO_LOCATIONS); linkForeignCall(options, providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF_NOFP, REEXECUTABLE, NO_LOCATIONS); @@ -325,13 +332,13 @@ linkForeignCall(options, providers, RESOLVE_DYNAMIC_INVOKE, cr.resolveDynamicInvoke, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any()); linkForeignCall(options, providers, RESOLVE_KLASS_BY_SYMBOL, cr.resolveKlassBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any()); linkForeignCall(options, providers, RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS, cr.resolveMethodBySymbolAndLoadCounters, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(options, providers, INITIALIZE_KLASS_BY_SYMBOL, cr.initializeKlassBySymbol, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any()); + linkForeignCall(options, providers, INITIALIZE_KLASS_BY_SYMBOL, cr.initializeKlassBySymbol, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); linkForeignCall(options, providers, INVOCATION_EVENT, cr.invocationEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(options, providers, BACKEDGE_EVENT, cr.backedgeEvent, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, NO_LOCATIONS); } // Cannot be a leaf as VM acquires Thread_lock which requires thread_in_vm state - linkForeignCall(options, providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, SAFEPOINT, NOT_REEXECUTABLE, any()); + linkForeignCall(options, providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE_ONLY_AFTER_EXCEPTION, any()); linkForeignCall(options, providers, TEST_DEOPTIMIZE_CALL_INT, c.testDeoptimizeCallInt, PREPEND_THREAD, SAFEPOINT, REEXECUTABLE, any()); @@ -349,32 +356,35 @@ registerCheckcastArraycopyDescriptor(true, c.checkcastArraycopyUninit); registerCheckcastArraycopyDescriptor(false, c.checkcastArraycopy); - registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); - registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); + registerForeignCall(GENERIC_ARRAYCOPY, c.genericArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.any()); + registerForeignCall(UNSAFE_ARRAYCOPY, c.unsafeArraycopy, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.any()); if (c.useMultiplyToLenIntrinsic()) { - registerForeignCall(MULTIPLY_TO_LEN, c.multiplyToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); + registerForeignCall(MULTIPLY_TO_LEN, c.multiplyToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, + NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } if (c.useSHA1Intrinsics()) { - registerForeignCall(SHA_IMPL_COMPRESS, c.sha1ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); + registerForeignCall(SHA_IMPL_COMPRESS, c.sha1ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.any()); } if (c.useSHA256Intrinsics()) { - registerForeignCall(SHA2_IMPL_COMPRESS, c.sha256ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); + registerForeignCall(SHA2_IMPL_COMPRESS, c.sha256ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.any()); } if (c.useSHA512Intrinsics()) { - registerForeignCall(SHA5_IMPL_COMPRESS, c.sha512ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.any()); + registerForeignCall(SHA5_IMPL_COMPRESS, c.sha512ImplCompress, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.any()); } if (c.useMulAddIntrinsic()) { - registerForeignCall(MUL_ADD, c.mulAdd, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); + registerForeignCall(MUL_ADD, c.mulAdd, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } if (c.useMontgomeryMultiplyIntrinsic()) { - registerForeignCall(MONTGOMERY_MULTIPLY, c.montgomeryMultiply, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); + registerForeignCall(MONTGOMERY_MULTIPLY, c.montgomeryMultiply, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, + NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } if (c.useMontgomerySquareIntrinsic()) { - registerForeignCall(MONTGOMERY_SQUARE, c.montgomerySquare, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); + registerForeignCall(MONTGOMERY_SQUARE, c.montgomerySquare, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, + NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } if (c.useSquareToLenIntrinsic()) { - registerForeignCall(SQUARE_TO_LEN, c.squareToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); + registerForeignCall(SQUARE_TO_LEN, c.squareToLen, NativeCall, DESTROYS_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Int)); } if (c.useAESIntrinsics) { @@ -385,9 +395,11 @@ */ try { // These stubs do callee saving - registerForeignCall(ENCRYPT_BLOCK, c.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); - registerForeignCall(DECRYPT_BLOCK, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); - registerForeignCall(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, + registerForeignCall(ENCRYPT_BLOCK, c.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, + NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); + registerForeignCall(DECRYPT_BLOCK, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, + NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); + registerForeignCall(DECRYPT_BLOCK_WITH_ORIGINAL_KEY, c.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); } catch (GraalError e) { if (!(e.getCause() instanceof ClassNotFoundException)) { @@ -396,11 +408,11 @@ } try { // These stubs do callee saving - registerForeignCall(ENCRYPT, c.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, + registerForeignCall(ENCRYPT, c.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); - registerForeignCall(DECRYPT, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, + registerForeignCall(DECRYPT, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); - registerForeignCall(DECRYPT_WITH_ORIGINAL_KEY, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, + registerForeignCall(DECRYPT_WITH_ORIGINAL_KEY, c.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, REEXECUTABLE_ONLY_AFTER_EXCEPTION, NamedLocationIdentity.getArrayLocation(JavaKind.Byte)); } catch (GraalError e) { if (!(e.getCause() instanceof ClassNotFoundException)) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/IntrinsificationPredicate.java Fri Aug 17 11:56:59 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * 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 org.graalvm.compiler.hotspot.meta; - -import java.lang.module.ModuleDescriptor.Requires; - -import jdk.internal.vm.compiler.collections.EconomicSet; -import org.graalvm.compiler.phases.tiers.CompilerConfiguration; - -/** - * Determines if methods in a given class can be intrinsified. - * - * Only classes loaded from the module defining the compiler configuration or any of its transitive - * dependencies can be intrinsified. - * - * This version of the class must be used on JDK 9 or later. - */ -public final class IntrinsificationPredicate { - /** - * Set of modules composed of the module defining the compiler configuration and its transitive - * dependencies. - */ - private final EconomicSet trustedModules; - - IntrinsificationPredicate(CompilerConfiguration compilerConfiguration) { - trustedModules = EconomicSet.create(); - Module compilerConfigurationModule = compilerConfiguration.getClass().getModule(); - if (compilerConfigurationModule.getDescriptor().isAutomatic()) { - throw new IllegalArgumentException(String.format("The module '%s' defining the Graal compiler configuration class '%s' must not be an automatic module", - compilerConfigurationModule.getName(), compilerConfiguration.getClass().getName())); - } - trustedModules.add(compilerConfigurationModule); - for (Requires require : compilerConfigurationModule.getDescriptor().requires()) { - for (Module module : compilerConfigurationModule.getLayer().modules()) { - if (module.getName().equals(require.name())) { - trustedModules.add(module); - } - } - } - } - - public boolean apply(Class declaringClass) { - Module module = declaringClass.getModule(); - return trustedModules.contains(module); - } -} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ClassGetHubNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -93,7 +93,7 @@ if (allUsagesAvailable && self != null && self.hasNoUsages()) { return null; } else { - if (clazz.isConstant()) { + if (clazz.isConstant() && !clazz.isNullConstant()) { if (metaAccess != null) { ResolvedJavaType exactType = constantReflection.asJavaType(clazz.asJavaConstant()); if (exactType.isPrimitive()) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Fri Aug 17 13:20:53 2018 -0700 @@ -63,7 +63,6 @@ import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.internal.vm.compiler.word.WordFactory; -import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.code.Register; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; @@ -186,13 +185,6 @@ return config.threadTlabEndOffset(); } - public static final LocationIdentity TLAB_START_LOCATION = NamedLocationIdentity.mutable("TlabStart"); - - @Fold - static int threadTlabStartOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.threadTlabStartOffset(); - } - public static final LocationIdentity PENDING_EXCEPTION_LOCATION = NamedLocationIdentity.mutable("PendingException"); /** @@ -203,16 +195,6 @@ return config.pendingExceptionOffset; } - public static final LocationIdentity PENDING_DEOPTIMIZATION_LOCATION = NamedLocationIdentity.mutable("PendingDeoptimization"); - - /** - * @see GraalHotSpotVMConfig#pendingDeoptimizationOffset - */ - @Fold - static int threadPendingDeoptimizationOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.pendingDeoptimizationOffset; - } - public static final LocationIdentity OBJECT_RESULT_LOCATION = NamedLocationIdentity.mutable("ObjectResult"); @Fold @@ -250,21 +232,10 @@ return thread.readWord(threadTlabEndOffset(INJECTED_VMCONFIG), TLAB_END_LOCATION); } - public static Word readTlabStart(Word thread) { - return thread.readWord(threadTlabStartOffset(INJECTED_VMCONFIG), TLAB_START_LOCATION); - } - public static void writeTlabTop(Word thread, Word top) { thread.writeWord(threadTlabTopOffset(INJECTED_VMCONFIG), top, TLAB_TOP_LOCATION); } - @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected") - public static void initializeTlab(Word thread, Word start, Word end) { - thread.writeWord(threadTlabStartOffset(INJECTED_VMCONFIG), start, TLAB_START_LOCATION); - thread.writeWord(threadTlabTopOffset(INJECTED_VMCONFIG), start, TLAB_TOP_LOCATION); - thread.writeWord(threadTlabEndOffset(INJECTED_VMCONFIG), end, TLAB_END_LOCATION); - } - /** * Clears the pending exception for the given thread. * @@ -278,19 +249,13 @@ } /** - * Reads the pending deoptimization value for the given thread. + * Gets the pending exception for the given thread. * - * @return {@code true} if there was a pending deoptimization + * @return the pending exception, or null if there was none */ - public static int readPendingDeoptimization(Word thread) { - return thread.readInt(threadPendingDeoptimizationOffset(INJECTED_VMCONFIG), PENDING_DEOPTIMIZATION_LOCATION); - } - - /** - * Writes the pending deoptimization value for the given thread. - */ - public static void writePendingDeoptimization(Word thread, int value) { - thread.writeInt(threadPendingDeoptimizationOffset(INJECTED_VMCONFIG), value, PENDING_DEOPTIMIZATION_LOCATION); + @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF_NONVIRTUAL", justification = "foldable method parameters are injected") + public static Object getPendingException(Word thread) { + return thread.readObject(threadPendingExceptionOffset(INJECTED_VMCONFIG), PENDING_EXCEPTION_LOCATION); } /** @@ -342,11 +307,6 @@ return UNSAFE.pageSize(); } - @Fold - public static int heapWordSize(@InjectedParameter GraalHotSpotVMConfig config) { - return config.heapWordSize; - } - public static final LocationIdentity PROTOTYPE_MARK_WORD_LOCATION = NamedLocationIdentity.mutable("PrototypeMarkWord"); @Fold @@ -354,11 +314,6 @@ return config.prototypeMarkWordOffset; } - @Fold - public static long arrayPrototypeMarkWord(@InjectedParameter GraalHotSpotVMConfig config) { - return config.arrayPrototypeMarkWord(); - } - public static final LocationIdentity KLASS_ACCESS_FLAGS_LOCATION = NamedLocationIdentity.immutable("Klass::_access_flags"); @Fold @@ -389,11 +344,6 @@ } }; - @Fold - public static int klassLayoutHelperOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.klassLayoutHelperOffset; - } - @NodeIntrinsic(value = KlassLayoutHelperNode.class) public static native int readLayoutHelper(KlassPointer object); @@ -707,16 +657,6 @@ } @Fold - public static boolean useG1GC(@InjectedParameter GraalHotSpotVMConfig config) { - return config.useG1GC; - } - - @Fold - public static boolean useCMSIncrementalMode(@InjectedParameter GraalHotSpotVMConfig config) { - return config.cmsIncrementalMode; - } - - @Fold public static boolean useCompressedOops(@InjectedParameter GraalHotSpotVMConfig config) { return config.useCompressedOops; } @@ -788,11 +728,6 @@ @NodeIntrinsic(value = LoadHubNode.class) public static native KlassPointer loadHubIntrinsic(Object object); - @Fold - public static int log2WordSize() { - return CodeUtil.log2(wordSize()); - } - public static final LocationIdentity CLASS_STATE_LOCATION = NamedLocationIdentity.mutable("ClassState"); @Fold @@ -832,11 +767,6 @@ } }; - @Fold - public static int klassOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.klassOffset; - } - public static final LocationIdentity CLASS_ARRAY_KLASS_LOCATION = new HotSpotOptimizingLocationIdentity("Class._array_klass") { @Override public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) { @@ -853,87 +783,6 @@ public static final LocationIdentity CLASS_MIRROR_HANDLE_LOCATION = NamedLocationIdentity.immutable("Klass::_java_mirror handle"); - public static final LocationIdentity HEAP_TOP_LOCATION = NamedLocationIdentity.mutable("HeapTop"); - - @Fold - public static long heapTopAddress(@InjectedParameter GraalHotSpotVMConfig config) { - return config.heapTopAddress; - } - - public static final LocationIdentity HEAP_END_LOCATION = NamedLocationIdentity.mutable("HeapEnd"); - - @Fold - public static long heapEndAddress(@InjectedParameter GraalHotSpotVMConfig config) { - return config.heapEndAddress; - } - - @Fold - public static long tlabIntArrayMarkWord(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabIntArrayMarkWord(); - } - - @Fold - public static boolean inlineContiguousAllocationSupported(@InjectedParameter GraalHotSpotVMConfig config) { - return config.inlineContiguousAllocationSupported; - } - - @Fold - public static int tlabAlignmentReserveInHeapWords(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabAlignmentReserve; - } - - public static final LocationIdentity TLAB_SIZE_LOCATION = NamedLocationIdentity.mutable("TlabSize"); - - @Fold - public static int threadTlabSizeOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.threadTlabSizeOffset(); - } - - public static final LocationIdentity TLAB_THREAD_ALLOCATED_BYTES_LOCATION = NamedLocationIdentity.mutable("TlabThreadAllocatedBytes"); - - @Fold - public static int threadAllocatedBytesOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.threadAllocatedBytesOffset; - } - - public static final LocationIdentity TLAB_REFILL_WASTE_LIMIT_LOCATION = NamedLocationIdentity.mutable("RefillWasteLimit"); - - @Fold - public static int tlabRefillWasteLimitOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabRefillWasteLimitOffset(); - } - - public static final LocationIdentity TLAB_NOF_REFILLS_LOCATION = NamedLocationIdentity.mutable("TlabNOfRefills"); - - @Fold - public static int tlabNumberOfRefillsOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabNumberOfRefillsOffset(); - } - - public static final LocationIdentity TLAB_FAST_REFILL_WASTE_LOCATION = NamedLocationIdentity.mutable("TlabFastRefillWaste"); - - @Fold - public static int tlabFastRefillWasteOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabFastRefillWasteOffset(); - } - - public static final LocationIdentity TLAB_SLOW_ALLOCATIONS_LOCATION = NamedLocationIdentity.mutable("TlabSlowAllocations"); - - @Fold - public static int tlabSlowAllocationsOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabSlowAllocationsOffset(); - } - - @Fold - public static int tlabRefillWasteIncrement(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabRefillWasteIncrement; - } - - @Fold - public static boolean tlabStats(@InjectedParameter GraalHotSpotVMConfig config) { - return config.tlabStats; - } - @Fold public static int layoutHelperHeaderSizeShift(@InjectedParameter GraalHotSpotVMConfig config) { return config.layoutHelperHeaderSizeShift; @@ -964,20 +813,10 @@ return config.layoutHelperElementTypeMask; } - @Fold - public static int layoutHelperElementTypePrimitiveInPlace(@InjectedParameter GraalHotSpotVMConfig config) { - return config.layoutHelperElementTypePrimitiveInPlace(); - } - @NodeIntrinsic(ForeignCallNode.class) public static native int identityHashCode(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); @Fold - public static int verifiedEntryPointOffset(@InjectedParameter GraalHotSpotVMConfig config) { - return config.nmethodEntryOffset; - } - - @Fold public static long gcTotalCollectionsAddress(@InjectedParameter GraalHotSpotVMConfig config) { return config.gcTotalCollectionsAddress(); } @@ -1023,9 +862,4 @@ public static final LocationIdentity METASPACE_ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("MetaspaceArrayLength"); public static final LocationIdentity SECONDARY_SUPERS_ELEMENT_LOCATION = NamedLocationIdentity.immutable("SecondarySupersElement"); - - @Fold - public static boolean useFastTLABRefill(@InjectedParameter GraalHotSpotVMConfig config) { - return config.useFastTLABRefill; - } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Fri Aug 17 13:20:53 2018 -0700 @@ -595,7 +595,7 @@ public static void traceObject(boolean enabled, String action, Object object, boolean enter, OptionValues options) { if (doProfile(options)) { - DynamicCounterNode.counter(action, enter ? "number of monitor enters" : "number of monitor exits", 1, PROFILE_CONTEXT); + DynamicCounterNode.counter(enter ? "number of monitor enters" : "number of monitor exits", action, 1, PROFILE_CONTEXT); } if (enabled) { Log.print(action); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Fri Aug 17 13:20:53 2018 -0700 @@ -177,8 +177,8 @@ String name = createName(path, typeContext, options); boolean context = withContext(options); - DynamicCounterNode.counter(name, "number of bytes allocated", size, context); - DynamicCounterNode.counter(name, "number of allocations", 1, context); + DynamicCounterNode.counter("number of bytes allocated", name, size, context); + DynamicCounterNode.counter("number of allocations", name, 1, context); } } @@ -276,6 +276,8 @@ */ return allocateInstanceHelper(layoutHelper, nonNullHub, prototypeMarkWord, fillContents, threadRegister, false, "", options, counters); } + } else { + DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } } return dynamicNewInstanceStub(type); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionSubstitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionSubstitutions.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/ReflectionSubstitutions.java Fri Aug 17 13:20:53 2018 -0700 @@ -37,7 +37,7 @@ import org.graalvm.compiler.hotspot.word.KlassPointer; /** - * Substitutions for {@link sun.reflect.Reflection} methods. + * Substitutions for {@code sun.reflect.Reflection} methods. */ @ClassSubstitution(className = {"jdk.internal.reflect.Reflection", "sun.reflect.Reflection"}, optional = true) public class ReflectionSubstitutions { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/CreateExceptionStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,9 +25,9 @@ package org.graalvm.compiler.hotspot.stubs; import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall; +import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS; import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT; -import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.REEXECUTABLE; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.clearPendingException; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; import static jdk.internal.vm.compiler.word.LocationIdentity.any; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -40,6 +40,7 @@ import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.JavaMethodContext; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; @@ -75,8 +76,8 @@ * deoptimization while the call is in progress. And since these are foreign/runtime calls on slow * paths, we don't want to force the register allocator to spill around the call. As such, this stub * saves and restores all allocatable registers. It also - * {@linkplain StubUtil#handlePendingException(Word, boolean) handles} any exceptions raised during - * the foreign call. + * {@linkplain StubUtil#handlePendingException(Word, boolean, boolean) handles} any exceptions + * raised during the foreign call. */ public class ForeignCallStub extends Stub { @@ -100,23 +101,21 @@ * @param descriptor the signature of the call to this stub * @param prependThread true if the JavaThread value for the current thread is to be prepended * to the arguments for the call to {@code address} - * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side - * effects. Deoptimization will not return to a point before a stub call that cannot - * be re-executed. + * @param reexecutability specifies if the stub call can be re-executed without (meaningful) + * side effects. Deoptimization will not return to a point before a stub call that + * cannot be re-executed. * @param killedLocations the memory locations killed by the stub call */ public ForeignCallStub(OptionValues options, HotSpotJVMCIRuntime runtime, HotSpotProviders providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, - Transition transition, - boolean reexecutable, - LocationIdentity... killedLocations) { + Transition transition, Reexecutability reexecutability, LocationIdentity... killedLocations) { super(options, providers, HotSpotForeignCallLinkageImpl.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), descriptor, 0L, - PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); + PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutability, killedLocations)); this.jvmciRuntime = runtime; this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); target = HotSpotForeignCallLinkageImpl.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), targetSig, address, - DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutable, killedLocations); + DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutability, killedLocations); } /** @@ -191,9 +190,9 @@ *

      *     Object foreignFunctionStub(args...) {
      *         foreignFunction(currentThread,  args);
-     *         if (clearPendingException(thread())) {
+     *         if ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
      *             getAndClearObjectResult(thread());
-     *             DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+     *             DeoptimizeCallerNode.deopt(None, RuntimeConstraint);
      *         }
      *         return verifyObject(getAndClearObjectResult(thread()));
      *     }
@@ -205,8 +204,8 @@
      * 
      *     int foreignFunctionStub(args...) {
      *         int result = foreignFunction(currentThread,  args);
-     *         if (clearPendingException(thread())) {
-     *             DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+     *         if ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
+     *             DeoptimizeCallerNode.deopt(None, RuntimeConstraint);
      *         }
      *         return result;
      *     }
@@ -217,8 +216,8 @@
      * 
      *     void foreignFunctionStub(args...) {
      *         foreignFunction(currentThread,  args);
-     *         if (clearPendingException(thread())) {
-     *             DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
+     *         if ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
+     *             DeoptimizeCallerNode.deopt(None, RuntimeConstraint);
      *         }
      *     }
      * 
@@ -232,7 +231,8 @@ WordTypes wordTypes = providers.getWordTypes(); Class[] args = linkage.getDescriptor().getArgumentTypes(); boolean isObjectResult = !LIRKind.isValue(linkage.getOutgoingCallingConvention().getReturn()); - + // Do we want to clear the pending exception? + boolean shouldClearException = linkage.isReexecutable() || linkage.isReexecutableOnlyAfterException(); try { ResolvedJavaMethod thisMethod = providers.getMetaAccess().lookupJavaMethod(ForeignCallStub.class.getDeclaredMethod("getGraph", DebugContext.class, CompilationIdentifier.class)); GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString()); @@ -240,7 +240,7 @@ ParameterNode[] params = createParameters(kit, args); ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false)); ValueNode result = createTargetCall(kit, params, thread); - kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, graph)); + kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(shouldClearException, graph), ConstantNode.forBoolean(isObjectResult, graph)); if (isObjectResult) { InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread); result = kit.createInvoke(StubUtil.class, "verifyObject", object); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/IntegerExactOverflowExceptionStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/IntegerExactOverflowExceptionStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.hotspot.stubs; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.nodes.CStringConstant; +import org.graalvm.compiler.word.Word; + +import jdk.vm.ci.code.Register; + +public class IntegerExactOverflowExceptionStub extends CreateExceptionStub { + public IntegerExactOverflowExceptionStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { + super("createIntegerExactOverflowException", options, providers, linkage); + } + + @Override + protected Object getConstantParameterValue(int index, String name) { + GraalError.guarantee(index == 0, "unknown parameter %s at index %d", name, index); + return providers.getRegisters().getThreadRegister(); + } + + @Snippet + private static Object createIntegerExactOverflowException(@ConstantParameter Register threadRegister) { + Word msg = CStringConstant.cstring("integer overflow"); + return createException(threadRegister, ArithmeticException.class, msg); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/LongExactOverflowExceptionStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/LongExactOverflowExceptionStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.hotspot.stubs; + +import org.graalvm.compiler.api.replacements.Snippet; +import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; +import org.graalvm.compiler.hotspot.meta.HotSpotProviders; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.compiler.replacements.nodes.CStringConstant; +import org.graalvm.compiler.word.Word; + +import jdk.vm.ci.code.Register; + +public class LongExactOverflowExceptionStub extends CreateExceptionStub { + public LongExactOverflowExceptionStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) { + super("createLongExactOverflowException", options, providers, linkage); + } + + @Override + protected Object getConstantParameterValue(int index, String name) { + GraalError.guarantee(index == 0, "unknown parameter %s at index %d", name, index); + return providers.getRegisters().getThreadRegister(); + } + + @Snippet + private static Object createLongExactOverflowException(@ConstantParameter Register threadRegister) { + Word msg = CStringConstant.cstring("long overflow"); + return createException(threadRegister, ArithmeticException.class, msg); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewArrayStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -26,7 +26,6 @@ import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayAllocationSize; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayPrototypeMarkWord; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypeMask; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperElementTypeShift; @@ -36,11 +35,6 @@ import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.layoutHelperLog2ElementSizeShift; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useFastTLABRefill; -import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH; -import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.formatArray; -import static org.graalvm.compiler.hotspot.stubs.NewInstanceStub.refillAllocate; import static org.graalvm.compiler.hotspot.stubs.StubUtil.handlePendingException; import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor; import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf; @@ -54,18 +48,13 @@ import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; -import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; -import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets; import org.graalvm.compiler.hotspot.word.KlassPointer; -import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.word.Word; -import jdk.internal.vm.compiler.word.WordFactory; import jdk.vm.ci.code.Register; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; /** * Stub implementing the fast path for TLAB refill during instance class allocation. This stub is @@ -81,15 +70,12 @@ @Override protected Object[] makeConstArgs() { - HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class); int count = method.getSignature().getParameterCount(false); Object[] args = new Object[count]; - assert checkConstArg(3, "intArrayHub"); - assert checkConstArg(4, "threadRegister"); - assert checkConstArg(5, "options"); - args[3] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null); - args[4] = providers.getRegisters().getThreadRegister(); - args[5] = options; + assert checkConstArg(2, "threadRegister"); + assert checkConstArg(3, "options"); + args[2] = providers.getRegisters().getThreadRegister(); + args[3] = options; return args; } @@ -104,12 +90,9 @@ * * @param hub the hub of the object to be allocated * @param length the length of the array - * @param fillContents Should the array be filled with zeroes? - * @param intArrayHub the hub for {@code int[].class} */ @Snippet - private static Object newArray(KlassPointer hub, int length, boolean fillContents, @ConstantParameter KlassPointer intArrayHub, @ConstantParameter Register threadRegister, - @ConstantParameter OptionValues options) { + private static Object newArray(KlassPointer hub, int length, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { int layoutHelper = readLayoutHelper(hub); int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG); int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG); @@ -122,26 +105,13 @@ printf("newArray: hub=%p\n", hub.asWord().rawValue()); } - // check that array length is small enough for fast path. Word thread = registerAsWord(threadRegister); - boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported(); - if (useFastTLABRefill(INJECTED_VMCONFIG) && inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG) && length >= 0 && - length <= MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH) { - Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options)); - if (memory.notEqual(0)) { - if (logging(options)) { - printf("newArray: allocated new array at %p\n", memory.rawValue()); - } - return verifyObject( - formatArray(hub, sizeInBytes, length, headerSize, memory, WordFactory.unsigned(arrayPrototypeMarkWord(INJECTED_VMCONFIG)), fillContents, false, null)); - } - } if (logging(options)) { printf("newArray: calling new_array_c\n"); } newArrayC(NEW_ARRAY_C, thread, hub, length); - handlePendingException(thread, true); + handlePendingException(thread, true, true); return verifyObject(getAndClearObjectResult(thread)); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/NewInstanceStub.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,50 +24,12 @@ package org.graalvm.compiler.hotspot.stubs; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; -import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HEAP_END_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HEAP_TOP_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_FAST_REFILL_WASTE_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_NOF_REFILLS_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_REFILL_WASTE_LIMIT_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_SIZE_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_SLOW_ALLOCATIONS_LOCATION; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_THREAD_ALLOCATED_BYTES_LOCATION; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getArrayBaseOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.initializeTlab; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.isInstanceKlassFullyInitialized; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.log2WordSize; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readLayoutHelper; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabEnd; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabStart; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.readTlabTop; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.threadAllocatedBytesOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.threadTlabSizeOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabAlignmentReserveInHeapWords; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabFastRefillWasteOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabIntArrayMarkWord; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabNumberOfRefillsOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabRefillWasteIncrement; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabRefillWasteLimitOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabSlowAllocationsOffset; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabStats; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useCMSIncrementalMode; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useFastTLABRefill; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useG1GC; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.useTLAB; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize; -import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.writeTlabTop; import static org.graalvm.compiler.hotspot.stubs.StubUtil.handlePendingException; import static org.graalvm.compiler.hotspot.stubs.StubUtil.newDescriptor; import static org.graalvm.compiler.hotspot.stubs.StubUtil.printf; import static org.graalvm.compiler.hotspot.stubs.StubUtil.verifyObject; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FAST_PATH_PROBABILITY; -import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.compiler.api.replacements.Snippet; @@ -77,19 +39,13 @@ import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage; import org.graalvm.compiler.hotspot.meta.HotSpotProviders; -import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode; -import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; import org.graalvm.compiler.hotspot.replacements.NewObjectSnippets; import org.graalvm.compiler.hotspot.word.KlassPointer; -import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.word.Word; -import jdk.internal.vm.compiler.word.WordFactory; import jdk.vm.ci.code.Register; -import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import jdk.vm.ci.meta.JavaKind; /** * Stub implementing the fast path for TLAB refill during instance class allocation. This stub is @@ -105,33 +61,15 @@ @Override protected Object[] makeConstArgs() { - HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class); int count = method.getSignature().getParameterCount(false); Object[] args = new Object[count]; - assert checkConstArg(1, "intArrayHub"); - assert checkConstArg(2, "threadRegister"); - assert checkConstArg(3, "options"); - args[1] = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), intArrayType.klass(), null); - args[2] = providers.getRegisters().getThreadRegister(); - args[3] = options; + assert checkConstArg(1, "threadRegister"); + assert checkConstArg(2, "options"); + args[1] = providers.getRegisters().getThreadRegister(); + args[2] = options; return args; } - private static Word allocate(Word thread, int size) { - Word top = readTlabTop(thread); - Word end = readTlabEnd(thread); - Word newTop = top.add(size); - /* - * this check might lead to problems if the TLAB is within 16GB of the address space end - * (checked in c++ code) - */ - if (probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { - writeTlabTop(thread, newTop); - return top; - } - return WordFactory.zero(); - } - @Fold static boolean logging(OptionValues options) { return StubOptions.TraceNewInstanceStub.getValue(options); @@ -142,168 +80,23 @@ * -XX:-UseTLAB). * * @param hub the hub of the object to be allocated - * @param intArrayHub the hub for {@code int[].class} */ @Snippet - private static Object newInstance(KlassPointer hub, @ConstantParameter KlassPointer intArrayHub, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { + private static Object newInstance(KlassPointer hub, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) { /* * The type is known to be an instance so Klass::_layout_helper is the instance size as a * raw number */ Word thread = registerAsWord(threadRegister); - boolean inlineContiguousAllocationSupported = GraalHotSpotVMConfigNode.inlineContiguousAllocationSupported(); - if (useFastTLABRefill(INJECTED_VMCONFIG) && !forceSlowPath(options) && inlineContiguousAllocationSupported && !useCMSIncrementalMode(INJECTED_VMCONFIG)) { - if (isInstanceKlassFullyInitialized(hub)) { - int sizeInBytes = readLayoutHelper(hub); - Word memory = refillAllocate(thread, intArrayHub, sizeInBytes, logging(options)); - if (memory.notEqual(0)) { - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION); - NewObjectSnippets.formatObjectForStub(hub, sizeInBytes, memory, prototypeMarkWord); - return verifyObject(memory.toObject()); - } - } - } - if (logging(options)) { printf("newInstance: calling new_instance_c\n"); } newInstanceC(NEW_INSTANCE_C, thread, hub); - handlePendingException(thread, true); + handlePendingException(thread, true, true); return verifyObject(getAndClearObjectResult(thread)); } - /** - * Attempts to refill the current thread's TLAB and retries the allocation. - * - * @param intArrayHub the hub for {@code int[].class} - * @param sizeInBytes the size of the allocation - * @param log specifies if logging is enabled - * - * @return the newly allocated, uninitialized chunk of memory, or {@link WordFactory#zero()} if - * the operation was unsuccessful - */ - static Word refillAllocate(Word thread, KlassPointer intArrayHub, int sizeInBytes, boolean log) { - // If G1 is enabled, the "eden" allocation space is not the same always - // and therefore we have to go to slowpath to allocate a new TLAB. - if (useG1GC(INJECTED_VMCONFIG)) { - return WordFactory.zero(); - } - if (!useTLAB(INJECTED_VMCONFIG)) { - return edenAllocate(WordFactory.unsigned(sizeInBytes), log); - } - Word intArrayMarkWord = WordFactory.unsigned(tlabIntArrayMarkWord(INJECTED_VMCONFIG)); - int alignmentReserveInBytes = tlabAlignmentReserveInHeapWords(INJECTED_VMCONFIG) * wordSize(); - - Word top = readTlabTop(thread); - Word end = readTlabEnd(thread); - - // calculate amount of free space - long tlabFreeSpaceInBytes = end.subtract(top).rawValue(); - - if (log) { - printf("refillTLAB: thread=%p\n", thread.rawValue()); - printf("refillTLAB: top=%p\n", top.rawValue()); - printf("refillTLAB: end=%p\n", end.rawValue()); - printf("refillTLAB: tlabFreeSpaceInBytes=%ld\n", tlabFreeSpaceInBytes); - } - - long tlabFreeSpaceInWords = tlabFreeSpaceInBytes >>> log2WordSize(); - - // Retain TLAB and allocate object in shared space if - // the amount free in the TLAB is too large to discard. - Word refillWasteLimit = thread.readWord(tlabRefillWasteLimitOffset(INJECTED_VMCONFIG), TLAB_REFILL_WASTE_LIMIT_LOCATION); - if (tlabFreeSpaceInWords <= refillWasteLimit.rawValue()) { - if (tlabStats(INJECTED_VMCONFIG)) { - // increment number of refills - thread.writeInt(tlabNumberOfRefillsOffset(INJECTED_VMCONFIG), thread.readInt(tlabNumberOfRefillsOffset(INJECTED_VMCONFIG), TLAB_NOF_REFILLS_LOCATION) + 1, TLAB_NOF_REFILLS_LOCATION); - if (log) { - printf("thread: %p -- number_of_refills %d\n", thread.rawValue(), thread.readInt(tlabNumberOfRefillsOffset(INJECTED_VMCONFIG), TLAB_NOF_REFILLS_LOCATION)); - } - // accumulate wastage - int wastage = thread.readInt(tlabFastRefillWasteOffset(INJECTED_VMCONFIG), TLAB_FAST_REFILL_WASTE_LOCATION) + (int) tlabFreeSpaceInWords; - if (log) { - printf("thread: %p -- accumulated wastage %d\n", thread.rawValue(), wastage); - } - thread.writeInt(tlabFastRefillWasteOffset(INJECTED_VMCONFIG), wastage, TLAB_FAST_REFILL_WASTE_LOCATION); - } - - // if TLAB is currently allocated (top or end != null) then - // fill [top, end + alignment_reserve) with array object - if (top.notEqual(0)) { - int headerSize = getArrayBaseOffset(INJECTED_METAACCESS, JavaKind.Int); - // just like the HotSpot assembler stubs, assumes that tlabFreeSpaceInInts fits in - // an int - int tlabFreeSpaceInInts = (int) tlabFreeSpaceInBytes >>> 2; - int length = ((alignmentReserveInBytes - headerSize) >>> 2) + tlabFreeSpaceInInts; - NewObjectSnippets.formatArray(intArrayHub, 0, length, headerSize, top, intArrayMarkWord, false, false, null); - - long allocated = thread.readLong(threadAllocatedBytesOffset(INJECTED_VMCONFIG), TLAB_THREAD_ALLOCATED_BYTES_LOCATION); - allocated = allocated + top.subtract(readTlabStart(thread)).rawValue(); - thread.writeLong(threadAllocatedBytesOffset(INJECTED_VMCONFIG), allocated, TLAB_THREAD_ALLOCATED_BYTES_LOCATION); - } - - // refill the TLAB with an eden allocation - Word tlabRefillSizeInWords = thread.readWord(threadTlabSizeOffset(INJECTED_VMCONFIG), TLAB_SIZE_LOCATION); - Word tlabRefillSizeInBytes = tlabRefillSizeInWords.multiply(wordSize()); - // allocate new TLAB, address returned in top - top = edenAllocate(tlabRefillSizeInBytes, log); - if (top.notEqual(0)) { - end = top.add(tlabRefillSizeInBytes.subtract(alignmentReserveInBytes)); - initializeTlab(thread, top, end); - - return NewInstanceStub.allocate(thread, sizeInBytes); - } else { - return WordFactory.zero(); - } - } else { - // Retain TLAB - Word newRefillWasteLimit = refillWasteLimit.add(tlabRefillWasteIncrement(INJECTED_VMCONFIG)); - thread.writeWord(tlabRefillWasteLimitOffset(INJECTED_VMCONFIG), newRefillWasteLimit, TLAB_REFILL_WASTE_LIMIT_LOCATION); - if (log) { - printf("refillTLAB: retaining TLAB - newRefillWasteLimit=%p\n", newRefillWasteLimit.rawValue()); - } - - if (tlabStats(INJECTED_VMCONFIG)) { - thread.writeInt(tlabSlowAllocationsOffset(INJECTED_VMCONFIG), thread.readInt(tlabSlowAllocationsOffset(INJECTED_VMCONFIG), TLAB_SLOW_ALLOCATIONS_LOCATION) + 1, - TLAB_SLOW_ALLOCATIONS_LOCATION); - } - - return edenAllocate(WordFactory.unsigned(sizeInBytes), log); - } - } - - /** - * Attempts to allocate a chunk of memory from Eden space. - * - * @param sizeInBytes the size of the chunk to allocate - * @param log specifies if logging is enabled - * @return the allocated chunk or {@link WordFactory#zero()} if allocation fails - */ - public static Word edenAllocate(Word sizeInBytes, boolean log) { - final long heapTopRawAddress = GraalHotSpotVMConfigNode.heapTopAddress(); - final long heapEndRawAddress = GraalHotSpotVMConfigNode.heapEndAddress(); - - Word heapTopAddress = WordFactory.unsigned(heapTopRawAddress); - Word heapEndAddress = WordFactory.unsigned(heapEndRawAddress); - - while (true) { - Word heapTop = heapTopAddress.readWord(0, HEAP_TOP_LOCATION); - Word newHeapTop = heapTop.add(sizeInBytes); - if (newHeapTop.belowOrEqual(heapTop)) { - return WordFactory.zero(); - } - - Word heapEnd = heapEndAddress.readWord(0, HEAP_END_LOCATION); - if (newHeapTop.aboveThan(heapEnd)) { - return WordFactory.zero(); - } - if (heapTopAddress.logicCompareAndSwapWord(0, heapTop, newHeapTop, HEAP_TOP_LOCATION)) { - return heapTop; - } - } - } - @Fold static boolean forceSlowPath(OptionValues options) { return StubOptions.ForceUseOfNewInstanceStub.getValue(options); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,6 +27,7 @@ import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint; import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.clearPendingException; +import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getPendingException; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.getAndClearObjectResult; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadHubIntrinsic; import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOops; @@ -95,8 +96,8 @@ return new ForeignCallDescriptor(name, found.getReturnType(), cCallTypes); } - public static void handlePendingException(Word thread, boolean isObjectResult) { - if (clearPendingException(thread) != null) { + public static void handlePendingException(Word thread, boolean shouldClearException, boolean isObjectResult) { + if ((shouldClearException && clearPendingException(thread) != null) || (!shouldClearException && getPendingException(thread) != null)) { if (isObjectResult) { getAndClearObjectResult(thread); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Aug 17 13:20:53 2018 -0700 @@ -1929,9 +1929,15 @@ } boolean check(boolean pluginResult) { - if (pluginResult == true) { + if (pluginResult) { + /* + * If lastInstr is null, even if this method has a non-void return type, the method + * doesn't return a value, it probably throws an exception. + */ int expectedStackSize = beforeStackSize + resultType.getSlotCount(); - assert expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize()); + assert lastInstr == null || expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, + frameState.stackSize()); + NodeIterable newNodes = graph.getNewNodes(mark); assert !needsNullCheck || isPointerNonNull(args[0].stamp(NodeView.DEFAULT)) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"), args[0]); @@ -3544,6 +3550,11 @@ } @Override + public ValueNode pop(JavaKind slotKind) { + return frameState.pop(slotKind); + } + + @Override public ConstantReflectionProvider getConstantReflection() { return constantReflection; } @@ -4277,13 +4288,7 @@ JavaKind fieldKind = resolvedField.getJavaKind(); - if (resolvedField.isVolatile() && fieldRead instanceof LoadFieldNode) { - StateSplitProxyNode readProxy = append(genVolatileFieldReadProxy(fieldRead)); - frameState.push(fieldKind, readProxy); - readProxy.setStateAfter(frameState.create(stream.nextBCI(), readProxy)); - } else { - frameState.push(fieldKind, fieldRead); - } + pushLoadField(resolvedField, fieldRead, fieldKind); } /** @@ -4334,10 +4339,8 @@ return needsExplicitException(); } - /** - * Returns true if an explicit exception check should be emitted. - */ - protected boolean needsExplicitException() { + @Override + public boolean needsExplicitException() { BytecodeExceptionMode exceptionMode = graphBuilderConfig.getBytecodeExceptionMode(); if (exceptionMode == BytecodeExceptionMode.CheckAll || StressExplicitExceptionCode.getValue(options)) { return true; @@ -4347,6 +4350,15 @@ return false; } + @Override + public AbstractBeginNode genExplicitExceptionEdge(BytecodeExceptionKind exceptionKind) { + BytecodeExceptionNode exceptionNode = graph.add(new BytecodeExceptionNode(metaAccess, exceptionKind)); + exceptionNode.setStateAfter(createFrameState(bci(), exceptionNode)); + AbstractBeginNode exceptionDispatch = handleException(exceptionNode, bci(), false); + exceptionNode.setNext(exceptionDispatch); + return BeginNode.begin(exceptionNode); + } + protected void genPutField(int cpi, int opcode) { JavaField field = lookupField(cpi, opcode); genPutField(field); @@ -4417,7 +4429,25 @@ } } - frameState.push(field.getJavaKind(), append(genLoadField(null, resolvedField))); + ValueNode fieldRead = append(genLoadField(null, resolvedField)); + JavaKind fieldKind = resolvedField.getJavaKind(); + + pushLoadField(resolvedField, fieldRead, fieldKind); + } + + /** + * Pushes a loaded field onto the stack. If the loaded field is volatile, a + * {@link StateSplitProxyNode} is appended so that deoptimization does not deoptimize to a point + * before the field load. + */ + private void pushLoadField(ResolvedJavaField resolvedField, ValueNode fieldRead, JavaKind fieldKind) { + if (resolvedField.isVolatile() && fieldRead instanceof LoadFieldNode) { + StateSplitProxyNode readProxy = append(genVolatileFieldReadProxy(fieldRead)); + frameState.push(fieldKind, readProxy); + readProxy.setStateAfter(frameState.create(stream.nextBCI(), readProxy)); + } else { + frameState.push(fieldKind, fieldRead); + } } private ResolvedJavaField resolveStaticFieldAccess(JavaField field, ValueNode value) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/IntegerExactOpSpeculation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/IntegerExactOpSpeculation.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.java; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; + +public final class IntegerExactOpSpeculation implements SpeculationReason { + + public enum IntegerExactOp { + INTEGER_ADD_EXACT, + INTEGER_INCREMENT_EXACT, + INTEGER_SUBTRACT_EXACT, + INTEGER_DECREMENT_EXACT, + INTEGER_MULTIPLY_EXACT + } + + protected final String methodDescriptor; + protected final IntegerExactOp op; + + public IntegerExactOpSpeculation(ResolvedJavaMethod method, IntegerExactOp op) { + this.methodDescriptor = method.format("%H.%n(%p)%R"); + this.op = op; + } + + @Override + public int hashCode() { + return methodDescriptor.hashCode() * 31 + op.ordinal(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof IntegerExactOpSpeculation) { + IntegerExactOpSpeculation other = (IntegerExactOpSpeculation) obj; + return op.equals(other.op) && methodDescriptor.equals(other.methodDescriptor); + } + return false; + } + +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/backend/LargeConstantSectionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/backend/LargeConstantSectionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/backend/LargeConstantSectionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -127,12 +127,12 @@ for (int i = 0; i < labels.length; i++) { mv.visitLabel(labels[i]); mv.visitFrame(Opcodes.F_NEW, 1, new Object[]{Opcodes.INTEGER}, 0, new Object[]{}); - mv.visitLdcInsn(new Long(LARGE_CONSTANT + i)); + mv.visitLdcInsn(Long.valueOf(LARGE_CONSTANT + i)); mv.visitInsn(LRETURN); } mv.visitLabel(defaultLabel); mv.visitFrame(Opcodes.F_NEW, 1, new Object[]{Opcodes.INTEGER}, 0, new Object[]{}); - mv.visitLdcInsn(new Long(3L)); + mv.visitLdcInsn(Long.valueOf(3L)); mv.visitInsn(LRETURN); Label end = new Label(); mv.visitLabel(end); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/bytecode/BC_i2d.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/bytecode/BC_i2d.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/bytecode/BC_i2d.java Fri Aug 17 13:20:53 2018 -0700 @@ -68,7 +68,7 @@ @Test public void run6() throws Throwable { - runTest("test", new Integer(Short.MAX_VALUE)); + runTest("test", Integer.valueOf(Short.MAX_VALUE)); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/except/UntrustedInterfaces.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/except/UntrustedInterfaces.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/except/UntrustedInterfaces.java Fri Aug 17 13:20:53 2018 -0700 @@ -151,8 +151,8 @@ // Checkstyle: stop @BeforeClass - public static void setUp() throws InstantiationException, IllegalAccessException, ClassNotFoundException { - poisonPill = (Pill) new PoisonLoader().findClass(PoisonLoader.POISON_IMPL_NAME).newInstance(); + public static void setUp() throws Exception { + poisonPill = (Pill) new PoisonLoader().findClass(PoisonLoader.POISON_IMPL_NAME).getDeclaredConstructor().newInstance(); } // Checkstyle: resume diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotpath/HP_allocate02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotpath/HP_allocate02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotpath/HP_allocate02.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,6 +32,7 @@ */ public class HP_allocate02 extends JTTTest { + @SuppressWarnings("deprecation") public static int test(int count) { int sum = 0; for (int i = 0; i < count; i++) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/NotOnDebug.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/NotOnDebug.java Fri Aug 17 11:56:59 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package org.graalvm.compiler.jtt.hotspot; - -import org.junit.rules.DisableOnDebug; -import org.junit.rules.TestRule; -import org.junit.rules.Timeout; - -public final class NotOnDebug { - public static TestRule create(Timeout seconds) { - try { - return new DisableOnDebug(seconds); - } catch (LinkageError ex) { - return null; - } - } - -} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6823354.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6823354.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6823354.java Fri Aug 17 13:20:53 2018 -0700 @@ -199,6 +199,7 @@ loadandrunclass(classname); } + @SuppressWarnings("deprecation") static void loadandrunclass(String classname) throws Exception { Class cl = Class.forName(classname); URLClassLoader apploader = (URLClassLoader) cl.getClassLoader(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6959129.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6959129.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/hotspot/Test6959129.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,10 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Test6959129 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); public static long test() { int min = Integer.MAX_VALUE - 30000; @@ -82,7 +81,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/micro/ReferenceMap01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/micro/ReferenceMap01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/micro/ReferenceMap01.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,24 +32,24 @@ */ public class ReferenceMap01 extends JTTTest { - public static Integer val1 = new Integer(3); - public static Integer val2 = new Integer(4); + public static Integer val1 = Integer.valueOf(3); + public static Integer val2 = Integer.valueOf(4); @SuppressWarnings("unused") private static String foo(String[] a) { String[] args = new String[]{"78"}; - Integer i1 = new Integer(1); - Integer i2 = new Integer(2); + Integer i1 = Integer.valueOf(1); + Integer i2 = Integer.valueOf(2); Integer i3 = val1; Integer i4 = val2; - Integer i5 = new Integer(5); - Integer i6 = new Integer(6); - Integer i7 = new Integer(7); - Integer i8 = new Integer(8); - Integer i9 = new Integer(9); - Integer i10 = new Integer(10); - Integer i11 = new Integer(11); - Integer i12 = new Integer(12); + Integer i5 = Integer.valueOf(5); + Integer i6 = Integer.valueOf(6); + Integer i7 = Integer.valueOf(7); + Integer i8 = Integer.valueOf(8); + Integer i9 = Integer.valueOf(9); + Integer i10 = Integer.valueOf(10); + Integer i11 = Integer.valueOf(11); + Integer i12 = Integer.valueOf(12); System.gc(); int sum = i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance01.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,6 +32,7 @@ public final class Class_newInstance01 extends JTTTest { + @SuppressWarnings("deprecation") public static boolean test(int i) throws IllegalAccessException, InstantiationException { if (i == 0) { return Class_newInstance01.class.newInstance() != null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance02.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,6 +32,7 @@ public final class Class_newInstance02 extends JTTTest { + @SuppressWarnings("deprecation") public static boolean test(int i) throws IllegalAccessException, InstantiationException { if (i == 0) { // note: we rely on the other class here. diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance03.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance03.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance03.java Fri Aug 17 13:20:53 2018 -0700 @@ -35,6 +35,7 @@ public abstract static class AbstractClass { } + @SuppressWarnings("deprecation") public static boolean test(int i) throws IllegalAccessException, InstantiationException { if (i == 0) { return AbstractClass.class.newInstance() != null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance06.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance06.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance06.java Fri Aug 17 13:20:53 2018 -0700 @@ -40,6 +40,7 @@ } } + @SuppressWarnings("deprecation") public static boolean test(int i) throws IllegalAccessException, InstantiationException { if (i == 0) { return Class_newInstance.class.newInstance() != null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance07.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance07.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Class_newInstance07.java Fri Aug 17 13:20:53 2018 -0700 @@ -39,6 +39,7 @@ } } + @SuppressWarnings("deprecation") public static boolean test(int i) throws IllegalAccessException, InstantiationException { if (i == 0) { return Class_newInstance.class.newInstance() != null; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_contended01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_contended01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_contended01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public final class Monitor_contended01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { boolean started = false; @@ -84,7 +82,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_notowner01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_notowner01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitor_notowner01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Monitor_notowner01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); static Object monitor = new Object(); static Object finished = new Object(); @@ -73,7 +71,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public final class Monitorenter01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); static final Object object = new Object(); @@ -50,7 +48,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Monitorenter02.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public final class Monitorenter02 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); static final Object object = new Object(); @@ -54,7 +52,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Object_wait01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -69,25 +67,21 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test", 0); } @Test public void run1() throws Throwable { - initializeForTimeout(); runTest("test", 1); } @Test public void run2() throws Throwable { - initializeForTimeout(); runTest("test", 3); } @Test public void run3() throws Throwable { - initializeForTimeout(); runTest("test", 15); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait02.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Object_wait02 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -70,19 +68,16 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test", 0); } @Test public void run1() throws Throwable { - initializeForTimeout(); runTest("test", 1); } @Test public void run2() throws Throwable { - initializeForTimeout(); runTest("test", 2); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait03.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait03.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait03.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; import jdk.vm.ci.meta.ResolvedJavaMethod; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; public class Object_wait03 extends JTTTest { @@ -50,7 +48,7 @@ */ static final long TIMEOUT_MS = COMPILATION_TIMEOUT_MS * 2; - @Rule public TestRule timeout = NotOnDebug.create(Timeout.millis(TIMEOUT_MS)); + @Rule public TestRule timeout = createTimeoutMillis(TIMEOUT_MS); private static class TestClass implements Runnable { @Override @@ -121,7 +119,6 @@ } private void run(int i) throws Throwable { - initializeForTimeout(); try { runTest("test", i); } catch (CancellationBailoutException e) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait04.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait04.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Object_wait04.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Object_wait04 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -80,37 +78,31 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test", 0); } @Test public void run1() throws Throwable { - initializeForTimeout(); runTest("test", 1); } @Test public void run2() throws Throwable { - initializeForTimeout(); runTest("test", 2); } @Test public void run3() throws Throwable { - initializeForTimeout(); runTest("test", 3); } @Test public void run4() throws Throwable { - initializeForTimeout(); runTest("test", 4); } @Test public void run5() throws Throwable { - initializeForTimeout(); runTest("test", 5); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/SynchronizedLoopExit01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/SynchronizedLoopExit01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/SynchronizedLoopExit01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,9 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; /** * Inspired by {@code com.sun.media.sound.DirectAudioDevice$DirectDL.drain()}. @@ -41,7 +39,7 @@ */ public final class SynchronizedLoopExit01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); protected Object object = new Object(); protected volatile boolean drained = false; @@ -62,7 +60,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted02.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,17 +29,15 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; //Test all, mainly monitors public class Thread_isInterrupted02 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static final Object start = new Object(); private static final Object end = new Object(); @@ -112,13 +110,11 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test", 0, 0); } @Test public void run1() throws Throwable { - initializeForTimeout(); runTest("test", 1, 500); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted03.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted03.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted03.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,9 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; /* */ @@ -37,7 +35,7 @@ // Interrupted while sleeping, throws an interrupted exception public class Thread_isInterrupted03 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); public static boolean test() throws InterruptedException { final Thread1 thread = new Thread1(); @@ -78,7 +76,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted05.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted05.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_isInterrupted05.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,9 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; /* */ @@ -37,7 +35,7 @@ // Interrupted during wait, with interrupter joining public class Thread_isInterrupted05 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); public static boolean test() throws InterruptedException { final WaitInterruptee waitInterruptee = new WaitInterruptee(); @@ -76,7 +74,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Thread_join01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -56,7 +54,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join02.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join02.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join02.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Thread_join02 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -63,7 +61,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join03.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join03.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_join03.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public class Thread_join03 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); private static class TestClass implements Runnable { @Override @@ -60,7 +58,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_sleep01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_sleep01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_sleep01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public final class Thread_sleep01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); public static boolean test(int i) throws InterruptedException { final long before = System.currentTimeMillis(); @@ -45,19 +43,16 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test", 10); } @Test public void run1() throws Throwable { - initializeForTimeout(); runTest("test", 20); } @Test public void run2() throws Throwable { - initializeForTimeout(); runTest("test", 100); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_yield01.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_yield01.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/threads/Thread_yield01.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ package org.graalvm.compiler.jtt.threads; import org.graalvm.compiler.jtt.JTTTest; -import org.graalvm.compiler.jtt.hotspot.NotOnDebug; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; -import org.junit.rules.Timeout; public final class Thread_yield01 extends JTTTest { - @Rule public TestRule timeout = NotOnDebug.create(Timeout.seconds(20)); + @Rule public TestRule timeout = createTimeoutSeconds(20); public static boolean test() { Thread.yield(); @@ -44,7 +42,6 @@ @Test public void run0() throws Throwable { - initializeForTimeout(); runTest("test"); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayCompareToOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayCompareToOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArrayCompareToOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -28,9 +28,6 @@ import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; -import java.lang.reflect.Array; -import java.lang.reflect.Field; - import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.aarch64.AArch64Address; import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler; @@ -44,7 +41,6 @@ import jdk.vm.ci.code.Register; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.Value; -import sun.misc.Unsafe; /** * Emits code which compares two arrays lexicographically. If the CPU supports any vector @@ -82,10 +78,8 @@ this.kind2 = kind2; // Both offsets should be the same but better be safe than sorry. - Class array1Class = Array.newInstance(kind1.toJavaClass(), 0).getClass(); - Class array2Class = Array.newInstance(kind2.toJavaClass(), 0).getClass(); - this.array1BaseOffset = UNSAFE.arrayBaseOffset(array1Class); - this.array2BaseOffset = UNSAFE.arrayBaseOffset(array2Class); + this.array1BaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind1); + this.array2BaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind2); this.resultValue = result; @@ -111,22 +105,6 @@ this.temp6 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind())); } - private static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } - @Override protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64LIRFlagsVersioned.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64LIRFlagsVersioned.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64LIRFlagsVersioned.java Fri Aug 17 13:20:53 2018 -0700 @@ -34,4 +34,4 @@ AArch64 aarch64 = (AArch64) arch; return aarch64.getFeatures().contains(CPUFeature.LSE) || aarch64.getFlags().contains(Flag.UseLSE); } -} \ No newline at end of file +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,13 +32,11 @@ import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; -import java.lang.reflect.Array; -import java.lang.reflect.Field; +import java.util.EnumSet; import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AvxVectorLen; import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.core.common.LIRKind; @@ -54,7 +52,6 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.Value; -import sun.misc.Unsafe; /** * Emits code which compares two arrays lexicographically. If the CPU supports any vector @@ -87,10 +84,8 @@ this.kind2 = kind2; // Both offsets should be the same but better be safe than sorry. - Class array1Class = Array.newInstance(kind1.toJavaClass(), 0).getClass(); - Class array2Class = Array.newInstance(kind2.toJavaClass(), 0).getClass(); - this.array1BaseOffset = UNSAFE.arrayBaseOffset(array1Class); - this.array2BaseOffset = UNSAFE.arrayBaseOffset(array2Class); + this.array1BaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind1); + this.array2BaseOffset = tool.getProviders().getArrayOffsetProvider().arrayBaseOffset(kind2); this.resultValue = result; this.array1Value = array1; @@ -126,9 +121,9 @@ return arch.getFeatures().contains(CPUFeature.AVX2); } - private static boolean supportsAVX512VLBW(@SuppressWarnings("unused") TargetDescription target) { - // TODO Add EVEX encoder in our assembler. - return false; + private static boolean supportsAVX512VLBW(TargetDescription target) { + EnumSet features = ((AMD64) target.arch).getFeatures(); + return features.contains(CPUFeature.AVX512BW) && features.contains(CPUFeature.AVX512VL); } @Override @@ -326,15 +321,15 @@ masm.bind(COMPARE_WIDE_VECTORS_LOOP_AVX3); // the hottest loop // if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) { if (kind1 == kind2) { - masm.evmovdquq(vec1, new AMD64Address(str1, result, scale), AvxVectorLen.AVX_512bit); + masm.evmovdqu64(vec1, new AMD64Address(str1, result, scale)); // k7 == 11..11, if operands equal, otherwise k7 has some 0 - masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale), AvxVectorLen.AVX_512bit); + masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale)); } else { - masm.vpmovzxbw(vec1, new AMD64Address(str1, result, scale1), AvxVectorLen.AVX_512bit); + masm.evpmovzxbw(vec1, new AMD64Address(str1, result, scale1)); // k7 == 11..11, if operands equal, otherwise k7 has some 0 - masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale2), AvxVectorLen.AVX_512bit); + masm.evpcmpeqb(k7, vec1, new AMD64Address(str2, result, scale2)); } - masm.kortestql(k7, k7); + masm.kortestq(k7, k7); masm.jcc(ConditionFlag.AboveEqual, COMPARE_WIDE_VECTORS_LOOP_FAILED); // miscompare masm.addq(result, stride2x2); // update since we already compared at this addr masm.subl(cnt2, stride2x2); // and sub the size too @@ -350,7 +345,7 @@ masm.vmovdqu(vec1, new AMD64Address(str1, result, scale)); masm.vpxor(vec1, vec1, new AMD64Address(str2, result, scale)); } else { - masm.vpmovzxbw(vec1, new AMD64Address(str1, result, scale1), AvxVectorLen.AVX_256bit); + masm.vpmovzxbw(vec1, new AMD64Address(str1, result, scale1)); masm.vpxor(vec1, vec1, new AMD64Address(str2, result, scale2)); } masm.vptest(vec1, vec1); @@ -532,7 +527,7 @@ if (supportsAVX512VLBW(crb.target)) { masm.bind(COMPARE_WIDE_VECTORS_LOOP_FAILED); - masm.kmovql(cnt1, k7); + masm.kmovq(cnt1, k7); masm.notq(cnt1); masm.bsfq(cnt2, cnt1); // if (ae != StrIntrinsicNode::LL) { @@ -584,20 +579,4 @@ masm.movzwl(elem2, new AMD64Address(str2, index, scale2, 0)); } } - - private static final Unsafe UNSAFE = initUnsafe(); - - private static Unsafe initUnsafe() { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - return (Unsafe) theUnsafe.get(Unsafe.class); - } catch (Exception e) { - throw new RuntimeException("exception while trying to get Unsafe", e); - } - } - } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -32,8 +32,8 @@ import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.NumUtil; @@ -277,7 +277,7 @@ Label loopCheck = new Label(); Label nanCheck = new Label(); - // Compare 16-byte vectors + // Compare 32-byte vectors masm.andl(result, AVX_VECTOR_SIZE - 1); // tail count (in bytes) masm.andl(length, ~(AVX_VECTOR_SIZE - 1)); // vector count (in bytes) masm.jcc(ConditionFlag.Zero, compareTail); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.lir.amd64; + +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; +import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; + +import org.graalvm.compiler.asm.Label; +import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMIOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.asm.amd64.AVXKind; +import org.graalvm.compiler.core.common.LIRKind; +import org.graalvm.compiler.lir.LIRInstructionClass; +import org.graalvm.compiler.lir.Opcode; +import org.graalvm.compiler.lir.asm.CompilationResultBuilder; +import org.graalvm.compiler.lir.gen.LIRGeneratorTool; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.amd64.AMD64.CPUFeature; +import jdk.vm.ci.amd64.AMD64Kind; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.Value; + +/** + */ +@Opcode("AMD64_ARRAY_INDEX_OF") +public final class AMD64ArrayIndexOfOp extends AMD64LIRInstruction { + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64ArrayIndexOfOp.class); + + private final JavaKind kind; + private final int vmPageSize; + + @Def({REG}) protected Value resultValue; + @Alive({REG}) protected Value charArrayPtrValue; + @Use({REG}) protected Value charArrayLengthValue; + @Alive({REG}) protected Value searchCharValue; + @Temp({REG}) protected Value arraySlotsRemaining; + @Temp({REG}) protected Value comparisonResult1; + @Temp({REG}) protected Value comparisonResult2; + @Temp({REG}) protected Value comparisonResult3; + @Temp({REG}) protected Value comparisonResult4; + @Temp({REG, ILLEGAL}) protected Value vectorCompareVal; + @Temp({REG, ILLEGAL}) protected Value vectorArray1; + @Temp({REG, ILLEGAL}) protected Value vectorArray2; + @Temp({REG, ILLEGAL}) protected Value vectorArray3; + @Temp({REG, ILLEGAL}) protected Value vectorArray4; + + public AMD64ArrayIndexOfOp( + JavaKind kind, + int vmPageSize, LIRGeneratorTool tool, + Value result, + Value arrayPtr, + Value arrayLength, + Value searchChar) { + super(TYPE); + this.kind = kind; + this.vmPageSize = vmPageSize; + assert byteMode() || charMode(); + assert supports(tool, CPUFeature.SSSE3) || supports(tool, CPUFeature.AVX) || supportsAVX2(tool); + resultValue = result; + charArrayPtrValue = arrayPtr; + charArrayLengthValue = arrayLength; + searchCharValue = searchChar; + + this.arraySlotsRemaining = tool.newVariable(LIRKind.value(AMD64Kind.DWORD)); + this.comparisonResult1 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD)); + this.comparisonResult2 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD)); + this.comparisonResult3 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD)); + this.comparisonResult4 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD)); + AMD64Kind vectorKind = byteMode() ? supportsAVX2(tool) ? AMD64Kind.V256_BYTE : AMD64Kind.V128_BYTE : supportsAVX2(tool) ? AMD64Kind.V256_WORD : AMD64Kind.V128_WORD; + this.vectorCompareVal = tool.newVariable(LIRKind.value(vectorKind)); + this.vectorArray1 = tool.newVariable(LIRKind.value(vectorKind)); + this.vectorArray2 = tool.newVariable(LIRKind.value(vectorKind)); + this.vectorArray3 = tool.newVariable(LIRKind.value(vectorKind)); + this.vectorArray4 = tool.newVariable(LIRKind.value(vectorKind)); + } + + private boolean byteMode() { + return kind == JavaKind.Byte; + } + + private boolean charMode() { + return kind == JavaKind.Char; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) { + Register arrayPtr = asRegister(charArrayPtrValue); + Register arrayLength = asRegister(charArrayLengthValue); + Register searchValue = asRegister(searchCharValue); + Register result = asRegister(resultValue); + Register vecCmp = asRegister(vectorCompareVal); + Register vecArray1 = asRegister(vectorArray1); + Register vecArray2 = asRegister(vectorArray2); + Register vecArray3 = asRegister(vectorArray3); + Register vecArray4 = asRegister(vectorArray4); + Register slotsRemaining = asRegister(arraySlotsRemaining); + Register cmpResult1 = asRegister(comparisonResult1); + Register cmpResult2 = asRegister(comparisonResult2); + Register cmpResult3 = asRegister(comparisonResult3); + Register cmpResult4 = asRegister(comparisonResult4); + + Label bulkVectorLoop = new Label(); + Label singleVectorLoop = new Label(); + Label vectorFound1 = new Label(); + Label vectorFound2 = new Label(); + Label vectorFound3 = new Label(); + Label vectorFound4 = new Label(); + Label lessThanVectorSizeRemaining = new Label(); + Label lessThanVectorSizeRemainingLoop = new Label(); + Label retFound = new Label(); + Label retNotFound = new Label(); + Label end = new Label(); + + AVXKind.AVXSize vectorSize = asm.supports(CPUFeature.AVX2) ? AVXKind.AVXSize.YMM : AVXKind.AVXSize.XMM; + int nVectors = 4; + int bytesPerVector = vectorSize.getBytes(); + int arraySlotsPerVector = vectorSize.getBytes() / kind.getByteCount(); + int bulkSize = arraySlotsPerVector * nVectors; + int bulkSizeBytes = bytesPerVector * nVectors; + assert bulkSizeBytes >= 64; + + // load array length + // important: this must be the first register manipulation, since charArrayLengthValue is + // annotated with @Use + asm.movl(slotsRemaining, arrayLength); + // move search value to vector + if (asm.supports(CPUFeature.AVX)) { + VexMoveOp.VMOVD.emit(asm, AVXKind.AVXSize.DWORD, vecCmp, searchValue); + } else { + asm.movdl(vecCmp, searchValue); + } + // load array pointer + asm.movq(result, arrayPtr); + // load copy of low part of array pointer + asm.movl(cmpResult1, arrayPtr); + // fill comparison vector with copies of the search value + emitBroadcast(asm, vecCmp, vecArray1, vectorSize); + + // check if bulk vector load is in bounds + asm.cmpl(slotsRemaining, bulkSize); + asm.jcc(AMD64Assembler.ConditionFlag.Below, singleVectorLoop); + + // check if array pointer is 64-byte aligned + asm.andl(cmpResult1, 63); + asm.jcc(AMD64Assembler.ConditionFlag.Zero, bulkVectorLoop); + + // do one unaligned bulk comparison pass and adjust alignment afterwards + emitBulkCompare(asm, vectorSize, bytesPerVector, result, vecCmp, vecArray1, vecArray2, vecArray3, vecArray4, cmpResult1, cmpResult2, cmpResult3, cmpResult4, + vectorFound1, vectorFound2, vectorFound3, vectorFound4, false); + // load copy of low part of array pointer + asm.movl(cmpResult1, arrayPtr); + // adjust array pointer + asm.addq(result, bulkSizeBytes); + // adjust number of array slots remaining + asm.subl(slotsRemaining, bulkSize); + // get offset to 64-byte alignment + asm.andl(cmpResult1, 63); + emitBytesToArraySlots(asm, cmpResult1); + // adjust array pointer to 64-byte alignment + asm.andq(result, ~63); + // adjust number of array slots remaining + asm.addl(slotsRemaining, cmpResult1); + // check if there are enough array slots remaining for the bulk loop + asm.cmpl(slotsRemaining, bulkSize); + asm.jcc(AMD64Assembler.ConditionFlag.Below, singleVectorLoop); + + emitAlign(crb, asm); + asm.bind(bulkVectorLoop); + // memory-aligned bulk comparison + emitBulkCompare(asm, vectorSize, bytesPerVector, result, vecCmp, vecArray1, vecArray2, vecArray3, vecArray4, cmpResult1, cmpResult2, cmpResult3, cmpResult4, + vectorFound1, vectorFound2, vectorFound3, vectorFound4, true); + // adjust number of array slots remaining + asm.subl(slotsRemaining, bulkSize); + // adjust array pointer + asm.addq(result, bulkSizeBytes); + // check if there are enough array slots remaining for the bulk loop + asm.cmpl(slotsRemaining, bulkSize); + asm.jcc(AMD64Assembler.ConditionFlag.Below, singleVectorLoop); + // continue loop + asm.jmpb(bulkVectorLoop); + + emitAlign(crb, asm); + // same loop as bulkVectorLoop, with only one vector + asm.bind(singleVectorLoop); + // check if single vector load is in bounds + asm.cmpl(slotsRemaining, arraySlotsPerVector); + asm.jcc(AMD64Assembler.ConditionFlag.Below, lessThanVectorSizeRemaining); + // compare + emitSingleVectorCompare(asm, vectorSize, result, vecCmp, vecArray1, cmpResult1); + + // check if a match was found + asm.testl(cmpResult1, cmpResult1); + asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound1); + // adjust number of array slots remaining + asm.subl(slotsRemaining, arraySlotsPerVector); + // adjust array pointer + asm.addq(result, bytesPerVector); + // continue loop + asm.jmpb(singleVectorLoop); + + asm.bind(lessThanVectorSizeRemaining); + // check if any array slots remain + asm.testl(slotsRemaining, slotsRemaining); + asm.jcc(AMD64Assembler.ConditionFlag.Zero, retNotFound); + + // a vector compare will read out of bounds of the input array. + // check if the out-of-bounds read would cross a memory page boundary. + // load copy of low part of array pointer + asm.movl(cmpResult1, result); + // check if pointer + vector size would cross the page boundary + asm.andl(cmpResult1, (vmPageSize - 1)); + asm.cmpl(cmpResult1, (vmPageSize - bytesPerVector)); + // if the page boundary would be crossed, do byte/character-wise comparison instead. + asm.jccb(AMD64Assembler.ConditionFlag.Above, lessThanVectorSizeRemainingLoop); + // otherwise, do a vector compare that reads beyond array bounds + emitSingleVectorCompare(asm, vectorSize, result, vecCmp, vecArray1, cmpResult1); + // check if a match was found + asm.testl(cmpResult1, cmpResult1); + asm.jcc(AMD64Assembler.ConditionFlag.Zero, retNotFound); + // find match offset + asm.bsfq(cmpResult1, cmpResult1); + if (charMode()) { + // convert number of remaining characters to bytes + asm.shll(slotsRemaining, 1); + } + // adjust array pointer for match result + asm.addq(result, cmpResult1); + // check if offset of matched value is greater than number of bytes remaining / out of array + // bounds + asm.cmpl(cmpResult1, slotsRemaining); + // match is out of bounds, return no match + asm.jcc(AMD64Assembler.ConditionFlag.GreaterEqual, retNotFound); + // match is in bounds, return offset + asm.jmpb(retFound); + + // compare remaining slots in the array one-by-one + asm.bind(lessThanVectorSizeRemainingLoop); + // check if any array slots remain + asm.testl(slotsRemaining, slotsRemaining); + asm.jcc(AMD64Assembler.ConditionFlag.Zero, retNotFound); + // load char / byte + AMD64Assembler.OperandSize operandSize = byteMode() ? AMD64Assembler.OperandSize.BYTE : AMD64Assembler.OperandSize.WORD; + if (byteMode()) { + AMD64Assembler.AMD64RMOp.MOVB.emit(asm, operandSize, cmpResult1, new AMD64Address(result)); + } else { + AMD64Assembler.AMD64RMOp.MOV.emit(asm, operandSize, cmpResult1, new AMD64Address(result)); + } + // check for match + AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(operandSize).emit(asm, operandSize, cmpResult1, searchValue); + asm.jcc(AMD64Assembler.ConditionFlag.Equal, retFound); + // adjust number of array slots remaining + asm.decrementl(slotsRemaining); + // adjust array pointer + asm.addq(result, kind.getByteCount()); + // continue loop + asm.jmpb(lessThanVectorSizeRemainingLoop); + + // return -1 (no match) + asm.bind(retNotFound); + asm.movl(result, -1); + asm.jmpb(end); + + emitVectorFoundWithOffset(asm, bytesPerVector, result, cmpResult2, vectorFound2, retFound); + emitVectorFoundWithOffset(asm, bytesPerVector * 2, result, cmpResult3, vectorFound3, retFound); + emitVectorFoundWithOffset(asm, bytesPerVector * 3, result, cmpResult4, vectorFound4, retFound); + + asm.bind(vectorFound1); + // find index of first set bit in bit mask + asm.bsfq(cmpResult1, cmpResult1); + // add offset to array pointer + asm.addq(result, cmpResult1); + + asm.bind(retFound); + // convert array pointer to offset + asm.subq(result, arrayPtr); + emitBytesToArraySlots(asm, result); + asm.bind(end); + } + + private static void emitAlign(CompilationResultBuilder crb, AMD64MacroAssembler asm) { + asm.align(crb.target.wordSize * 2); + } + + /** + * Fills {@code vecDst} with copies of its lowest byte or word. + */ + private void emitBroadcast(AMD64MacroAssembler asm, Register vecDst, Register vecTmp, AVXKind.AVXSize vectorSize) { + if (asm.supports(CPUFeature.AVX2)) { + if (byteMode()) { + VexRMOp.VPBROADCASTB.emit(asm, vectorSize, vecDst, vecDst); + } else { + VexRMOp.VPBROADCASTW.emit(asm, vectorSize, vecDst, vecDst); + } + } else if (asm.supports(CPUFeature.AVX)) { + if (byteMode()) { + // fill vecTmp with zeroes + VexRVMOp.VPXOR.emit(asm, vectorSize, vecTmp, vecTmp, vecTmp); + // broadcast loaded search value + VexRVMOp.VPSHUFB.emit(asm, vectorSize, vecDst, vecDst, vecTmp); + } else { + // fill low qword + VexRMIOp.VPSHUFLW.emit(asm, vectorSize, vecDst, vecDst, 0); + // copy low qword to high qword + VexRMIOp.VPSHUFD.emit(asm, vectorSize, vecDst, vecDst, 0); + } + } else { + // SSE version + if (byteMode()) { + // fill vecTmp with zeroes + asm.pxor(vecTmp, vecTmp); + // broadcast loaded search value + asm.pshufb(vecDst, vecTmp); + } else { + // fill low qword + asm.pshuflw(vecDst, vecDst, 0); + // copy low qword to high qword + asm.pshufd(vecDst, vecDst, 0); + } + } + } + + /** + * Loads {@code vectorSize} bytes from the position pointed to by {@code arrayPtr} and compares + * them to the search value stored in {@code vecCmp}. {@code vecArray} is overwritten by this + * operation. The comparison result is stored in {@code cmpResult}. + */ + private void emitSingleVectorCompare(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, + Register arrayPtr, Register vecCmp, Register vecArray, Register cmpResult) { + // load array contents into vector + emitArrayLoad(asm, vectorSize, vecArray, arrayPtr, 0, false); + // compare all loaded bytes to the search value. + emitVectorCompare(asm, vectorSize, vecArray, vecCmp); + // create a 32-bit-mask from the most significant bit of every byte in the comparison + // result. + emitMOVMSK(asm, vectorSize, cmpResult, vecArray); + } + + /** + * Convert a byte offset stored in {@code bytes} to an array index offset. + */ + private void emitBytesToArraySlots(AMD64MacroAssembler asm, Register bytes) { + if (charMode()) { + asm.shrl(bytes, 1); + } else { + assert byteMode(); + } + } + + private void emitBulkCompare(AMD64MacroAssembler asm, + AVXKind.AVXSize vectorSize, + int bytesPerVector, + Register arrayPtr, + Register vecCmp, + Register vecArray1, + Register vecArray2, + Register vecArray3, + Register vecArray4, + Register cmpResult1, + Register cmpResult2, + Register cmpResult3, + Register cmpResult4, + Label vectorFound1, + Label vectorFound2, + Label vectorFound3, + Label vectorFound4, + boolean alignedLoad) { + // load array contents into vectors + emitArrayLoad(asm, vectorSize, vecArray1, arrayPtr, 0, alignedLoad); + emitArrayLoad(asm, vectorSize, vecArray2, arrayPtr, bytesPerVector, alignedLoad); + emitArrayLoad(asm, vectorSize, vecArray3, arrayPtr, bytesPerVector * 2, alignedLoad); + emitArrayLoad(asm, vectorSize, vecArray4, arrayPtr, bytesPerVector * 3, alignedLoad); + // compare all loaded bytes to the search value. + // matching bytes are set to 0xff, non-matching bytes are set to 0x00. + emitVectorCompare(asm, vectorSize, vecArray1, vecCmp); + emitVectorCompare(asm, vectorSize, vecArray2, vecCmp); + emitVectorCompare(asm, vectorSize, vecArray3, vecCmp); + emitVectorCompare(asm, vectorSize, vecArray4, vecCmp); + // create 32-bit-masks from the most significant bit of every byte in the comparison + // results. + emitMOVMSK(asm, vectorSize, cmpResult1, vecArray1); + emitMOVMSK(asm, vectorSize, cmpResult2, vecArray2); + emitMOVMSK(asm, vectorSize, cmpResult3, vecArray3); + emitMOVMSK(asm, vectorSize, cmpResult4, vecArray4); + // check if a match was found + asm.testl(cmpResult1, cmpResult1); + asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound1); + asm.testl(cmpResult2, cmpResult2); + asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound2); + asm.testl(cmpResult3, cmpResult3); + asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound3); + asm.testl(cmpResult4, cmpResult4); + asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound4); + } + + private static void emitVectorFoundWithOffset(AMD64MacroAssembler asm, int resultOffset, Register result, Register cmpResult, Label entry, Label ret) { + asm.bind(entry); + if (resultOffset > 0) { + // adjust array pointer + asm.addq(result, resultOffset); + } + // find index of first set bit in bit mask + asm.bsfq(cmpResult, cmpResult); + // add offset to array pointer + asm.addq(result, cmpResult); + asm.jmpb(ret); + } + + private static void emitArrayLoad(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecDst, Register arrayPtr, int offset, boolean alignedLoad) { + AMD64Address src = new AMD64Address(arrayPtr, offset); + if (asm.supports(CPUFeature.AVX)) { + VexMoveOp loadOp = alignedLoad ? VexMoveOp.VMOVDQA : VexMoveOp.VMOVDQU; + loadOp.emit(asm, vectorSize, vecDst, src); + } else { + // SSE + asm.movdqu(vecDst, src); + } + } + + private void emitVectorCompare(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecArray, Register vecCmp) { + // compare all loaded bytes to the search value. + // matching bytes are set to 0xff, non-matching bytes are set to 0x00. + if (asm.supports(CPUFeature.AVX)) { + if (byteMode()) { + VexRVMOp.VPCMPEQB.emit(asm, vectorSize, vecArray, vecCmp, vecArray); + } else { + VexRVMOp.VPCMPEQW.emit(asm, vectorSize, vecArray, vecCmp, vecArray); + } + } else { + // SSE + if (byteMode()) { + asm.pcmpeqb(vecArray, vecCmp); + } else { + asm.pcmpeqw(vecArray, vecCmp); + } + } + } + + private static void emitMOVMSK(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) { + if (asm.supports(CPUFeature.AVX)) { + VexRMOp.VPMOVMSKB.emit(asm, vectorSize, dst, vecSrc); + } else { + // SSE + asm.pmovmskb(dst, vecSrc); + } + } + + private static boolean supportsAVX2(LIRGeneratorTool tool) { + return supports(tool, CPUFeature.AVX2); + } + + private static boolean supports(LIRGeneratorTool tool, CPUFeature cpuFeature) { + return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Binary.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Binary.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Binary.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,25 +24,24 @@ package org.graalvm.compiler.lir.amd64; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isRegister; +import static jdk.vm.ci.code.ValueUtil.isStackSlot; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; import static org.graalvm.compiler.lir.LIRValueUtil.differentRegisters; import static org.graalvm.compiler.lir.LIRValueUtil.sameRegister; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import static jdk.vm.ci.code.ValueUtil.isRegister; -import static jdk.vm.ci.code.ValueUtil.isStackSlot; -import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; @@ -99,40 +98,6 @@ } /** - * Instruction that has three {@link AllocatableValue} operands. - */ - public static class ThreeOp extends AMD64LIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ThreeOp.class); - - @Opcode private final AMD64RRMOp opcode; - private final OperandSize size; - - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - @Use({REG, STACK}) protected AllocatableValue y; - - public ThreeOp(AMD64RRMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) { - super(TYPE); - this.opcode = opcode; - this.size = size; - - this.result = result; - this.x = x; - this.y = y; - } - - @Override - public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (isRegister(y)) { - opcode.emit(masm, size, asRegister(result), asRegister(x), asRegister(y)); - } else { - assert isStackSlot(y); - opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asAddress(y)); - } - } - } - - /** * Commutative instruction that has two {@link AllocatableValue} operands. */ public static class CommutativeTwoOp extends AMD64LIRInstruction { @@ -175,40 +140,6 @@ } /** - * Commutative instruction that has three {@link AllocatableValue} operands. - */ - public static class CommutativeThreeOp extends AMD64LIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(CommutativeThreeOp.class); - - @Opcode private final AMD64RRMOp opcode; - private final OperandSize size; - - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - @Use({REG, STACK}) protected AllocatableValue y; - - public CommutativeThreeOp(AMD64RRMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) { - super(TYPE); - this.opcode = opcode; - this.size = size; - - this.result = result; - this.x = x; - this.y = y; - } - - @Override - public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (isRegister(y)) { - opcode.emit(masm, size, asRegister(result), asRegister(x), asRegister(y)); - } else { - assert isStackSlot(y); - opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asAddress(y)); - } - } - } - - /** * Instruction that has one {@link AllocatableValue} operand and one 32-bit immediate operand. */ public static class ConstOp extends AMD64LIRInstruction { @@ -282,44 +213,6 @@ } /** - * Instruction that has two {@link AllocatableValue} operands and one - * {@link DataSectionReference} operand. - */ - public static class DataThreeOp extends AMD64LIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(DataThreeOp.class); - - @Opcode private final AMD64RRMOp opcode; - private final OperandSize size; - - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - private final JavaConstant y; - - private final int alignment; - - public DataThreeOp(AMD64RRMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y) { - this(opcode, size, result, x, y, y.getJavaKind().getByteCount()); - } - - public DataThreeOp(AMD64RRMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, JavaConstant y, int alignment) { - super(TYPE); - this.opcode = opcode; - this.size = size; - - this.result = result; - this.x = x; - this.y = y; - - this.alignment = alignment; - } - - @Override - public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.recordDataReferenceInCode(y, alignment)); - } - } - - /** * Instruction that has one {@link AllocatableValue} operand and one {@link AMD64AddressValue * memory} operand. */ @@ -373,58 +266,6 @@ } /** - * Instruction that has one {@link AllocatableValue} operand and one {@link AMD64AddressValue - * memory} operand. - */ - public static class MemoryThreeOp extends AMD64LIRInstruction implements ImplicitNullCheck { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MemoryThreeOp.class); - - @Opcode private final AMD64RRMOp opcode; - private final OperandSize size; - - @Def({REG}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - @Use({COMPOSITE}) protected AMD64AddressValue y; - - @State protected LIRFrameState state; - - public MemoryThreeOp(AMD64RRMOp opcode, OperandSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) { - super(TYPE); - this.opcode = opcode; - this.size = size; - - this.result = result; - this.x = x; - this.y = y; - - this.state = state; - } - - @Override - public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (state != null) { - crb.recordImplicitException(masm.position(), state); - } - opcode.emit(masm, size, asRegister(result), asRegister(x), y.toAddress()); - } - - @Override - public void verify() { - super.verify(); - assert differentRegisters(result, y) || sameRegister(x, y); - } - - @Override - public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) { - if (state == null && y.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) { - state = nullCheckState; - return true; - } - return false; - } - } - - /** * Instruction with a separate result operand, one {@link AllocatableValue} input and one 32-bit * immediate input. */ diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64BinaryConsumer.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64BinaryConsumer.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64BinaryConsumer.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,22 +24,22 @@ package org.graalvm.compiler.lir.amd64; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isRegister; +import static jdk.vm.ci.code.ValueUtil.isStackSlot; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import static jdk.vm.ci.code.ValueUtil.isRegister; -import static jdk.vm.ci.code.ValueUtil.isStackSlot; -import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MROp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; @@ -121,12 +121,16 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(x)) { - opcode.emit(masm, size, asRegister(x), y); + opcode.emit(masm, size, asRegister(x), y, shouldAnnotate()); } else { assert isStackSlot(x); - opcode.emit(masm, size, (AMD64Address) crb.asAddress(x), y); + opcode.emit(masm, size, (AMD64Address) crb.asAddress(x), y, shouldAnnotate()); } } + + protected boolean shouldAnnotate() { + return false; + } } /** @@ -148,6 +152,11 @@ crb.recordInlineDataInCode(c); super.emitCode(crb, masm); } + + @Override + protected boolean shouldAnnotate() { + return true; + } } /** @@ -313,7 +322,11 @@ if (state != null) { crb.recordImplicitException(masm.position(), state); } - opcode.emit(masm, size, x.toAddress(), y); + opcode.emit(masm, size, x.toAddress(), y, shouldAnnotate()); + } + + protected boolean shouldAnnotate() { + return false; } @Override @@ -349,5 +362,10 @@ crb.recordInlineDataInCode(c); super.emitCode(crb, masm); } + + @Override + protected boolean shouldAnnotate() { + return true; + } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ClearRegisterOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ClearRegisterOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ClearRegisterOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,12 +24,12 @@ package org.graalvm.compiler.lir.amd64; +import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; -import static jdk.vm.ci.code.ValueUtil.asRegister; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Move.java Fri Aug 17 13:20:53 2018 -0700 @@ -46,7 +46,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.LIRKind; @@ -572,6 +572,7 @@ if (asRegister(input).equals(asRegister(result))) { return; } + assert asRegister(result).getRegisterCategory().equals(asRegister(input).getRegisterCategory()); switch (kind) { case BYTE: case WORD: @@ -701,7 +702,7 @@ } } else if (crb.target.inlineObjects) { crb.recordInlineDataInCode(input); - masm.movq(result, 0xDEADDEADDEADDEADL); + masm.movq(result, 0xDEADDEADDEADDEADL, true); } else { masm.movq(result, (AMD64Address) crb.recordDataReferenceInCode(input, 0)); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64MulDivOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64MulDivOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64MulDivOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,6 +24,10 @@ package org.graalvm.compiler.lir.amd64; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isIllegal; +import static jdk.vm.ci.code.ValueUtil.isRegister; +import static jdk.vm.ci.code.ValueUtil.isStackSlot; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.DIV; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.IDIV; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp.IMUL; @@ -31,14 +35,10 @@ import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import static jdk.vm.ci.code.ValueUtil.isIllegal; -import static jdk.vm.ci.code.ValueUtil.isRegister; -import static jdk.vm.ci.code.ValueUtil.isStackSlot; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.lir.LIRFrameState; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ShiftOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ShiftOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ShiftOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,13 +24,13 @@ package org.graalvm.compiler.lir.amd64; +import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; -import static jdk.vm.ci.code.ValueUtil.asRegister; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SignExtendOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SignExtendOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64SignExtendOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,12 +24,12 @@ package org.graalvm.compiler.lir.amd64; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD; -import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD; +import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.lir.LIRInstructionClass; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringIndexOfOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringIndexOfOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64StringIndexOfOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,10 +27,15 @@ import static jdk.vm.ci.amd64.AMD64.rax; import static jdk.vm.ci.amd64.AMD64.rcx; import static jdk.vm.ci.amd64.AMD64.rdx; +import static jdk.vm.ci.amd64.AMD64.rsp; import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; +import org.graalvm.compiler.asm.Label; +import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; @@ -96,9 +101,430 @@ Register vec = asRegister(vectorTemp1); Register tmp = asRegister(temp1); if (intCnt2 >= 8) { - masm.stringIndexofC8(charPtr1, charPtr2, cnt1, cnt2, intCnt2, result, vec, tmp); + // IndexOf for constant substrings with size >= 8 chars which don't need to be loaded + // through stack. + stringIndexofC8(masm, charPtr1, charPtr2, cnt1, cnt2, result, vec, tmp); } else { - masm.stringIndexOf(charPtr1, charPtr2, cnt1, cnt2, intCnt2, result, vec, tmp, vmPageSize); + // Small strings are loaded through stack if they cross page boundary. + stringIndexOf(masm, charPtr1, charPtr2, cnt1, cnt2, result, vec, tmp); } } + + private void stringIndexofC8(AMD64MacroAssembler masm, Register charPtr1, Register charPtr2, Register cnt1, Register cnt2, Register result, Register vec, Register tmp) { + // assert(UseSSE42Intrinsics, "SSE4.2 is required"); + + // This method uses pcmpestri inxtruction with bound registers + // inputs: + // xmm - substring + // rax - substring length (elements count) + // mem - scanned string + // rdx - string length (elements count) + // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) + // outputs: + // rcx - matched index in string + assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; + + Label reloadSubstr = new Label(); + Label scanToSubstr = new Label(); + Label scanSubstr = new Label(); + Label retFound = new Label(); + Label retNotFound = new Label(); + Label exit = new Label(); + Label foundSubstr = new Label(); + Label matchSubstrHead = new Label(); + Label reloadStr = new Label(); + Label foundCandidate = new Label(); + + // Note, inline_string_indexOf() generates checks: + // if (substr.count > string.count) return -1; + // if (substr.count == 0) return 0; + assert intCnt2 >= 8 : "this code isused only for cnt2 >= 8 chars"; + + // Load substring. + masm.movdqu(vec, new AMD64Address(charPtr2, 0)); + masm.movl(cnt2, intCnt2); + masm.movq(result, charPtr1); // string addr + + if (intCnt2 > 8) { + masm.jmpb(scanToSubstr); + + // Reload substr for rescan, this code + // is executed only for large substrings (> 8 chars) + masm.bind(reloadSubstr); + masm.movdqu(vec, new AMD64Address(charPtr2, 0)); + masm.negq(cnt2); // Jumped here with negative cnt2, convert to positive + + masm.bind(reloadStr); + // We came here after the beginning of the substring was + // matched but the rest of it was not so we need to search + // again. Start from the next element after the previous match. + + // cnt2 is number of substring reminding elements and + // cnt1 is number of string reminding elements when cmp failed. + // Restored cnt1 = cnt1 - cnt2 + int_cnt2 + masm.subl(cnt1, cnt2); + masm.addl(cnt1, intCnt2); + masm.movl(cnt2, intCnt2); // Now restore cnt2 + + masm.decrementl(cnt1, 1); // Shift to next element + masm.cmpl(cnt1, cnt2); + masm.jccb(ConditionFlag.Negative, retNotFound); // Left less then substring + + masm.addq(result, 2); + + } // (int_cnt2 > 8) + + // Scan string for start of substr in 16-byte vectors + masm.bind(scanToSubstr); + masm.pcmpestri(vec, new AMD64Address(result, 0), 0x0d); + masm.jccb(ConditionFlag.Below, foundCandidate); // CF == 1 + masm.subl(cnt1, 8); + masm.jccb(ConditionFlag.LessEqual, retNotFound); // Scanned full string + masm.cmpl(cnt1, cnt2); + masm.jccb(ConditionFlag.Negative, retNotFound); // Left less then substring + masm.addq(result, 16); + masm.jmpb(scanToSubstr); + + // Found a potential substr + masm.bind(foundCandidate); + // Matched whole vector if first element matched (tmp(rcx) == 0). + if (intCnt2 == 8) { + masm.jccb(ConditionFlag.Overflow, retFound); // OF == 1 + } else { // int_cnt2 > 8 + masm.jccb(ConditionFlag.Overflow, foundSubstr); + } + // After pcmpestri tmp(rcx) contains matched element index + // Compute start addr of substr + masm.leaq(result, new AMD64Address(result, tmp, Scale.Times2, 0)); + + // Make sure string is still long enough + masm.subl(cnt1, tmp); + masm.cmpl(cnt1, cnt2); + if (intCnt2 == 8) { + masm.jccb(ConditionFlag.GreaterEqual, scanToSubstr); + } else { // int_cnt2 > 8 + masm.jccb(ConditionFlag.GreaterEqual, matchSubstrHead); + } + // Left less then substring. + + masm.bind(retNotFound); + masm.movl(result, -1); + masm.jmpb(exit); + + if (intCnt2 > 8) { + // This code is optimized for the case when whole substring + // is matched if its head is matched. + masm.bind(matchSubstrHead); + masm.pcmpestri(vec, new AMD64Address(result, 0), 0x0d); + // Reload only string if does not match + masm.jccb(ConditionFlag.NoOverflow, reloadStr); // OF == 0 + + Label contScanSubstr = new Label(); + // Compare the rest of substring (> 8 chars). + masm.bind(foundSubstr); + // First 8 chars are already matched. + masm.negq(cnt2); + masm.addq(cnt2, 8); + + masm.bind(scanSubstr); + masm.subl(cnt1, 8); + masm.cmpl(cnt2, -8); // Do not read beyond substring + masm.jccb(ConditionFlag.LessEqual, contScanSubstr); + // Back-up strings to avoid reading beyond substring: + // cnt1 = cnt1 - cnt2 + 8 + masm.addl(cnt1, cnt2); // cnt2 is negative + masm.addl(cnt1, 8); + masm.movl(cnt2, 8); + masm.negq(cnt2); + masm.bind(contScanSubstr); + if (intCnt2 < 1024 * 1024 * 1024) { + masm.movdqu(vec, new AMD64Address(charPtr2, cnt2, Scale.Times2, intCnt2 * 2)); + masm.pcmpestri(vec, new AMD64Address(result, cnt2, Scale.Times2, intCnt2 * 2), 0x0d); + } else { + // calculate index in register to avoid integer overflow (int_cnt2*2) + masm.movl(tmp, intCnt2); + masm.addq(tmp, cnt2); + masm.movdqu(vec, new AMD64Address(charPtr2, tmp, Scale.Times2, 0)); + masm.pcmpestri(vec, new AMD64Address(result, tmp, Scale.Times2, 0), 0x0d); + } + // Need to reload strings pointers if not matched whole vector + masm.jcc(ConditionFlag.NoOverflow, reloadSubstr); // OF == 0 + masm.addq(cnt2, 8); + masm.jcc(ConditionFlag.Negative, scanSubstr); + // Fall through if found full substring + + } // (int_cnt2 > 8) + + masm.bind(retFound); + // Found result if we matched full small substring. + // Compute substr offset + masm.subq(result, charPtr1); + masm.shrl(result, 1); // index + masm.bind(exit); + } + + private void stringIndexOf(AMD64MacroAssembler masm, Register charPtr1, Register charPtr2, Register cnt1, Register cnt2, Register result, Register vec, Register tmp) { + // + // int_cnt2 is length of small (< 8 chars) constant substring + // or (-1) for non constant substring in which case its length + // is in cnt2 register. + // + // Note, inline_string_indexOf() generates checks: + // if (substr.count > string.count) return -1; + // if (substr.count == 0) return 0; + // + assert intCnt2 == -1 || (0 < intCnt2 && intCnt2 < 8) : "should be != 0"; + + // This method uses pcmpestri instruction with bound registers + // inputs: + // xmm - substring + // rax - substring length (elements count) + // mem - scanned string + // rdx - string length (elements count) + // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) + // outputs: + // rcx - matched index in string + assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; + + Label reloadSubstr = new Label(); + Label scanToSubstr = new Label(); + Label scanSubstr = new Label(); + Label adjustStr = new Label(); + Label retFound = new Label(); + Label retNotFound = new Label(); + Label cleanup = new Label(); + Label foundSubstr = new Label(); + Label foundCandidate = new Label(); + + int wordSize = 8; + // We don't know where these strings are located + // and we can't read beyond them. Load them through stack. + Label bigStrings = new Label(); + Label checkStr = new Label(); + Label copySubstr = new Label(); + Label copyStr = new Label(); + + masm.movq(tmp, rsp); // save old SP + + if (intCnt2 > 0) { // small (< 8 chars) constant substring + if (intCnt2 == 1) { // One char + masm.movzwl(result, new AMD64Address(charPtr2, 0)); + masm.movdl(vec, result); // move 32 bits + } else if (intCnt2 == 2) { // Two chars + masm.movdl(vec, new AMD64Address(charPtr2, 0)); // move 32 bits + } else if (intCnt2 == 4) { // Four chars + masm.movq(vec, new AMD64Address(charPtr2, 0)); // move 64 bits + } else { // cnt2 = { 3, 5, 6, 7 } + // Array header size is 12 bytes in 32-bit VM + // + 6 bytes for 3 chars == 18 bytes, + // enough space to load vec and shift. + masm.movdqu(vec, new AMD64Address(charPtr2, (intCnt2 * 2) - 16)); + masm.psrldq(vec, 16 - (intCnt2 * 2)); + } + } else { // not constant substring + masm.cmpl(cnt2, 8); + masm.jccb(ConditionFlag.AboveEqual, bigStrings); // Both strings are big enough + + // We can read beyond string if str+16 does not cross page boundary + // since heaps are aligned and mapped by pages. + assert vmPageSize < 1024 * 1024 * 1024 : "default page should be small"; + masm.movl(result, charPtr2); // We need only low 32 bits + masm.andl(result, (vmPageSize - 1)); + masm.cmpl(result, (vmPageSize - 16)); + masm.jccb(ConditionFlag.BelowEqual, checkStr); + + // Move small strings to stack to allow load 16 bytes into vec. + masm.subq(rsp, 16); + int stackOffset = wordSize - 2; + masm.push(cnt2); + + masm.bind(copySubstr); + masm.movzwl(result, new AMD64Address(charPtr2, cnt2, Scale.Times2, -2)); + masm.movw(new AMD64Address(rsp, cnt2, Scale.Times2, stackOffset), result); + masm.decrementl(cnt2, 1); + masm.jccb(ConditionFlag.NotZero, copySubstr); + + masm.pop(cnt2); + masm.movq(charPtr2, rsp); // New substring address + } // non constant + + masm.bind(checkStr); + masm.cmpl(cnt1, 8); + masm.jccb(ConditionFlag.AboveEqual, bigStrings); + + // Check cross page boundary. + masm.movl(result, charPtr1); // We need only low 32 bits + masm.andl(result, (vmPageSize - 1)); + masm.cmpl(result, (vmPageSize - 16)); + masm.jccb(ConditionFlag.BelowEqual, bigStrings); + + masm.subq(rsp, 16); + int stackOffset = -2; + if (intCnt2 < 0) { // not constant + masm.push(cnt2); + stackOffset += wordSize; + } + masm.movl(cnt2, cnt1); + + masm.bind(copyStr); + masm.movzwl(result, new AMD64Address(charPtr1, cnt2, Scale.Times2, -2)); + masm.movw(new AMD64Address(rsp, cnt2, Scale.Times2, stackOffset), result); + masm.decrementl(cnt2, 1); + masm.jccb(ConditionFlag.NotZero, copyStr); + + if (intCnt2 < 0) { // not constant + masm.pop(cnt2); + } + masm.movq(charPtr1, rsp); // New string address + + masm.bind(bigStrings); + // Load substring. + if (intCnt2 < 0) { // -1 + masm.movdqu(vec, new AMD64Address(charPtr2, 0)); + masm.push(cnt2); // substr count + masm.push(charPtr2); // substr addr + masm.push(charPtr1); // string addr + } else { + // Small (< 8 chars) constant substrings are loaded already. + masm.movl(cnt2, intCnt2); + } + masm.push(tmp); // original SP + // Finished loading + + // ======================================================== + // Start search + // + + masm.movq(result, charPtr1); // string addr + + if (intCnt2 < 0) { // Only for non constant substring + masm.jmpb(scanToSubstr); + + // SP saved at sp+0 + // String saved at sp+1*wordSize + // Substr saved at sp+2*wordSize + // Substr count saved at sp+3*wordSize + + // Reload substr for rescan, this code + // is executed only for large substrings (> 8 chars) + masm.bind(reloadSubstr); + masm.movq(charPtr2, new AMD64Address(rsp, 2 * wordSize)); + masm.movl(cnt2, new AMD64Address(rsp, 3 * wordSize)); + masm.movdqu(vec, new AMD64Address(charPtr2, 0)); + // We came here after the beginning of the substring was + // matched but the rest of it was not so we need to search + // again. Start from the next element after the previous match. + masm.subq(charPtr1, result); // Restore counter + masm.shrl(charPtr1, 1); + masm.addl(cnt1, charPtr1); + masm.decrementl(cnt1); // Shift to next element + masm.cmpl(cnt1, cnt2); + masm.jccb(ConditionFlag.Negative, retNotFound); // Left less then substring + + masm.addq(result, 2); + } // non constant + + // Scan string for start of substr in 16-byte vectors + masm.bind(scanToSubstr); + assert cnt1.equals(rdx) && cnt2.equals(rax) && tmp.equals(rcx) : "pcmpestri"; + masm.pcmpestri(vec, new AMD64Address(result, 0), 0x0d); + masm.jccb(ConditionFlag.Below, foundCandidate); // CF == 1 + masm.subl(cnt1, 8); + masm.jccb(ConditionFlag.LessEqual, retNotFound); // Scanned full string + masm.cmpl(cnt1, cnt2); + masm.jccb(ConditionFlag.Negative, retNotFound); // Left less then substring + masm.addq(result, 16); + + masm.bind(adjustStr); + masm.cmpl(cnt1, 8); // Do not read beyond string + masm.jccb(ConditionFlag.GreaterEqual, scanToSubstr); + // Back-up string to avoid reading beyond string. + masm.leaq(result, new AMD64Address(result, cnt1, Scale.Times2, -16)); + masm.movl(cnt1, 8); + masm.jmpb(scanToSubstr); + + // Found a potential substr + masm.bind(foundCandidate); + // After pcmpestri tmp(rcx) contains matched element index + + // Make sure string is still long enough + masm.subl(cnt1, tmp); + masm.cmpl(cnt1, cnt2); + masm.jccb(ConditionFlag.GreaterEqual, foundSubstr); + // Left less then substring. + + masm.bind(retNotFound); + masm.movl(result, -1); + masm.jmpb(cleanup); + + masm.bind(foundSubstr); + // Compute start addr of substr + masm.leaq(result, new AMD64Address(result, tmp, Scale.Times2)); + + if (intCnt2 > 0) { // Constant substring + // Repeat search for small substring (< 8 chars) + // from new point without reloading substring. + // Have to check that we don't read beyond string. + masm.cmpl(tmp, 8 - intCnt2); + masm.jccb(ConditionFlag.Greater, adjustStr); + // Fall through if matched whole substring. + } else { // non constant + assert intCnt2 == -1 : "should be != 0"; + masm.addl(tmp, cnt2); + // Found result if we matched whole substring. + masm.cmpl(tmp, 8); + masm.jccb(ConditionFlag.LessEqual, retFound); + + // Repeat search for small substring (<= 8 chars) + // from new point 'str1' without reloading substring. + masm.cmpl(cnt2, 8); + // Have to check that we don't read beyond string. + masm.jccb(ConditionFlag.LessEqual, adjustStr); + + Label checkNext = new Label(); + Label contScanSubstr = new Label(); + Label retFoundLong = new Label(); + // Compare the rest of substring (> 8 chars). + masm.movq(charPtr1, result); + + masm.cmpl(tmp, cnt2); + // First 8 chars are already matched. + masm.jccb(ConditionFlag.Equal, checkNext); + + masm.bind(scanSubstr); + masm.pcmpestri(vec, new AMD64Address(charPtr1, 0), 0x0d); + // Need to reload strings pointers if not matched whole vector + masm.jcc(ConditionFlag.NoOverflow, reloadSubstr); // OF == 0 + + masm.bind(checkNext); + masm.subl(cnt2, 8); + masm.jccb(ConditionFlag.LessEqual, retFoundLong); // Found full substring + masm.addq(charPtr1, 16); + masm.addq(charPtr2, 16); + masm.subl(cnt1, 8); + masm.cmpl(cnt2, 8); // Do not read beyond substring + masm.jccb(ConditionFlag.GreaterEqual, contScanSubstr); + // Back-up strings to avoid reading beyond substring. + masm.leaq(charPtr2, new AMD64Address(charPtr2, cnt2, Scale.Times2, -16)); + masm.leaq(charPtr1, new AMD64Address(charPtr1, cnt2, Scale.Times2, -16)); + masm.subl(cnt1, cnt2); + masm.movl(cnt2, 8); + masm.addl(cnt1, 8); + masm.bind(contScanSubstr); + masm.movdqu(vec, new AMD64Address(charPtr2, 0)); + masm.jmpb(scanSubstr); + + masm.bind(retFoundLong); + masm.movq(charPtr1, new AMD64Address(rsp, wordSize)); + } // non constant + + masm.bind(retFound); + // Compute substr offset + masm.subq(result, charPtr1); + masm.shrl(result, 1); // index + + masm.bind(cleanup); + masm.pop(rsp); // restore SP + } + } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Unary.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Unary.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Unary.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,19 +24,19 @@ package org.graalvm.compiler.lir.amd64; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isRegister; +import static jdk.vm.ci.code.ValueUtil.isStackSlot; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import static jdk.vm.ci.code.ValueUtil.isRegister; -import static jdk.vm.ci.code.ValueUtil.isStackSlot; import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MROp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp; -import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize; +import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstructionClass; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorBinary.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,35 +24,39 @@ package org.graalvm.compiler.lir.amd64.vector; -import jdk.vm.ci.meta.AllocatableValue; -import org.graalvm.compiler.asm.amd64.AMD64Address; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AVXKind; -import org.graalvm.compiler.lir.LIRFrameState; -import org.graalvm.compiler.lir.LIRInstructionClass; -import org.graalvm.compiler.lir.Opcode; -import org.graalvm.compiler.lir.amd64.AMD64AddressValue; -import org.graalvm.compiler.lir.asm.CompilationResultBuilder; - import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; +import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRRIOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.asm.amd64.AVXKind; +import org.graalvm.compiler.lir.LIRFrameState; +import org.graalvm.compiler.lir.LIRInstructionClass; +import org.graalvm.compiler.lir.Opcode; +import org.graalvm.compiler.lir.amd64.AMD64AddressValue; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; +import org.graalvm.compiler.lir.asm.CompilationResultBuilder; + +import jdk.vm.ci.meta.AllocatableValue; + public class AMD64VectorBinary { - public static final class AVXBinaryOp extends AMD64VectorLIRInstruction { + public static final class AVXBinaryOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXBinaryOp.class); - @Opcode private final AMD64VectorAssembler.VexRVMOp opcode; + @Opcode private final VexRVMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; @Use({REG, STACK}) protected AllocatableValue y; - public AVXBinaryOp(AMD64VectorAssembler.VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) { + public AVXBinaryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AllocatableValue y) { super(TYPE); this.opcode = opcode; this.size = size; @@ -62,27 +66,27 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(y)) { - opcode.emit(vasm, size, asRegister(result), asRegister(x), asRegister(y)); + opcode.emit(masm, size, asRegister(result), asRegister(x), asRegister(y)); } else { - opcode.emit(vasm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asAddress(y)); + opcode.emit(masm, size, asRegister(result), asRegister(x), (AMD64Address) crb.asAddress(y)); } } } - public static final class AVXBinaryConstOp extends AMD64VectorLIRInstruction { + public static final class AVXBinaryConstOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXBinaryConstOp.class); - @Opcode private final AMD64VectorAssembler.VexRRIOp opcode; + @Opcode private final VexRRIOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; protected int y; - public AVXBinaryConstOp(AMD64VectorAssembler.VexRRIOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, int y) { + public AVXBinaryConstOp(VexRRIOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, int y) { super(TYPE); assert (y & 0xFF) == y; this.opcode = opcode; @@ -93,15 +97,15 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { - opcode.emit(vasm, size, asRegister(result), asRegister(x), y); + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + opcode.emit(masm, size, asRegister(result), asRegister(x), y); } } - public static final class AVXBinaryMemoryOp extends AMD64VectorLIRInstruction { + public static final class AVXBinaryMemoryOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXBinaryMemoryOp.class); - @Opcode private final AMD64VectorAssembler.VexRVMOp opcode; + @Opcode private final VexRVMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @@ -109,7 +113,7 @@ @Use({COMPOSITE}) protected AMD64AddressValue y; @State protected LIRFrameState state; - public AVXBinaryMemoryOp(AMD64VectorAssembler.VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) { + public AVXBinaryMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue x, AMD64AddressValue y, LIRFrameState state) { super(TYPE); this.opcode = opcode; this.size = size; @@ -120,11 +124,11 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (state != null) { - crb.recordImplicitException(vasm.position(), state); + crb.recordImplicitException(masm.position(), state); } - opcode.emit(vasm, size, asRegister(result), asRegister(x), y.toAddress()); + opcode.emit(masm, size, asRegister(result), asRegister(x), y.toAddress()); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorClearOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorClearOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorClearOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,25 +24,25 @@ package org.graalvm.compiler.lir.amd64.vector; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMOp.VPXOR; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMOp.VXORPD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMOp.VXORPS; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VPXOR; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPS; import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.XMM; -import static jdk.vm.ci.code.ValueUtil.asRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.asm.amd64.AVXKind; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.LIRInstructionClass; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AVXKind; - import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.code.Register; import jdk.vm.ci.meta.AllocatableValue; -public class AMD64VectorClearOp extends AMD64VectorLIRInstruction { +public class AMD64VectorClearOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64VectorClearOp.class); protected @LIRInstruction.Def({REG}) AllocatableValue result; @@ -57,23 +57,23 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); Register register = asRegister(result); switch (kind.getScalar()) { case SINGLE: - VXORPS.emit(vasm, AVXKind.getRegisterSize(kind), register, register, register); + VXORPS.emit(masm, AVXKind.getRegisterSize(kind), register, register, register); break; case DOUBLE: - VXORPD.emit(vasm, AVXKind.getRegisterSize(kind), register, register, register); + VXORPD.emit(masm, AVXKind.getRegisterSize(kind), register, register, register); break; default: // on AVX1, YMM VPXOR is not supported - still it is possible to clear the whole YMM // register as the upper 128-bit are implicitly cleared by the AVX1 instruction. - VPXOR.emit(vasm, XMM, register, register, register); + VPXOR.emit(masm, XMM, register, register, register); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorCompareOp.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorCompareOp.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorCompareOp.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,21 +24,23 @@ package org.graalvm.compiler.lir.amd64.vector; +import static jdk.vm.ci.code.ValueUtil.asRegister; +import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; -import static jdk.vm.ci.code.ValueUtil.asRegister; -import static jdk.vm.ci.code.ValueUtil.isRegister; -import jdk.vm.ci.meta.AllocatableValue; import org.graalvm.compiler.asm.amd64.AMD64Address; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRMOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; import org.graalvm.compiler.lir.LIRInstructionClass; import org.graalvm.compiler.lir.Opcode; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; -import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; -public final class AMD64VectorCompareOp extends AMD64VectorLIRInstruction { +import jdk.vm.ci.meta.AllocatableValue; + +public final class AMD64VectorCompareOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64VectorCompareOp.class); @Opcode private final VexRMOp opcode; @@ -53,11 +55,11 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(y)) { - opcode.emit(vasm, AVXSize.XMM, asRegister(x), asRegister(y)); + opcode.emit(masm, AVXSize.XMM, asRegister(x), asRegister(y)); } else { - opcode.emit(vasm, AVXSize.XMM, asRegister(x), (AMD64Address) crb.asAddress(y)); + opcode.emit(masm, AVXSize.XMM, asRegister(x), (AMD64Address) crb.asAddress(y)); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorLIRInstruction.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorLIRInstruction.java Fri Aug 17 11:56:59 2018 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. - * 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 org.graalvm.compiler.lir.amd64.vector; - -import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.lir.LIRInstructionClass; -import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; -import org.graalvm.compiler.lir.asm.CompilationResultBuilder; - -public abstract class AMD64VectorLIRInstruction extends AMD64LIRInstruction { - public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64VectorLIRInstruction.class); - - protected AMD64VectorLIRInstruction(LIRInstructionClass c) { - super(c); - } - - @Override - public final void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - emitCode(crb, (AMD64VectorAssembler) masm); - } - - public abstract void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm); -} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorMove.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,14 +27,14 @@ import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isRegister; import static jdk.vm.ci.code.ValueUtil.isStackSlot; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVDQU; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVQ; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVSD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVSS; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVUPD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVUPS; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMOp.VXORPD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVDQU; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVQ; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVSD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVSS; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVUPD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVUPS; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VXORPD; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; @@ -42,9 +42,8 @@ import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED; import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp; import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp; import org.graalvm.compiler.asm.amd64.AVXKind; import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize; import org.graalvm.compiler.debug.GraalError; @@ -54,6 +53,7 @@ import org.graalvm.compiler.lir.StandardOp.LoadConstantOp; import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; import org.graalvm.compiler.lir.amd64.AMD64AddressValue; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.amd64.AMD64Move; import org.graalvm.compiler.lir.amd64.AMD64RestoreRegistersOp; import org.graalvm.compiler.lir.amd64.AMD64SaveRegistersOp; @@ -71,7 +71,7 @@ public class AMD64VectorMove { @Opcode("VMOVE") - public static final class MoveToRegOp extends AMD64VectorLIRInstruction implements ValueMoveOp { + public static final class MoveToRegOp extends AMD64LIRInstruction implements ValueMoveOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveToRegOp.class); @Def({REG, HINT}) protected AllocatableValue result; @@ -84,8 +84,8 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { - move(crb, vasm, result, input); + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + move(crb, masm, result, input); } @Override @@ -100,7 +100,7 @@ } @Opcode("VMOVE") - public static final class MoveFromRegOp extends AMD64VectorLIRInstruction implements ValueMoveOp { + public static final class MoveFromRegOp extends AMD64LIRInstruction implements ValueMoveOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveFromRegOp.class); @Def({REG, STACK}) protected AllocatableValue result; @@ -113,8 +113,8 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { - move(crb, vasm, result, input); + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + move(crb, masm, result, input); } @Override @@ -129,7 +129,7 @@ } @Opcode("VMOVE") - public static class MoveFromConstOp extends AMD64VectorLIRInstruction implements LoadConstantOp { + public static class MoveFromConstOp extends AMD64LIRInstruction implements LoadConstantOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(MoveFromConstOp.class); @Def({REG, STACK}) protected AllocatableValue result; @@ -142,12 +142,12 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(result)) { - const2reg(crb, vasm, (RegisterValue) result, input); + const2reg(crb, masm, (RegisterValue) result, input); } else { assert isStackSlot(result); - AMD64Move.const2stack(crb, vasm, result, input); + AMD64Move.const2stack(crb, masm, result, input); } } @@ -163,7 +163,7 @@ } @Opcode("VSTACKMOVE") - public static final class StackMoveOp extends AMD64VectorLIRInstruction implements ValueMoveOp { + public static final class StackMoveOp extends AMD64LIRInstruction implements ValueMoveOp { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(StackMoveOp.class); @Def({STACK}) protected AllocatableValue result; @@ -191,7 +191,7 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler masm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { // backup scratch register move(crb, masm, backupSlot, scratch.asValue(backupSlot.getValueKind())); // move stack slot @@ -203,7 +203,7 @@ } } - public abstract static class VectorMemOp extends AMD64VectorLIRInstruction { + public abstract static class VectorMemOp extends AMD64LIRInstruction { protected final AVXSize size; protected final VexMoveOp op; @@ -219,14 +219,14 @@ this.state = state; } - protected abstract void emitMemAccess(AMD64VectorAssembler vasm); + protected abstract void emitMemAccess(AMD64MacroAssembler masm); @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (state != null) { - crb.recordImplicitException(vasm.position(), state); + crb.recordImplicitException(masm.position(), state); } - emitMemAccess(vasm); + emitMemAccess(masm); } } @@ -241,8 +241,8 @@ } @Override - public void emitMemAccess(AMD64VectorAssembler vasm) { - op.emit(vasm, size, asRegister(result), address.toAddress()); + public void emitMemAccess(AMD64MacroAssembler masm) { + op.emit(masm, size, asRegister(result), address.toAddress()); } } @@ -257,8 +257,8 @@ } @Override - public void emitMemAccess(AMD64VectorAssembler vasm) { - op.emit(vasm, size, address.toAddress(), asRegister(input)); + public void emitMemAccess(AMD64MacroAssembler masm) { + op.emit(masm, size, address.toAddress(), asRegister(input)); } } @@ -282,7 +282,7 @@ } AMD64Address addr = (AMD64Address) crb.asAddress(result); - op.emit((AMD64VectorAssembler) masm, AVXKind.getRegisterSize(kind), addr, register); + op.emit(masm, AVXKind.getRegisterSize(kind), addr, register); } else { super.saveRegister(crb, masm, result, register); } @@ -309,7 +309,7 @@ } AMD64Address addr = (AMD64Address) crb.asAddress(input); - op.emit((AMD64VectorAssembler) masm, AVXKind.getRegisterSize(kind), register, addr); + op.emit(masm, AVXKind.getRegisterSize(kind), register, addr); } else { super.restoreRegister(crb, masm, register, input); } @@ -349,7 +349,7 @@ } } - private static void move(CompilationResultBuilder crb, AMD64VectorAssembler vasm, AllocatableValue result, Value input) { + private static void move(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, Value input) { VexMoveOp op; AVXSize size; AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); @@ -372,23 +372,23 @@ if (isRegister(input)) { if (isRegister(result)) { if (!asRegister(input).equals(asRegister(result))) { - op.emit(vasm, size, asRegister(result), asRegister(input)); + op.emit(masm, size, asRegister(result), asRegister(input)); } } else { assert isStackSlot(result); - op.emit(vasm, size, (AMD64Address) crb.asAddress(result), asRegister(input)); + op.emit(masm, size, (AMD64Address) crb.asAddress(result), asRegister(input)); } } else { assert isStackSlot(input) && isRegister(result); - op.emit(vasm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); + op.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); } } - private static void const2reg(CompilationResultBuilder crb, AMD64VectorAssembler vasm, RegisterValue result, JavaConstant input) { + private static void const2reg(CompilationResultBuilder crb, AMD64MacroAssembler masm, RegisterValue result, JavaConstant input) { if (input.isDefaultForKind()) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); Register register = result.getRegister(); - VXORPD.emit(vasm, AVXKind.getRegisterSize(kind), register, register, register); + VXORPD.emit(masm, AVXKind.getRegisterSize(kind), register, register, register); return; } @@ -406,10 +406,10 @@ throw GraalError.shouldNotReachHere(); } VexMoveOp op = getScalarMoveOp((AMD64Kind) result.getPlatformKind()); - op.emit(vasm, AVXSize.XMM, asRegister(result), address); + op.emit(masm, AVXSize.XMM, asRegister(result), address); } - public static final class AVXMoveToIntOp extends AMD64VectorLIRInstruction { + public static final class AVXMoveToIntOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXMoveToIntOp.class); @Opcode private final VexMoveOp opcode; @@ -425,11 +425,11 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(result)) { - opcode.emitReverse(vasm, AVXSize.XMM, asRegister(result), asRegister(input)); + opcode.emitReverse(masm, AVXSize.XMM, asRegister(result), asRegister(input)); } else { - opcode.emit(vasm, AVXSize.XMM, (AMD64Address) crb.asAddress(result), asRegister(input)); + opcode.emit(masm, AVXSize.XMM, (AMD64Address) crb.asAddress(result), asRegister(input)); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorShuffle.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorShuffle.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorShuffle.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,31 +27,32 @@ import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isRegister; import static jdk.vm.ci.code.ValueUtil.isStackSlot; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VEXTRACTF128; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VEXTRACTI128; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VPEXTRB; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VPEXTRD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VPEXTRQ; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp.VPEXTRW; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMoveOp.VMOVQ; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMIOp.VINSERTF128; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMIOp.VINSERTI128; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMIOp.VSHUFPD; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMIOp.VSHUFPS; -import static org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMOp.VPSHUFB; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VEXTRACTF128; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VEXTRACTI128; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VPEXTRB; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VPEXTRD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VPEXTRQ; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp.VPEXTRW; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp.VMOVQ; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMIOp.VINSERTF128; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMIOp.VINSERTI128; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMIOp.VSHUFPD; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMIOp.VSHUFPS; +import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VPSHUFB; import static org.graalvm.compiler.asm.amd64.AVXKind.AVXSize.XMM; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK; import org.graalvm.compiler.asm.amd64.AMD64Address; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexMRIOp; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRMIOp; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler.VexRVMIOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMRIOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMIOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMIOp; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; import org.graalvm.compiler.asm.amd64.AVXKind; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.lir.LIRInstructionClass; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; import jdk.vm.ci.amd64.AMD64; @@ -61,7 +62,7 @@ public class AMD64VectorShuffle { - public static final class IntToVectorOp extends AMD64VectorLIRInstruction { + public static final class IntToVectorOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(IntToVectorOp.class); @Def({REG}) protected AllocatableValue result; @@ -75,17 +76,17 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(value)) { - VMOVD.emit(vasm, XMM, asRegister(result), asRegister(value)); + VMOVD.emit(masm, XMM, asRegister(result), asRegister(value)); } else { assert isStackSlot(value); - VMOVD.emit(vasm, XMM, asRegister(result), (AMD64Address) crb.asAddress(value)); + VMOVD.emit(masm, XMM, asRegister(result), (AMD64Address) crb.asAddress(value)); } } } - public static final class LongToVectorOp extends AMD64VectorLIRInstruction { + public static final class LongToVectorOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(LongToVectorOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue value; @@ -98,17 +99,17 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(value)) { - VMOVQ.emit(vasm, XMM, asRegister(result), asRegister(value)); + VMOVQ.emit(masm, XMM, asRegister(result), asRegister(value)); } else { assert isStackSlot(value); - VMOVQ.emit(vasm, XMM, asRegister(result), (AMD64Address) crb.asAddress(value)); + VMOVQ.emit(masm, XMM, asRegister(result), (AMD64Address) crb.asAddress(value)); } } } - public static final class ShuffleBytesOp extends AMD64VectorLIRInstruction { + public static final class ShuffleBytesOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ShuffleBytesOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue source; @@ -122,18 +123,18 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); if (isRegister(selector)) { - VPSHUFB.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), asRegister(selector)); + VPSHUFB.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), asRegister(selector)); } else { assert isStackSlot(selector); - VPSHUFB.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), (AMD64Address) crb.asAddress(selector)); + VPSHUFB.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), (AMD64Address) crb.asAddress(selector)); } } } - public static final class ConstShuffleBytesOp extends AMD64VectorLIRInstruction { + public static final class ConstShuffleBytesOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ConstShuffleBytesOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue source; @@ -148,14 +149,14 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(selector, selector.length); - VPSHUFB.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), address); + VPSHUFB.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), address); } } - public static class ShuffleWordOp extends AMD64VectorLIRInstruction { + public static class ShuffleWordOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ShuffleWordOp.class); private final VexRMIOp op; @Def({REG}) protected AllocatableValue result; @@ -171,17 +172,17 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) source.getPlatformKind(); if (isRegister(source)) { - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), selector); } else { - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), (AMD64Address) crb.asAddress(source), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), (AMD64Address) crb.asAddress(source), selector); } } } - public static class ShuffleFloatOp extends AMD64VectorLIRInstruction { + public static class ShuffleFloatOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ShuffleFloatOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue source1; @@ -197,7 +198,7 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); VexRVMIOp op; @@ -213,15 +214,15 @@ } if (isRegister(source2)) { - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), asRegister(source2), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), asRegister(source2), selector); } else { assert isStackSlot(source2); - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), (AMD64Address) crb.asAddress(source2), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), (AMD64Address) crb.asAddress(source2), selector); } } } - public static final class Extract128Op extends AMD64VectorLIRInstruction { + public static final class Extract128Op extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(Extract128Op.class); @Def({REG, STACK}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue source; @@ -235,7 +236,7 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) source.getPlatformKind(); VexMRIOp op; @@ -253,15 +254,15 @@ } if (isRegister(result)) { - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source), selector); } else { assert isStackSlot(result); - op.emit(vasm, AVXKind.getRegisterSize(kind), (AMD64Address) crb.asAddress(result), asRegister(source), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), (AMD64Address) crb.asAddress(result), asRegister(source), selector); } } } - public static final class Insert128Op extends AMD64VectorLIRInstruction { + public static final class Insert128Op extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(Insert128Op.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue source1; @@ -277,7 +278,7 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { AMD64Kind kind = (AMD64Kind) result.getPlatformKind(); VexRVMIOp op; @@ -296,15 +297,15 @@ } if (isRegister(source2)) { - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), asRegister(source2), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), asRegister(source2), selector); } else { assert isStackSlot(source2); - op.emit(vasm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), (AMD64Address) crb.asAddress(source2), selector); + op.emit(masm, AVXKind.getRegisterSize(kind), asRegister(result), asRegister(source1), (AMD64Address) crb.asAddress(source2), selector); } } } - public static final class ExtractByteOp extends AMD64VectorLIRInstruction { + public static final class ExtractByteOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ExtractByteOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue vector; @@ -320,12 +321,12 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { - VPEXTRB.emit(vasm, XMM, asRegister(result), asRegister(vector), selector); + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + VPEXTRB.emit(masm, XMM, asRegister(result), asRegister(vector), selector); } } - public static final class ExtractShortOp extends AMD64VectorLIRInstruction { + public static final class ExtractShortOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ExtractShortOp.class); @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue vector; @@ -341,12 +342,12 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { - VPEXTRW.emit(vasm, XMM, asRegister(result), asRegister(vector), selector); + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + VPEXTRW.emit(masm, XMM, asRegister(result), asRegister(vector), selector); } } - public static final class ExtractIntOp extends AMD64VectorLIRInstruction { + public static final class ExtractIntOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ExtractIntOp.class); @Def({REG, STACK}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue vector; @@ -362,25 +363,25 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(result)) { if (selector == 0) { - VMOVD.emitReverse(vasm, XMM, asRegister(result), asRegister(vector)); + VMOVD.emitReverse(masm, XMM, asRegister(result), asRegister(vector)); } else { - VPEXTRD.emit(vasm, XMM, asRegister(result), asRegister(vector), selector); + VPEXTRD.emit(masm, XMM, asRegister(result), asRegister(vector), selector); } } else { assert isStackSlot(result); if (selector == 0) { - VMOVD.emit(vasm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector)); + VMOVD.emit(masm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector)); } else { - VPEXTRD.emit(vasm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector), selector); + VPEXTRD.emit(masm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector), selector); } } } } - public static final class ExtractLongOp extends AMD64VectorLIRInstruction { + public static final class ExtractLongOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(ExtractLongOp.class); @Def({REG, STACK}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue vector; @@ -396,19 +397,19 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(result)) { if (selector == 0) { - VMOVQ.emitReverse(vasm, XMM, asRegister(result), asRegister(vector)); + VMOVQ.emitReverse(masm, XMM, asRegister(result), asRegister(vector)); } else { - VPEXTRQ.emit(vasm, XMM, asRegister(result), asRegister(vector), selector); + VPEXTRQ.emit(masm, XMM, asRegister(result), asRegister(vector), selector); } } else { assert isStackSlot(result); if (selector == 0) { - VMOVQ.emit(vasm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector)); + VMOVQ.emit(masm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector)); } else { - VPEXTRQ.emit(vasm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector), selector); + VPEXTRQ.emit(masm, XMM, (AMD64Address) crb.asAddress(result), asRegister(vector), selector); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/vector/AMD64VectorUnary.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,17 +24,6 @@ package org.graalvm.compiler.lir.amd64.vector; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.Value; -import org.graalvm.compiler.asm.amd64.AMD64Address; -import org.graalvm.compiler.asm.amd64.AMD64VectorAssembler; -import org.graalvm.compiler.asm.amd64.AVXKind; -import org.graalvm.compiler.lir.LIRFrameState; -import org.graalvm.compiler.lir.LIRInstructionClass; -import org.graalvm.compiler.lir.Opcode; -import org.graalvm.compiler.lir.amd64.AMD64AddressValue; -import org.graalvm.compiler.lir.asm.CompilationResultBuilder; - import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isRegister; import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE; @@ -44,18 +33,33 @@ import static org.graalvm.compiler.lir.LIRValueUtil.asConstant; import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue; +import org.graalvm.compiler.asm.amd64.AMD64Address; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp; +import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp; +import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler; +import org.graalvm.compiler.asm.amd64.AVXKind; +import org.graalvm.compiler.lir.LIRFrameState; +import org.graalvm.compiler.lir.LIRInstructionClass; +import org.graalvm.compiler.lir.Opcode; +import org.graalvm.compiler.lir.amd64.AMD64AddressValue; +import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; +import org.graalvm.compiler.lir.asm.CompilationResultBuilder; + +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.Value; + public class AMD64VectorUnary { - public static final class AVXUnaryOp extends AMD64VectorLIRInstruction { + public static final class AVXUnaryOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXUnaryOp.class); - @Opcode private final AMD64VectorAssembler.VexRMOp opcode; + @Opcode private final VexRMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue input; - public AVXUnaryOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) { + public AVXUnaryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AllocatableValue input) { super(TYPE); this.opcode = opcode; this.size = size; @@ -64,26 +68,26 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(input)) { - opcode.emit(vasm, size, asRegister(result), asRegister(input)); + opcode.emit(masm, size, asRegister(result), asRegister(input)); } else { - opcode.emit(vasm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); + opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); } } } - public static final class AVXUnaryMemoryOp extends AMD64VectorLIRInstruction { + public static final class AVXUnaryMemoryOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXUnaryMemoryOp.class); - @Opcode private final AMD64VectorAssembler.VexRMOp opcode; + @Opcode private final VexRMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE}) protected AMD64AddressValue input; @State protected LIRFrameState state; - public AVXUnaryMemoryOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { + public AVXUnaryMemoryOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { super(TYPE); this.opcode = opcode; this.size = size; @@ -93,24 +97,24 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (state != null) { - crb.recordImplicitException(vasm.position(), state); + crb.recordImplicitException(masm.position(), state); } - opcode.emit(vasm, size, asRegister(result), input.toAddress()); + opcode.emit(masm, size, asRegister(result), input.toAddress()); } } - public static final class AVXBroadcastOp extends AMD64VectorLIRInstruction { + public static final class AVXBroadcastOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXBroadcastOp.class); - @Opcode private final AMD64VectorAssembler.VexRMOp opcode; + @Opcode private final VexRMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; - public AVXBroadcastOp(AMD64VectorAssembler.VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) { + public AVXBroadcastOp(VexRMOp opcode, AVXKind.AVXSize size, AllocatableValue result, Value input) { super(TYPE); this.opcode = opcode; this.size = size; @@ -119,30 +123,30 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(input)) { - opcode.emit(vasm, size, asRegister(result), asRegister(input)); + opcode.emit(masm, size, asRegister(result), asRegister(input)); } else if (isConstantValue(input)) { int align = input.getPlatformKind().getSizeInBytes(); AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(asConstant(input), align); - opcode.emit(vasm, size, asRegister(result), address); + opcode.emit(masm, size, asRegister(result), address); } else { - opcode.emit(vasm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); + opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input)); } } } - public static final class AVXConvertMemoryOp extends AMD64VectorLIRInstruction { + public static final class AVXConvertMemoryOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXConvertMemoryOp.class); - @Opcode private final AMD64VectorAssembler.VexRVMOp opcode; + @Opcode private final VexRVMOp opcode; private final AVXKind.AVXSize size; @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE}) protected AMD64AddressValue input; @State protected LIRFrameState state; - public AVXConvertMemoryOp(AMD64VectorAssembler.VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { + public AVXConvertMemoryOp(VexRVMOp opcode, AVXKind.AVXSize size, AllocatableValue result, AMD64AddressValue input, LIRFrameState state) { super(TYPE); this.opcode = opcode; this.size = size; @@ -152,22 +156,22 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (state != null) { - crb.recordImplicitException(vasm.position(), state); + crb.recordImplicitException(masm.position(), state); } - opcode.emit(vasm, size, asRegister(result), asRegister(result), input.toAddress()); + opcode.emit(masm, size, asRegister(result), asRegister(result), input.toAddress()); } } - public static final class AVXConvertOp extends AMD64VectorLIRInstruction { + public static final class AVXConvertOp extends AMD64LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AVXConvertOp.class); - @Opcode private final AMD64VectorAssembler.VexRVMOp opcode; + @Opcode private final VexRVMOp opcode; @Def({REG}) protected AllocatableValue result; @Use({REG, STACK}) protected AllocatableValue input; - public AVXConvertOp(AMD64VectorAssembler.VexRVMOp opcode, AllocatableValue result, AllocatableValue input) { + public AVXConvertOp(VexRVMOp opcode, AllocatableValue result, AllocatableValue input) { super(TYPE); this.opcode = opcode; this.result = result; @@ -175,16 +179,16 @@ } @Override - public void emitCode(CompilationResultBuilder crb, AMD64VectorAssembler vasm) { + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (isRegister(input)) { if (!asRegister(input).equals(asRegister(result))) { // clear result register to avoid unnecessary dependency - AMD64VectorAssembler.VexRVMOp.VXORPD.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); + VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); } - opcode.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(input)); + opcode.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(input)); } else { - AMD64VectorAssembler.VexRVMOp.VXORPD.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); - opcode.emit(vasm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), (AMD64Address) crb.asAddress(input)); + VexRVMOp.VXORPD.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), asRegister(result)); + opcode.emit(masm, AVXKind.AVXSize.XMM, asRegister(result), asRegister(result), (AMD64Address) crb.asAddress(input)); } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/SwitchStrategy.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/SwitchStrategy.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/SwitchStrategy.java Fri Aug 17 13:20:53 2018 -0700 @@ -441,7 +441,7 @@ } double probabilityStart = probabilitySums[left]; double probabilityMiddle = (probabilityStart + probabilitySums[right + 1]) / 2; - assert probabilityStart >= probabilityStart; + assert probabilityMiddle >= probabilityStart; int middle = left; while (getSliceEnd(closure, middle + 1) < right && probabilitySums[getSliceEnd(closure, middle + 1)] < probabilityMiddle) { middle = getSliceEnd(closure, middle + 1); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/GlobalLivenessAnalysisPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/GlobalLivenessAnalysisPhase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/GlobalLivenessAnalysisPhase.java Fri Aug 17 13:20:53 2018 -0700 @@ -65,7 +65,7 @@ context.contextAdd(livenessInfo); } - private final class Analyser { + private static final class Analyser { private static final int LOG_LEVEL = DebugContext.INFO_LEVEL; @@ -129,7 +129,7 @@ return lir.numVariables(); } - private int operandNumber(Value operand) { + private static int operandNumber(Value operand) { if (isVariable(operand)) { return asVariable(operand).index; } @@ -318,7 +318,7 @@ } } - private int[] bitSetToIntArray(BitSet live) { + private static int[] bitSetToIntArray(BitSet live) { int[] vars = new int[live.cardinality()]; int cnt = 0; for (int i = live.nextSetBit(0); i >= 0; i = live.nextSetBit(i + 1), cnt++) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,7 +24,6 @@ package org.graalvm.compiler.lir.gen; -import jdk.vm.ci.code.RegisterConfig; import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.calc.Condition; @@ -44,6 +43,7 @@ import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.RegisterAttributes; +import jdk.vm.ci.code.RegisterConfig; import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.code.ValueKindFactory; import jdk.vm.ci.meta.AllocatableValue; @@ -268,6 +268,11 @@ throw GraalError.unimplemented("String.indexOf substitution is not implemented on this architecture"); } + @SuppressWarnings("unused") + default Variable emitArrayIndexOf(JavaKind kind, Value sourcePointer, Value sourceCount, Value charValue) { + throw GraalError.unimplemented("String.indexOf substitution is not implemented on this architecture"); + } + void emitBlackhole(Value operand); LIRKind getLIRKind(Stamp stamp); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MethodProfilingPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MethodProfilingPhase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MethodProfilingPhase.java Fri Aug 17 13:20:53 2018 -0700 @@ -51,7 +51,7 @@ new Analyzer(target, lirGenRes.getCompilationUnitName(), lirGenRes.getLIR(), context.diagnosticLirGenTool).run(); } - private class Analyzer { + private static class Analyzer { private final LIR lir; private final DiagnosticLIRGeneratorTool diagnosticLirGenTool; private final LIRInsertionBuffer buffer; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MoveProfilingPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MoveProfilingPhase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/profiling/MoveProfilingPhase.java Fri Aug 17 13:20:53 2018 -0700 @@ -142,7 +142,7 @@ protected String createGroupName() { if (Options.LIRDynMoveProfileMethod.getValue(lirGenRes.getLIR().getOptions())) { - return new StringBuilder('"').append(MOVE_OPERATIONS).append(':').append(lirGenRes.getCompilationUnitName()).append('"').toString(); + return new StringBuilder("\"").append(MOVE_OPERATIONS).append(':').append(lirGenRes.getCompilationUnitName()).append('"').toString(); } return MOVE_OPERATIONS; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeCycles.java Fri Aug 17 13:20:53 2018 -0700 @@ -64,6 +64,8 @@ CYCLES_512(512), CYCLES_1024(1024); + private static final NodeCycles[] VALUES = values(); + public final int value; NodeCycles(int value) { @@ -83,10 +85,9 @@ } assert base.ordinal() > CYCLES_0.ordinal(); int log2 = log2(base.value * opCount); - NodeCycles[] values = values(); - for (int i = base.ordinal(); i < values.length; i++) { - if (log2(values[i].value) == log2) { - return values[i]; + for (int i = base.ordinal(); i < VALUES.length; i++) { + if (log2(VALUES[i].value) == log2) { + return VALUES[i]; } } return CYCLES_1024; @@ -97,13 +98,12 @@ if (rawValue == 0) { return CYCLES_0; } - NodeCycles[] values = values(); - for (int i = CYCLES_0.ordinal(); i < values.length - 1; i++) { - if (values[i].value >= rawValue && rawValue <= values[i + 1].value) { - int r1 = values[i].value; - int r2 = values[i + 1].value; + for (int i = CYCLES_0.ordinal(); i < VALUES.length - 1; i++) { + if (VALUES[i].value >= rawValue && rawValue <= VALUES[i + 1].value) { + int r1 = VALUES[i].value; + int r2 = VALUES[i + 1].value; int diff = r2 - r1; - return rawValue - r1 > diff / 2 ? values[i + 1] : values[i]; + return rawValue - r1 > diff / 2 ? VALUES[i + 1] : VALUES[i]; } } return CYCLES_1024; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodeinfo/src/org/graalvm/compiler/nodeinfo/NodeSize.java Fri Aug 17 13:20:53 2018 -0700 @@ -65,6 +65,8 @@ SIZE_512(512), SIZE_1024(1024); + private static final NodeSize[] VALUES = values(); + public final int value; NodeSize(int value) { @@ -80,10 +82,9 @@ } assert base.ordinal() > SIZE_0.ordinal(); int log2 = log2(base.value * opCount); - NodeSize[] values = values(); - for (int i = base.ordinal(); i < values.length; i++) { - if (log2(values[i].value) == log2) { - return values[i]; + for (int i = base.ordinal(); i < VALUES.length; i++) { + if (log2(VALUES[i].value) == log2) { + return VALUES[i]; } } return SIZE_1024; @@ -95,13 +96,12 @@ return SIZE_0; } assert rawValue > 0; - NodeSize[] values = values(); - for (int i = SIZE_0.ordinal(); i < values.length - 1; i++) { - if (values[i].value >= rawValue && rawValue <= values[i + 1].value) { - int r1 = values[i].value; - int r2 = values[i + 1].value; + for (int i = SIZE_0.ordinal(); i < VALUES.length - 1; i++) { + if (VALUES[i].value >= rawValue && rawValue <= VALUES[i + 1].value) { + int r1 = VALUES[i].value; + int r2 = VALUES[i + 1].value; int diff = r2 - r1; - return rawValue - r1 > diff / 2 ? values[i + 1] : values[i]; + return rawValue - r1 > diff / 2 ? VALUES[i + 1] : VALUES[i]; } } return SIZE_1024; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -112,7 +112,7 @@ }; } - private class BlockNodeIterator implements Iterator { + private static class BlockNodeIterator implements Iterator { private FixedNode current; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ConstantNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -43,11 +43,13 @@ import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.calc.FloatingNode; +import org.graalvm.compiler.nodes.spi.ArrayLengthProvider; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -57,7 +59,7 @@ * The {@code ConstantNode} represents a {@link Constant constant}. */ @NodeInfo(nameTemplate = "C({p#rawvalue}) {p#stampKind}", cycles = CYCLES_0, size = SIZE_1) -public final class ConstantNode extends FloatingNode implements LIRLowerable { +public final class ConstantNode extends FloatingNode implements LIRLowerable, ArrayLengthProvider { public static final NodeClass TYPE = NodeClass.create(ConstantNode.class); @@ -532,4 +534,16 @@ return super.toString(verbosity); } } + + @Override + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { + if (constantReflection == null || !(value instanceof JavaConstant) || ((JavaConstant) value).isNull()) { + return null; + } + Integer length = constantReflection.readArrayLength((JavaConstant) value); + if (length == null) { + return null; + } + return ConstantNode.forInt(length); + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FixedNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -38,7 +38,7 @@ @Override public boolean verify() { - assertTrue(this.successors().isNotEmpty() || this.predecessor() != null, "FixedNode should not float"); + assertTrue(this.successors().isNotEmpty() || this.predecessor() != null, "FixedNode should not float: %s", this); return super.verify(); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/FrameState.java Fri Aug 17 13:20:53 2018 -0700 @@ -237,7 +237,8 @@ } public void setOuterFrameState(FrameState x) { - assert x == null || (!x.isDeleted() && x.bci >= 0); + assert x == null || (!x.isDeleted() && x.bci >= 0) : "cannot set outer frame state of:\n" + toString(this) + + "\nto:\n" + toString(x) + "\nisDeleted=" + x.isDeleted(); updateUsages(this.outerFrameState, x); this.outerFrameState = x; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -826,7 +826,21 @@ if (this.graph().hasValueProxies()) { if (trueSuccessor instanceof LoopExitNode && falseSuccessor instanceof LoopExitNode) { assert ((LoopExitNode) trueSuccessor).loopBegin() == ((LoopExitNode) falseSuccessor).loopBegin(); - assert trueSuccessor.usages().isEmpty() && falseSuccessor.usages().isEmpty(); + /* + * we can collapse all proxy nodes on one loop exit, the surviving one, which will + * be the true successor + */ + if (falseSuccessor.anchored().isEmpty() && falseSuccessor.usages().isNotEmpty()) { + for (Node n : falseSuccessor.usages().snapshot()) { + assert n instanceof ProxyNode; + ((ProxyNode) n).setProxyPoint((LoopExitNode) trueSuccessor); + } + } + /* + * The true successor (surviving loop exit) can have usages, namely proxy nodes, the + * false successor however, must not have usages any more after the code above + */ + assert trueSuccessor.anchored().isEmpty() && falseSuccessor.usages().isEmpty(); return this.graph().addOrUnique(new ValueProxyNode(replacement, (LoopExitNode) trueSuccessor)); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java Fri Aug 17 13:20:53 2018 -0700 @@ -386,7 +386,7 @@ } } - public final class PlaceholderInvokable implements Invokable { + public static final class PlaceholderInvokable implements Invokable { private int bci; private ResolvedJavaMethod method; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiArrayNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiArrayNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiArrayNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,6 +27,7 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeClass; @@ -48,7 +49,7 @@ @Input ValueNode length; @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { return length; } @@ -59,7 +60,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (GraphUtil.arrayLength(object(), ArrayLengthProvider.FindLengthMode.SEARCH_ONLY) != length) { + if (GraphUtil.arrayLength(object(), ArrayLengthProvider.FindLengthMode.SEARCH_ONLY, tool.getConstantReflection()) != length) { return this; } return super.canonical(tool); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/ProxyNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -53,6 +53,11 @@ public abstract ValueNode value(); + public void setProxyPoint(LoopExitNode newProxyPoint) { + this.updateUsages(loopExit, newProxyPoint); + this.loopExit = newProxyPoint; + } + public LoopExitNode proxyPoint() { return loopExit; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java Fri Aug 17 13:20:53 2018 -0700 @@ -46,7 +46,6 @@ import org.graalvm.compiler.core.common.cfg.BlockMap; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.debug.DebugContext; -import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.JavaMethodContext; import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.graph.Graph; @@ -111,6 +110,10 @@ return this == FLOATING_GUARDS; } + public boolean allowsGuardInsertion() { + return this.ordinal() <= FIXED_DEOPTS.ordinal(); + } + public boolean areFrameStatesAtDeopts() { return this == AFTER_FSA; } @@ -930,10 +933,9 @@ * Records that {@code method} was used to build this graph. */ public void recordMethod(ResolvedJavaMethod method) { - if (methods == null) { - throw new GraalError("inlined method recording not enabled for %s", this); + if (methods != null) { + methods.add(method); } - methods.add(method); } /** @@ -941,14 +943,13 @@ * to build another graph. */ public void updateMethods(StructuredGraph other) { - if (methods == null) { - throw new GraalError("inlined method recording not enabled for %s", this); - } - if (other.rootMethod != null) { - methods.add(other.rootMethod); - } - for (ResolvedJavaMethod m : other.methods) { - methods.add(m); + if (methods != null) { + if (other.rootMethod != null) { + methods.add(other.rootMethod); + } + for (ResolvedJavaMethod m : other.methods) { + methods.add(m); + } } } @@ -1006,14 +1007,6 @@ return res; } - /** - * - * @return true if the graph contains only a {@link StartNode} and {@link ReturnNode} - */ - public boolean isTrivial() { - return !(start.next() instanceof ReturnNode); - } - @Override public JavaMethod asJavaMethod() { return method(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/DynamicCounterNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -60,18 +60,18 @@ public static final NodeClass TYPE = NodeClass.create(DynamicCounterNode.class); @Input ValueNode increment; + protected final String group; protected final String name; - protected final String group; protected final boolean withContext; - public DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) { - this(TYPE, name, group, increment, withContext); + public DynamicCounterNode(String group, String name, ValueNode increment, boolean withContext) { + this(TYPE, group, name, increment, withContext); } - protected DynamicCounterNode(NodeClass c, String name, String group, ValueNode increment, boolean withContext) { + protected DynamicCounterNode(NodeClass c, String group, String name, ValueNode increment, boolean withContext) { super(c, StampFactory.forVoid()); + this.group = group; this.name = name; - this.group = group; this.increment = increment; this.withContext = withContext; } @@ -94,11 +94,11 @@ public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) { StructuredGraph graph = position.graph(); - graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(name, group, ConstantNode.forLong(increment, position.graph()), withContext))); + graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(group, name, ConstantNode.forLong(increment, position.graph()), withContext))); } @NodeIntrinsic - public static native void counter(@ConstantNodeParameter String name, @ConstantNodeParameter String group, long increment, @ConstantNodeParameter boolean addContext); + public static native void counter(@ConstantNodeParameter String group, @ConstantNodeParameter String name, long increment, @ConstantNodeParameter boolean addContext); @Override public void generate(NodeLIRBuilderTool generator) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/WeakCounterNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/WeakCounterNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/debug/WeakCounterNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -71,7 +71,7 @@ public static void addCounterBefore(String group, String name, long increment, boolean addContext, ValueNode checkedValue, FixedNode position) { StructuredGraph graph = position.graph(); - WeakCounterNode counter = graph.add(new WeakCounterNode(name, group, ConstantNode.forLong(increment, graph), addContext, checkedValue)); + WeakCounterNode counter = graph.add(new WeakCounterNode(group, name, ConstantNode.forLong(increment, graph), addContext, checkedValue)); graph.addBeforeFixed(position, counter); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/BytecodeExceptionNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,9 @@ OUT_OF_BOUNDS(2, ArrayIndexOutOfBoundsException.class), CLASS_CAST(2, ClassCastException.class), ARRAY_STORE(1, ArrayStoreException.class), - DIVISION_BY_ZERO(0, ArithmeticException.class); + DIVISION_BY_ZERO(0, ArithmeticException.class), + INTEGER_EXACT_OVERFLOW(0, ArithmeticException.class), + LONG_EXACT_OVERFLOW(0, ArithmeticException.class); final int numArguments; final Class exceptionClass; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/FixedValueAnchorNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -66,7 +66,7 @@ @Override public boolean inferStamp() { if (predefinedStamp == null) { - return updateStamp(object.stamp(NodeView.DEFAULT)); + return updateStamp(stamp.join(object.stamp(NodeView.DEFAULT))); } else { return false; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.StampPair; +import org.graalvm.compiler.debug.GraalError; +import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractMergeNode; import org.graalvm.compiler.nodes.CallTargetNode; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; @@ -49,6 +51,7 @@ import org.graalvm.compiler.nodes.calc.NarrowNode; import org.graalvm.compiler.nodes.calc.SignExtendNode; import org.graalvm.compiler.nodes.calc.ZeroExtendNode; +import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind; import org.graalvm.compiler.nodes.type.StampTool; import jdk.vm.ci.code.BailoutException; @@ -77,6 +80,16 @@ void push(JavaKind kind, ValueNode value); /** + * Pops a value from the frame state stack using an explicit kind. + * + * @param slotKind the kind to use when type checking this operation + * @return the value on the top of the stack + */ + default ValueNode pop(JavaKind slotKind) { + throw GraalError.unimplemented(); + } + + /** * Adds a node to the graph. If the node is in the graph, returns immediately. If the node is a * {@link StateSplit} with a null {@linkplain StateSplit#stateAfter() frame state}, the frame * state is initialized. @@ -319,6 +332,24 @@ return append(SignExtendNode.create(narrow, 32, NodeView.DEFAULT)); } } + + /** + * @return true if an explicit exception check should be emitted. + */ + default boolean needsExplicitException() { + return false; + } + + /** + * Generates an exception edge for the current bytecode. When {@link #needsExplicitException()} + * returns true, this method should return non-null begin nodes. + * + * @param exceptionKind the type of exception to be created. + * @return a begin node that precedes the actual exception instantiation code. + */ + default AbstractBeginNode genExplicitExceptionEdge(@SuppressWarnings("ununsed") BytecodeExceptionKind exceptionKind) { + return null; + } } class GraphBuilderContextUtil { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/InvocationPlugins.java Fri Aug 17 13:20:53 2018 -0700 @@ -442,6 +442,7 @@ * {@code declaringClass} */ public void register(InvocationPlugin plugin, String name, Type... argumentTypes) { + assert plugins != null : String.format("Late registrations of invocation plugins for %s is already closed", declaringType); boolean isStatic = argumentTypes.length == 0 || argumentTypes[0] != InvocationPlugin.Receiver.class; if (!isStatic) { argumentTypes[0] = declaringType; @@ -567,7 +568,7 @@ /** * Maps method names to binding lists. */ - private final EconomicMap bindings = EconomicMap.create(Equivalence.DEFAULT); + final EconomicMap bindings = EconomicMap.create(Equivalence.DEFAULT); /** * Gets the invocation plugin for a given method. @@ -883,11 +884,33 @@ flushDeferrables(); } + /** + * Determines if this object currently contains any plugins (in any state of registration). If + * this object has any {@link #defer(Runnable) deferred registrations}, it is assumed that + * executing them will result in at least one plugin being registered. + */ public boolean isEmpty() { - if (resolvedRegistrations != null) { - return resolvedRegistrations.isEmpty(); + if (parent != null && !parent.isEmpty()) { + return false; + } + UnmodifiableEconomicMap resolvedRegs = resolvedRegistrations; + if (resolvedRegs != null) { + if (!resolvedRegs.isEmpty()) { + return false; + } } - return registrations.size() == 0 && lateRegistrations == null; + List deferred = deferredRegistrations; + if (deferred != null) { + if (!deferred.isEmpty()) { + return false; + } + } + for (LateClassPlugins late = lateRegistrations; late != null; late = late.next) { + if (!late.bindings.isEmpty()) { + return false; + } + } + return registrations.size() == 0; } /** diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewArrayNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewArrayNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/AbstractNewArrayNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,6 +24,7 @@ package org.graalvm.compiler.nodes.java; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -45,7 +46,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { return length; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -44,7 +44,6 @@ import org.graalvm.compiler.nodes.virtual.VirtualArrayNode; import jdk.vm.ci.meta.ConstantReflectionProvider; -import jdk.vm.ci.meta.JavaConstant; /** * The {@code ArrayLength} instruction gets the length of an array. @@ -75,7 +74,7 @@ return newArray.length(); } - ValueNode length = readArrayLengthConstant(forValue, constantReflection); + ValueNode length = readArrayLength(forValue, constantReflection); if (length != null) { return length; } @@ -97,25 +96,7 @@ * @return a node representing the length of {@code array} or null if it is not available */ public static ValueNode readArrayLength(ValueNode originalArray, ConstantReflectionProvider constantReflection) { - ValueNode length = GraphUtil.arrayLength(originalArray, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ); - if (length != null) { - return length; - } - return readArrayLengthConstant(originalArray, constantReflection); - } - - private static ValueNode readArrayLengthConstant(ValueNode originalArray, ConstantReflectionProvider constantReflection) { - ValueNode array = GraphUtil.unproxify(originalArray); - if (constantReflection != null && array.isConstant() && !array.isNullConstant()) { - JavaConstant constantValue = array.asJavaConstant(); - if (constantValue != null && constantValue.isNonNull()) { - Integer constantLength = constantReflection.readArrayLength(constantValue); - if (constantLength != null) { - return ConstantNode.forInt(constantLength); - } - } - } - return null; + return GraphUtil.arrayLength(originalArray, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ, constantReflection); } @Override diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadFieldNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -38,10 +38,12 @@ import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizeNode; +import org.graalvm.compiler.nodes.FixedGuardNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.PhiNode; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValuePhiNode; +import org.graalvm.compiler.nodes.calc.IsNullNode; import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider; import org.graalvm.compiler.nodes.spi.Virtualizable; import org.graalvm.compiler.nodes.spi.VirtualizerTool; @@ -110,8 +112,13 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) { NodeView view = NodeView.from(tool); - if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp(view)))) { - return null; + if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile()) { + if (isStatic() || StampTool.isPointerNonNull(forObject.stamp(view))) { + return null; + } + if (graph().getGuardsStage().allowsGuardInsertion()) { + return new FixedGuardNode(new IsNullNode(forObject), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true, getNodeSourcePosition()); + } } return canonical(this, StampPair.create(stamp, uncheckedStamp), forObject, field, tool.getConstantFieldProvider(), tool.getConstantReflection(), tool.getOptions(), tool.getMetaAccess(), tool.canonicalizeReads(), tool.allUsagesAvailable()); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,6 +27,7 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; +import org.graalvm.compiler.core.common.calc.CanonicalCondition; import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; @@ -35,10 +36,16 @@ import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.Canonicalizable; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.graph.spi.Simplifiable; +import org.graalvm.compiler.graph.spi.SimplifierTool; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.ConstantNode; +import org.graalvm.compiler.nodes.FixedGuardNode; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.calc.CompareNode; import org.graalvm.compiler.nodes.extended.GuardingNode; import org.graalvm.compiler.nodes.spi.Virtualizable; import org.graalvm.compiler.nodes.spi.VirtualizerTool; @@ -48,6 +55,8 @@ import jdk.vm.ci.meta.Assumptions; import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.DeoptimizationAction; +import jdk.vm.ci.meta.DeoptimizationReason; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; @@ -57,7 +66,7 @@ * The {@code LoadIndexedNode} represents a read from an element of an array. */ @NodeInfo(cycles = CYCLES_8, size = SIZE_8) -public class LoadIndexedNode extends AccessIndexedNode implements Virtualizable, Canonicalizable { +public class LoadIndexedNode extends AccessIndexedNode implements Virtualizable, Canonicalizable, Simplifiable { public static final NodeClass TYPE = NodeClass.create(LoadIndexedNode.class); @@ -138,6 +147,30 @@ return this; } + @Override + public void simplify(SimplifierTool tool) { + if (tool.allUsagesAvailable() && hasNoUsages()) { + NodeView view = NodeView.from(tool); + ValueNode arrayLength = ArrayLengthNode.create(array, tool.getConstantReflection()); + LogicNode boundsCheck = CompareNode.createCompareNode(CanonicalCondition.BT, index, arrayLength, tool.getConstantReflection(), view); + if (boundsCheck.isTautology()) { + return; + } + if (graph().getGuardsStage().allowsGuardInsertion()) { + if (!arrayLength.isAlive()) { + arrayLength = graph().addOrUniqueWithInputs(arrayLength); + if (arrayLength instanceof FixedWithNextNode) { + FixedWithNextNode fixedArrayLength = (FixedWithNextNode) arrayLength; + graph().addBeforeFixed(this, fixedArrayLength); + } + } + boundsCheck = graph().addOrUniqueWithInputs(boundsCheck); + FixedGuardNode fixedGuard = new FixedGuardNode(boundsCheck, DeoptimizationReason.BoundsCheckException, DeoptimizationAction.InvalidateReprofile, false, getNodeSourcePosition()); + graph().replaceFixedWithFixed(this, graph().add(fixedGuard)); + } + } + } + private static ValueNode tryConstantFold(ValueNode array, ValueNode index, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { if (array.isConstant() && !array.isNullConstant() && index.isConstant()) { JavaConstant arrayConstant = array.asJavaConstant(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewMultiArrayNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -27,6 +27,7 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; import org.graalvm.compiler.graph.NodeClass; @@ -89,7 +90,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { return dimension(0); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -125,7 +125,7 @@ } } if (locationIdentity.equals(ARRAY_LENGTH_LOCATION)) { - ValueNode length = GraphUtil.arrayLength(object, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ); + ValueNode length = GraphUtil.arrayLength(object, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ, tool.getConstantReflection()); if (length != null) { return length; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/ArrayLengthProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/ArrayLengthProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/ArrayLengthProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,6 +24,7 @@ package org.graalvm.compiler.nodes.spi; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValuePhiNode; import org.graalvm.compiler.nodes.ValueProxyNode; @@ -65,5 +66,5 @@ * * This method should not be called directly. Use {@link GraphUtil#arrayLength} instead. */ - ValueNode findLength(FindLengthMode mode); + ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java Fri Aug 17 13:20:53 2018 -0700 @@ -677,7 +677,7 @@ * @param mode The mode as documented in {@link FindLengthMode}. * @return The array length if one was found, or null otherwise. */ - public static ValueNode arrayLength(ValueNode value, ArrayLengthProvider.FindLengthMode mode) { + public static ValueNode arrayLength(ValueNode value, FindLengthMode mode, ConstantReflectionProvider constantReflection) { Objects.requireNonNull(mode); ValueNode current = value; @@ -687,14 +687,14 @@ * ArrayLengthProvider, therefore we check this case first. */ if (current instanceof ArrayLengthProvider) { - return ((ArrayLengthProvider) current).findLength(mode); + return ((ArrayLengthProvider) current).findLength(mode, constantReflection); } else if (current instanceof ValuePhiNode) { - return phiArrayLength((ValuePhiNode) current, mode); + return phiArrayLength((ValuePhiNode) current, mode, constantReflection); } else if (current instanceof ValueProxyNode) { ValueProxyNode proxy = (ValueProxyNode) current; - ValueNode length = arrayLength(proxy.getOriginalNode(), mode); + ValueNode length = arrayLength(proxy.getOriginalNode(), mode, constantReflection); if (mode == ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ && length != null && !length.isConstant()) { length = new ValueProxyNode(length, proxy.proxyPoint()); } @@ -710,7 +710,7 @@ } while (true); } - private static ValueNode phiArrayLength(ValuePhiNode phi, ArrayLengthProvider.FindLengthMode mode) { + private static ValueNode phiArrayLength(ValuePhiNode phi, ArrayLengthProvider.FindLengthMode mode, ConstantReflectionProvider constantReflection) { if (phi.merge() instanceof LoopBeginNode) { /* Avoid cycle detection by not processing phi functions that could introduce cycles. */ return null; @@ -719,7 +719,7 @@ ValueNode singleLength = null; for (int i = 0; i < phi.values().count(); i++) { ValueNode input = phi.values().get(i); - ValueNode length = arrayLength(input, mode); + ValueNode length = arrayLength(input, mode, constantReflection); if (length == null) { return null; } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/AllocatedObjectNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/AllocatedObjectNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/AllocatedObjectNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -28,6 +28,7 @@ import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.core.common.type.TypeReference; import org.graalvm.compiler.graph.NodeClass; @@ -74,7 +75,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { - return GraphUtil.arrayLength(virtualObject, mode); + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { + return GraphUtil.arrayLength(virtualObject, mode, constantReflection); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/virtual/VirtualArrayNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -26,6 +26,7 @@ import java.nio.ByteOrder; +import jdk.vm.ci.meta.ConstantReflectionProvider; import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.nodeinfo.NodeInfo; @@ -138,7 +139,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { return ConstantNode.forInt(length); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/EnumOptionKey.java Fri Aug 17 13:20:53 2018 -0700 @@ -31,13 +31,12 @@ public class EnumOptionKey> extends OptionKey { final Class enumClass; - @SuppressWarnings("unchecked") public EnumOptionKey(T value) { super(value); if (value == null) { throw new IllegalArgumentException("Value must not be null"); } - this.enumClass = (Class) value.getClass(); + this.enumClass = value.getDeclaringClass(); } /** diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java Fri Aug 17 13:20:53 2018 -0700 @@ -308,7 +308,7 @@ processAccess((MemoryAccess) node, state); } - if (createFloatingReads & node instanceof FloatableAccessNode) { + if (createFloatingReads && node instanceof FloatableAccessNode) { processFloatable((FloatableAccessNode) node, state); } else if (node instanceof MemoryCheckpoint.Single) { processCheckpoint((MemoryCheckpoint.Single) node, state); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/info/elem/InlineableGraph.java Fri Aug 17 13:20:53 2018 -0700 @@ -192,7 +192,7 @@ private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller, boolean trackNodeSourcePosition) { DebugContext debug = caller.getDebug(); StructuredGraph newGraph = new StructuredGraph.Builder(caller.getOptions(), debug, AllowAssumptions.ifNonNull(caller.getAssumptions())).method(method).trackNodeSourcePosition( - trackNodeSourcePosition).build(); + trackNodeSourcePosition).useProfilingInfo(caller.useProfilingInfo()).build(); try (DebugContext.Scope s = debug.scope("InlineGraph", newGraph)) { if (!caller.isUnsafeAccessTrackingEnabled()) { newGraph.disableUnsafeAccessTracking(); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/BasePhase.java Fri Aug 17 13:20:53 2018 -0700 @@ -260,7 +260,7 @@ return false; } - private final class GraphChangeListener extends NodeEventListener { + private static final class GraphChangeListener extends NodeEventListener { boolean changed; private StructuredGraph graph; private Mark mark; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.amd64; + +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512; + +import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.InputType; +import org.graalvm.compiler.nodeinfo.NodeCycles; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.FixedWithNextNode; +import org.graalvm.compiler.nodes.NamedLocationIdentity; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.ValueNodeUtil; +import org.graalvm.compiler.nodes.memory.MemoryAccess; +import org.graalvm.compiler.nodes.memory.MemoryNode; +import org.graalvm.compiler.nodes.spi.LIRLowerable; +import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import jdk.internal.vm.compiler.word.LocationIdentity; +import jdk.internal.vm.compiler.word.Pointer; + +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.Value; + +@NodeInfo(size = SIZE_512, cycles = NodeCycles.CYCLES_UNKNOWN) +public class AMD64ArrayIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess { + + public static final NodeClass TYPE = NodeClass.create(AMD64ArrayIndexOfNode.class); + + private final JavaKind kind; + + @Input private ValueNode arrayPointer; + @Input private ValueNode arrayLength; + @Input private ValueNode searchValue; + + @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess; + + public AMD64ArrayIndexOfNode(ValueNode arrayPointer, ValueNode arrayLength, ValueNode searchValue, @ConstantNodeParameter JavaKind kind) { + super(TYPE, StampFactory.forKind(JavaKind.Int)); + this.kind = kind; + this.arrayPointer = arrayPointer; + this.arrayLength = arrayLength; + this.searchValue = searchValue; + } + + @Override + public LocationIdentity getLocationIdentity() { + return NamedLocationIdentity.getArrayLocation(kind); + } + + @Override + public void generate(NodeLIRBuilderTool gen) { + Value result = gen.getLIRGeneratorTool().emitArrayIndexOf(kind, gen.operand(arrayPointer), gen.operand(arrayLength), gen.operand(searchValue)); + gen.setResult(this, result); + } + + @Override + public MemoryNode getLastLocationAccess() { + return lastLocationAccess; + } + + @Override + public void setLastLocationAccess(MemoryNode lla) { + updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla)); + lastLocationAccess = lla; + } + + @NodeIntrinsic + public static native int optimizedArrayIndexOf(Pointer arrayPointer, int arrayLength, char searchValue, @ConstantNodeParameter JavaKind kind); +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Aug 17 13:20:53 2018 -0700 @@ -80,8 +80,8 @@ new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object, JavaKind.Boolean, JavaKind.Byte, JavaKind.Short, JavaKind.Char, JavaKind.Float, JavaKind.Double}); registerUnsafePlugins(invocationPlugins, replacementsBytecodeProvider, explicitUnsafeNullChecks); registerStringPlugins(invocationPlugins, arch, replacementsBytecodeProvider); - registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider); - registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider); + registerStringLatin1Plugins(invocationPlugins, arch, replacementsBytecodeProvider); + registerStringUTF16Plugins(invocationPlugins, arch, replacementsBytecodeProvider); registerMathPlugins(invocationPlugins, arch, arithmeticStubs, replacementsBytecodeProvider); registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider); } @@ -198,25 +198,34 @@ r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class, int.class, char[].class, int.class, int.class, int.class); } + if (arch.getFeatures().contains(CPUFeature.SSSE3)) { + r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", Receiver.class, int.class, int.class); + } r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo", Receiver.class, String.class); } } - private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) { + private static void registerStringLatin1Plugins(InvocationPlugins plugins, AMD64 arch, BytecodeProvider replacementsBytecodeProvider) { if (JAVA_SPECIFICATION_VERSION >= 9) { Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider); r.setAllowOverwrite(true); r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class); r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class); + if (arch.getFeatures().contains(CPUFeature.SSSE3)) { + r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "indexOf", byte[].class, int.class, int.class); + } } } - private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) { + private static void registerStringUTF16Plugins(InvocationPlugins plugins, AMD64 arch, BytecodeProvider replacementsBytecodeProvider) { if (JAVA_SPECIFICATION_VERSION >= 9) { Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider); r.setAllowOverwrite(true); r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class); r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class); + if (arch.getFeatures().contains(CPUFeature.SSSE3)) { + r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "indexOfCharUnsafe", byte[].class, int.class, int.class, int.class); + } } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,11 +24,15 @@ package org.graalvm.compiler.replacements.amd64; +import jdk.vm.ci.meta.JavaKind; import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; import org.graalvm.compiler.api.replacements.MethodSubstitution; +import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode; - -import jdk.vm.ci.meta.JavaKind; +import org.graalvm.compiler.word.Word; +import jdk.internal.vm.compiler.word.Pointer; // JaCoCo Exclude @@ -40,6 +44,14 @@ @ClassSubstitution(className = "java.lang.StringLatin1", optional = true) public class AMD64StringLatin1Substitutions { + @Fold + static int byteArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { + return arrayOffsetProvider.arrayBaseOffset(JavaKind.Byte); + } + + /** Marker value for the {@link InjectedParameter} injected parameter. */ + static final ArrayOffsetProvider INJECTED = null; + /** * @param value is byte[] * @param other is byte[] @@ -58,4 +70,25 @@ return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Char); } + @MethodSubstitution(optional = true) + public static int indexOf(byte[] value, int ch, int origFromIndex) { + int fromIndex = origFromIndex; + if (ch >>> 8 != 0) { + // search value must be a byte value + return -1; + } + int length = value.length; + if (fromIndex < 0) { + fromIndex = 0; + } else if (fromIndex >= length) { + // Note: fromIndex might be near -1>>>1. + return -1; + } + Pointer sourcePointer = Word.objectToTrackedPointer(value).add(byteArrayBaseOffset(INJECTED)).add(fromIndex); + int result = AMD64ArrayIndexOfNode.optimizedArrayIndexOf(sourcePointer, length - fromIndex, (char) ch, JavaKind.Byte); + if (result != -1) { + return result + fromIndex; + } + return result; + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java Fri Aug 17 13:20:53 2018 -0700 @@ -92,6 +92,33 @@ return result; } + // Only exists in JDK <= 8 + @MethodSubstitution(isStatic = false, optional = true) + public static int indexOf(String source, int ch, int origFromIndex) { + int fromIndex = origFromIndex; + final int sourceCount = source.length(); + if (fromIndex >= sourceCount) { + // Note: fromIndex might be near -1>>>1. + return -1; + } + if (fromIndex < 0) { + fromIndex = 0; + } + + if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { + char[] sourceArray = StringSubstitutions.getValue(source); + + Pointer sourcePointer = Word.objectToTrackedPointer(sourceArray).add(charArrayBaseOffset(INJECTED)).add(fromIndex * charArrayIndexScale(INJECTED)); + int result = AMD64ArrayIndexOfNode.optimizedArrayIndexOf(sourcePointer, sourceCount - fromIndex, (char) ch, JavaKind.Char); + if (result != -1) { + return result + fromIndex; + } + return result; + } else { + return indexOf(source, ch, origFromIndex); + } + } + @MethodSubstitution(isStatic = false) @SuppressFBWarnings(value = "ES_COMPARING_PARAMETER_STRING_WITH_EQ", justification = "reference equality on the receiver is what we want") public static int compareTo(String receiver, String anotherString) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,10 +25,15 @@ package org.graalvm.compiler.replacements.amd64; import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.compiler.api.replacements.Fold.InjectedParameter; import org.graalvm.compiler.api.replacements.MethodSubstitution; +import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider; import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode; import jdk.vm.ci.meta.JavaKind; +import org.graalvm.compiler.word.Word; +import jdk.internal.vm.compiler.word.Pointer; // JaCoCo Exclude @@ -40,6 +45,19 @@ @ClassSubstitution(className = "java.lang.StringUTF16", optional = true) public class AMD64StringUTF16Substitutions { + @Fold + static int byteArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { + return arrayOffsetProvider.arrayBaseOffset(JavaKind.Byte); + } + + @Fold + static int charArrayIndexScale(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { + return arrayOffsetProvider.arrayScalingFactor(JavaKind.Char); + } + + /** Marker value for the {@link InjectedParameter} injected parameter. */ + static final ArrayOffsetProvider INJECTED = null; + /** * @param value is char[] * @param other is char[] @@ -62,4 +80,13 @@ return ArrayCompareToNode.compareTo(other, value, other.length, value.length, JavaKind.Char, JavaKind.Byte); } + @MethodSubstitution(optional = true) + public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) { + Pointer sourcePointer = Word.objectToTrackedPointer(value).add(byteArrayBaseOffset(INJECTED)).add(fromIndex * charArrayIndexScale(INJECTED)); + int result = AMD64ArrayIndexOfNode.optimizedArrayIndexOf(sourcePointer, max - fromIndex, (char) ch, JavaKind.Char); + if (result != -1) { + return result + fromIndex; + } + return result; + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/GeneratedPlugin.java Fri Aug 17 13:20:53 2018 -0700 @@ -51,7 +51,8 @@ public GeneratedPlugin(ExecutableElement intrinsicMethod) { this.intrinsicMethod = intrinsicMethod; this.needInjectionProvider = false; - this.pluginName = intrinsicMethod.getEnclosingElement().getSimpleName() + "_" + intrinsicMethod.getSimpleName(); + // Lets keep generated class names short to mitigate hitting file name length limits. + this.pluginName = intrinsicMethod.getSimpleName().toString(); } protected abstract TypeElement getAnnotationClass(AbstractProcessor processor); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/PluginGenerator.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/PluginGenerator.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.processor/src/org/graalvm/compiler/replacements/processor/PluginGenerator.java Fri Aug 17 13:20:53 2018 -0700 @@ -38,13 +38,6 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.TypeVariable; -import javax.lang.model.type.WildcardType; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; @@ -106,49 +99,12 @@ } } - private static void appendSimpleTypeName(StringBuilder ret, TypeMirror type) { - switch (type.getKind()) { - case DECLARED: - DeclaredType declared = (DeclaredType) type; - TypeElement element = (TypeElement) declared.asElement(); - ret.append(element.getSimpleName()); - break; - case TYPEVAR: - appendSimpleTypeName(ret, ((TypeVariable) type).getUpperBound()); - break; - case WILDCARD: - appendSimpleTypeName(ret, ((WildcardType) type).getExtendsBound()); - break; - case ARRAY: - appendSimpleTypeName(ret, ((ArrayType) type).getComponentType()); - ret.append("Array"); - break; - default: - ret.append(type); - } - } - private static void disambiguateNames(List plugins) { - // if we have more than one method with the same name, disambiguate with the argument types - disambiguateWith(plugins, plugin -> { - StringBuilder ret = new StringBuilder(plugin.getPluginName()); - for (VariableElement param : plugin.intrinsicMethod.getParameters()) { - ret.append('_'); - appendSimpleTypeName(ret, param.asType()); - } - return ret.toString(); - }); - - // since we're using simple names for argument types, we could still have a collision - disambiguateWith(plugins, new Function() { - - private int idx = 0; - - @Override - public String apply(GeneratedPlugin plugin) { - return plugin.getPluginName() + "_" + (idx++); - } - }); + // If we have more than one method with the same name, disambiguate with a numeric suffix. + // We use this instead of a suffix based on argument types to mitigate hitting file name + // length limits. We start the suffix with "__" to make it visually stick out. + int[] nextId = {0}; + disambiguateWith(plugins, plugin -> plugin.getPluginName() + "__" + nextId[0]++); } private static void createPluginFactory(AbstractProcessor processor, Element topLevelClass, List plugins) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -83,7 +83,7 @@ ClassLoader testCl = new MyClassLoader(); @SuppressWarnings("unchecked") Class c = (Class) testCl.loadClass(name); - Runnable r = c.newInstance(); + Runnable r = c.getDeclaredConstructor().newInstance(); ct = Long.MAX_VALUE; // warmup for (int i = 0; i < 100; i++) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnIntegerExactTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnIntegerExactTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.test; + +import jdk.vm.ci.meta.SpeculationLog; +import org.graalvm.compiler.code.CompilationResult; +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.graalvm.compiler.debug.DebugContext; +import org.junit.Test; + +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class DeoptimizeOnIntegerExactTest extends GraalCompilerTest { + + private final SpeculationLog speculationLog; + + static boolean highlyLikely = true; + static boolean highlyUnlikely = false; + + public DeoptimizeOnIntegerExactTest() { + speculationLog = getCodeCache().createSpeculationLog(); + } + + public static int testAddExactSnippet(int x, int y) { + if (highlyLikely) { + return highlyUnlikely ? Math.addExact(x, y) : x; + } else { + return highlyUnlikely ? y : Math.addExact(x, y); + } + } + + public static int testSubtractExactSnippet(int x, int y) { + if (highlyLikely) { + return highlyUnlikely ? Math.subtractExact(x, y) : x; + } else { + return highlyUnlikely ? y : Math.subtractExact(x, y); + } + } + + public static int testMultiplyExactSnippet(int x, int y) { + if (highlyLikely) { + return highlyUnlikely ? Math.multiplyExact(x, y) : x; + } else { + return highlyUnlikely ? y : Math.multiplyExact(x, y); + } + } + + public static int testIncrementExactSnippet(int x, int y) { + if (highlyLikely) { + return highlyUnlikely ? Math.incrementExact(x) : x; + } else { + return highlyUnlikely ? y : Math.incrementExact(x); + } + } + + public static int testDecrementExactSnippet(int x, int y) { + if (highlyLikely) { + return highlyUnlikely ? Math.decrementExact(x) : x; + } else { + return highlyUnlikely ? y : Math.decrementExact(x); + } + } + + public void testAgainIfDeopt(String methodName, int x, int y) throws InvalidInstalledCodeException { + ResolvedJavaMethod method = getResolvedJavaMethod(methodName); + // We speculate on the first compilation. The global value numbering will merge the two + // floating integer exact operation nodes. + InstalledCode code = getCode(method); + code.executeVarargs(x, y); + if (!code.isValid()) { + // At the recompilation, we anchor the floating integer exact operation nodes at their + // corresponding branches. + code = getCode(method); + code.executeVarargs(x, y); + // The recompiled code should not get deoptimized. + assertTrue(code.isValid()); + } + } + + @Test + public void testAddExact() throws InvalidInstalledCodeException { + testAgainIfDeopt("testAddExactSnippet", Integer.MAX_VALUE, 1); + } + + @Test + public void testSubtractExact() throws InvalidInstalledCodeException { + testAgainIfDeopt("testSubtractExactSnippet", 0, Integer.MIN_VALUE); + } + + @Test + public void testMultiplyExact() throws InvalidInstalledCodeException { + testAgainIfDeopt("testMultiplyExactSnippet", Integer.MAX_VALUE, 2); + } + + @Test + public void testIncrementExact() throws InvalidInstalledCodeException { + testAgainIfDeopt("testIncrementExactSnippet", Integer.MAX_VALUE, 1); + } + + @Test + public void testDecrementExact() throws InvalidInstalledCodeException { + testAgainIfDeopt("testDecrementExactSnippet", Integer.MIN_VALUE, 1); + } + + @Override + protected SpeculationLog getSpeculationLog() { + speculationLog.collectFailedSpeculations(); + return speculationLog; + } + + @Override + protected InstalledCode addMethod(DebugContext debug, final ResolvedJavaMethod method, final CompilationResult compilationResult) { + return getBackend().createInstalledCode(debug, method, compilationResult, speculationLog, null, false); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactExceptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/IntegerExactExceptionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.test; + +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.junit.Test; + +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +public class IntegerExactExceptionTest extends GraalCompilerTest { + + static int intCounter = 32; + + public void testIntegerExactOverflowSnippet(int input) { + try { + intCounter = Math.addExact(intCounter, input); + } catch (ArithmeticException e) { + intCounter = intCounter / 2; + } + } + + @Test + public void testIntegerExact() throws InvalidInstalledCodeException { + ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowSnippet"); + InstalledCode code = getCode(method); + code.executeVarargs(this, Integer.MAX_VALUE); + + if (!code.isValid()) { + code = getCode(method); + code.executeVarargs(this, Integer.MAX_VALUE); + assertTrue(code.isValid()); + } + } + + public void testIntegerExactOverflowWithoutHandlerSnippetW(int input) { + try { + intCounter = Math.addExact(intCounter, input); + } finally { + intCounter = intCounter / 2; + } + } + + @Test + public void testIntegerExactWithoutHandler() throws InvalidInstalledCodeException { + ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutHandlerSnippetW"); + InstalledCode code = getCode(method); + + try { + code.executeVarargs(this, Integer.MAX_VALUE); + } catch (ArithmeticException e) { + // An ArithmeticException is expected to be thrown. + } + + if (!code.isValid()) { + code = getCode(method); + try { + code.executeVarargs(this, Integer.MAX_VALUE); + } catch (ArithmeticException e) { + // An ArithmeticException is expected to be thrown. + } + assertTrue(code.isValid()); + } + } + + static long longCounter = 10; + + public void testLongExactOverflowSnippet(long input) { + try { + longCounter = Math.addExact(longCounter, input); + } catch (ArithmeticException e) { + longCounter = longCounter / 2; + } + } + + @Test + public void testLongExact() throws InvalidInstalledCodeException { + ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowSnippet"); + InstalledCode code = getCode(method); + code.executeVarargs(this, Long.MAX_VALUE); + + if (!code.isValid()) { + code = getCode(method); + code.executeVarargs(this, Long.MAX_VALUE); + assertTrue(code.isValid()); + } + } + + public void testLongExactWithoutHandlerSnippet(long input) { + try { + longCounter = Math.addExact(longCounter, input); + } finally { + longCounter = longCounter / 2; + } + } + + @Test + public void testLongExactWithoutHandler() throws InvalidInstalledCodeException { + ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactWithoutHandlerSnippet"); + InstalledCode code = getCode(method); + + try { + code.executeVarargs(this, Long.MAX_VALUE); + } catch (ArithmeticException e) { + // An ArithmeticException is expected to be thrown. + } + + if (!code.isValid()) { + code = getCode(method); + try { + code.executeVarargs(this, Long.MAX_VALUE); + } catch (ArithmeticException e) { + // An ArithmeticException is expected to be thrown. + } + assertTrue(code.isValid()); + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -35,6 +35,7 @@ import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; import org.graalvm.compiler.nodes.java.MethodCallTargetNode; import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.common.CanonicalizerPhase; import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase; import org.graalvm.compiler.phases.common.LoweringPhase; @@ -57,6 +58,11 @@ return testGraph(snippet, null); } + @SuppressWarnings("unused") + public BasePhase createInliningPhase(StructuredGraph graph) { + return new InliningPhase(new CanonicalizerPhase()); + } + @SuppressWarnings("try") protected StructuredGraph testGraph(final String snippet, String name) { DebugContext debug = getDebugContext(); @@ -64,7 +70,7 @@ StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug); HighTierContext context = getDefaultHighTierContext(); debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph"); - new InliningPhase(new CanonicalizerPhase()).apply(graph, context); + createInliningPhase(graph).apply(graph, context); debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph"); new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,69 +24,19 @@ package org.graalvm.compiler.replacements.test; -import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode; -import org.junit.Assert; -import org.junit.Assume; import org.junit.Test; -import jdk.vm.ci.amd64.AMD64; -import jdk.vm.ci.aarch64.AArch64; -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.meta.ResolvedJavaMethod; - /** * Tests compareTo method intrinsic. */ -public class StringCompareToTest extends MethodSubstitutionTest { - - private ResolvedJavaMethod realMethod = null; - private ResolvedJavaMethod testMethod = null; - private InstalledCode testCode = null; - - private final String[] testData = new String[]{ - "A", "\uFF21", "AB", "A", "a", "Ab", "AA", "\uFF21", - "A\uFF21", "ABC", "AB", "ABcD", "ABCD\uFF21\uFF21", "ABCD\uFF21", "ABCDEFG\uFF21", "ABCD", - "ABCDEFGH\uFF21\uFF21", "\uFF22", "\uFF21\uFF22", "\uFF21A", - "\uFF21\uFF21", - "\u043c\u0430\u043c\u0430\u0020\u043c\u044b\u043b\u0430\u0020\u0440\u0430\u043c\u0443\u002c\u0020\u0440\u0430\u043c\u0430\u0020\u0441\u044a\u0435\u043b\u0430\u0020\u043c\u0430\u043c\u0443", - "crazy dog jumps over laszy fox", - "some-string\0xff", - "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM+YMM-YMM-ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM+", - "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM-XMM-XMM+YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", - "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM+", - "" - }; +public class StringCompareToTest extends StringSubstitutionTestBase { public StringCompareToTest() { - Assume.assumeTrue((getTarget().arch instanceof AMD64) || (getTarget().arch instanceof AArch64)); - - realMethod = getResolvedJavaMethod(String.class, "compareTo", String.class); - testMethod = getResolvedJavaMethod("stringCompareTo"); - StructuredGraph graph = testGraph("stringCompareTo"); - - // Check to see if the resulting graph contains the expected node - StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null); - if (replacement == null) { - assertInGraph(graph, ArrayCompareToNode.class); - } - - // Force compilation - testCode = getCode(testMethod); - Assert.assertNotNull(testCode); - } - - private void executeStringCompareTo(String s0, String s1) { - Object expected = invokeSafe(realMethod, s0, s1); - // Verify that the original method and the substitution produce the same value - assertDeepEquals(expected, invokeSafe(testMethod, null, s0, s1)); - // Verify that the generated code and the original produce the same value - assertDeepEquals(expected, executeVarargsSafe(testCode, s0, s1)); + initSubstitution( + getResolvedJavaMethod(String.class, "compareTo", String.class), + getResolvedJavaMethod("stringCompareTo"), + ArrayCompareToNode.class); } public static int stringCompareTo(String a, String b) { @@ -94,36 +44,20 @@ } @Test + @Override public void testEqualString() { - String s = "equal-string"; - executeStringCompareTo(s, new String(s.toCharArray())); + super.testEqualString(); } @Test + @Override public void testDifferentString() { - // Smoke test for primary cases - executeStringCompareTo("AAAAAAAA", ""); - // LL - executeStringCompareTo("some-stringA", "some-string\0xff"); - // UU - executeStringCompareTo("\u2241AAAAAAAB", "\u2241\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41"); - // LU - executeStringCompareTo("AAAAAAAAB", "\u0041\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41"); + super.testDifferentString(); } @Test + @Override public void testAllStrings() { - for (String s0 : testData) { - for (String s1 : testData) { - try { - executeStringCompareTo(s0, s1); - } catch (AssertionError ex) { - System.out.println("FAIL: '" + ex + "'"); - System.out.println(" ***: s0 '" + s0 + "'"); - System.out.println(" ***: s1 '" + s1 + "'"); - throw ex; - } - } - } + super.testAllStrings(); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringEqualsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringEqualsTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.test; + +import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode; +import org.junit.Test; + +/** + * Tests compareTo method intrinsic. + */ +public class StringEqualsTest extends StringSubstitutionTestBase { + + public StringEqualsTest() { + initSubstitution( + getResolvedJavaMethod(String.class, "equals"), + getResolvedJavaMethod("stringEquals"), + ArrayEqualsNode.class); + } + + public static boolean stringEquals(String a, String b) { + return a.equals(b); + } + + @Test + @Override + public void testEqualString() { + super.testEqualString(); + } + + @Test + @Override + public void testDifferentString() { + super.testDifferentString(); + } + + @Test + @Override + public void testAllStrings() { + super.testAllStrings(); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfCharTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfCharTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.test; + +import java.util.ArrayList; +import java.util.Collection; + +import org.graalvm.compiler.core.test.GraalCompilerTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(value = Parameterized.class) +public class StringIndexOfCharTest extends GraalCompilerTest { + @Parameterized.Parameter(value = 0) public String sourceString; + @Parameterized.Parameter(value = 1) public int constantChar; + @Parameterized.Parameter(value = 2) public int fromIndex; + + @Parameterized.Parameters(name = "{0},{1},{2}") + public static Collection data() { + ArrayList tests = new ArrayList<>(); + String longString = "ab"; + for (int i = 0; i < 15; i++) { + longString = longString + longString; + } + longString = longString + "xx"; + String longUTF16String = "\u03bb" + longString; + String mediumString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax" + + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + String mediumUTF16String = "\u03bbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax" + + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + String[] targets = new String[]{"foobar", "foo", "bar", "\u03bbfoobar", mediumString, mediumUTF16String, longString, longUTF16String}; + int[] targetChars = new int[]{'f', 'o', 'r', 'x', Character.MIN_SUPPLEMENTARY_CODE_POINT}; + int[] targetOffsets = new int[18]; + for (int i = 0; i < 18; i++) { + targetOffsets[i] = i - 1; + } + for (String source : targets) { + for (int targetChar : targetChars) { + for (int offset : targetOffsets) { + tests.add(new Object[]{source, targetChar, offset}); + } + } + } + + return tests; + } + + public int testStringIndexOf(String a, int b) { + return a.indexOf(b); + } + + public int testStringIndexOfOffset(String a, int b, int offset) { + return a.indexOf(b, offset); + } + + @Test + public void testStringIndexOfConstant() { + test("testStringIndexOf", this.sourceString, this.constantChar); + } + + @Test + public void testStringIndexOfConstantOffset() { + test("testStringIndexOfOffset", this.sourceString, this.constantChar, this.fromIndex); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfConstantTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -24,15 +24,14 @@ package org.graalvm.compiler.replacements.test; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.meta.ResolvedJavaMethod; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.replacements.ConstantBindingParameterPlugin; import org.junit.Test; -import jdk.vm.ci.code.InstalledCode; -import jdk.vm.ci.meta.ResolvedJavaMethod; - public class StringIndexOfConstantTest extends StringIndexOfTestBase { /* diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringIndexOfTestBase.java Fri Aug 17 13:20:53 2018 -0700 @@ -41,6 +41,13 @@ public static Collection data() { ArrayList tests = new ArrayList<>(); String[] targets = new String[]{"foobar", "foo", "bar"}; + String[] utf16targets = new String[]{"grga " + ((char) 0x10D) + "varak", "grga", ((char) 0x10D) + "varak"}; + addTargets(tests, targets); + addTargets(tests, utf16targets); + return tests; + } + + private static void addTargets(ArrayList tests, String[] targets) { for (String source : targets) { for (String target : targets) { tests.add(new Object[]{source, target}); @@ -60,7 +67,6 @@ tests.add(new Object[]{s.substring(0, s.length() - 1) + s, s}); } } - return tests; } public int testStringIndexOf(String a, String b) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionTestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionTestBase.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements.test; + +import org.graalvm.compiler.nodes.StructuredGraph; +import org.junit.Assert; +import org.junit.Assume; + +import jdk.vm.ci.amd64.AMD64; +import jdk.vm.ci.aarch64.AArch64; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.meta.ResolvedJavaMethod; + +/** + * Tests compareTo method intrinsic. + */ +public class StringSubstitutionTestBase extends MethodSubstitutionTest { + + private ResolvedJavaMethod realMethod = null; + private ResolvedJavaMethod testMethod = null; + private InstalledCode testCode = null; + + protected final String[] testData = new String[]{ + "A", "\uFF21", "AB", "A", "a", "Ab", "AA", "\uFF21", + "A\uFF21", "ABC", "AB", "ABcD", "ABCD\uFF21\uFF21", "ABCD\uFF21", "ABCDEFG\uFF21", "ABCD", + "ABCDEFGH\uFF21\uFF21", "\uFF22", "\uFF21\uFF22", "\uFF21A", + "\uFF21\uFF21", + "\u043c\u0430\u043c\u0430\u0020\u043c\u044b\u043b\u0430\u0020\u0440\u0430\u043c\u0443\u002c\u0020\u0440\u0430\u043c\u0430\u0020\u0441\u044a\u0435\u043b\u0430\u0020\u043c\u0430\u043c\u0443", + "crazy dog jumps over laszy fox", + "some-string\0xff", + "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM+YMM-YMM-ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM+", + "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM-XMM-XMM+YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-", + "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM+", + "" + }; + + protected void initSubstitution(ResolvedJavaMethod theRealMethod, + ResolvedJavaMethod theTestMethod, Class expectedNode) { + Assume.assumeTrue((getTarget().arch instanceof AMD64) || (getTarget().arch instanceof AArch64)); + + realMethod = theRealMethod; + testMethod = theTestMethod; + + StructuredGraph graph = testGraph(testMethod.getName()); + + // Check to see if the resulting graph contains the expected node + StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null); + if (replacement == null) { + assertInGraph(graph, expectedNode); + } + + // Force compilation + testCode = getCode(testMethod); + Assert.assertNotNull(testCode); + } + + private void executeSubstitution(String s0, String s1) { + Object expected = invokeSafe(realMethod, s0, s1); + // Verify that the original method and the substitution produce the same value + assertDeepEquals(expected, invokeSafe(testMethod, null, s0, s1)); + // Verify that the generated code and the original produce the same value + assertDeepEquals(expected, executeVarargsSafe(testCode, s0, s1)); + } + + protected void testEqualString() { + String s = "equal-string"; + executeSubstitution(s, new String(s.toCharArray())); + } + + protected void testDifferentString() { + // Smoke test for primary cases + executeSubstitution("AAAAAAAA", ""); + // LL + executeSubstitution("some-stringA", "some-string\0xff"); + // UU + executeSubstitution("\u2241AAAAAAAB", "\u2241\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41"); + // LU + executeSubstitution("AAAAAAAAB", "\u0041\u0041\u0041\u0041\u0041\u0041\u0041\u0041\uFF41"); + } + + protected void testAllStrings() { + for (String s0 : testData) { + for (String s1 : testData) { + try { + executeSubstitution(s0, s1); + } catch (AssertionError ex) { + System.out.println("FAIL: '" + ex + "'"); + System.out.println(" ***: s0 '" + s0 + "'"); + System.out.println(" ***: s1 '" + s1 + "'"); + throw ex; + } + } + } + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -102,4 +102,44 @@ return a.equals(b); } + @Test + public void testIndexOfConstant() { + test("indexOfConstant"); + } + + public int indexOfConstant() { + String foobar = "foobar"; + String bar = "bar"; + return foobar.indexOf(bar); + } + + @Test + public void testIndexOfConstantUTF16() { + test("indexOfConstantUTF16case1"); + test("indexOfConstantUTF16case2"); + test("indexOfConstantUTF16case3"); + } + + public int indexOfConstantUTF16case1() { + return ("grga " + ((char) 0x10D) + "varak").indexOf(((char) 0x10D) + "varak"); + } + + public int indexOfConstantUTF16case2() { + int index = ("grga " + ((char) 0xD) + "varak").indexOf(((char) 0x10D) + "varak"); + return index; + } + + public int indexOfConstantUTF16case3() { + int index = ("grga " + ((char) 0x100) + "varak").indexOf(((char) 0x10D) + "varak"); + return index; + } + + @Test + public void testCompareTo() { + test("compareTo"); + } + + public int compareTo() { + return "ofar".compareTo("rafo"); + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -198,6 +198,7 @@ } } + @SuppressWarnings("deprecation") public static boolean loadAgent(Path agent) throws Exception { String vmName = ManagementFactory.getRuntimeMXBean().getName(); int p = vmName.indexOf('@'); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Fri Aug 17 13:20:53 2018 -0700 @@ -49,6 +49,8 @@ public static class Templates extends AbstractTemplates { private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant"); + private final SnippetInfo latin1IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "latin1IndexOfConstant"); + private final SnippetInfo utf16IndexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "utf16IndexOfConstant"); public Templates(OptionValues options, Iterable factories, Providers providers, SnippetReflectionProvider snippetReflection, TargetDescription target) { super(options, factories, providers, snippetReflection, target); @@ -69,6 +71,34 @@ args.addConst("cache", computeCache(targetCharArray)); template(stringIndexOf, args).instantiate(providers.getMetaAccess(), stringIndexOf, DEFAULT_REPLACER, args); } + + public void lowerLatin1(SnippetLowerableMemoryNode latin1IndexOf, LoweringTool tool) { + StructuredGraph graph = latin1IndexOf.graph(); + Arguments args = new Arguments(latin1IndexOfConstant, graph.getGuardsStage(), tool.getLoweringStage()); + args.add("source", latin1IndexOf.getArgument(0)); + args.add("sourceCount", latin1IndexOf.getArgument(1)); + args.addConst("target", latin1IndexOf.getArgument(2)); + args.add("targetCount", latin1IndexOf.getArgument(3)); + args.add("origFromIndex", latin1IndexOf.getArgument(4)); + byte[] targetByteArray = snippetReflection.asObject(byte[].class, latin1IndexOf.getArgument(2).asJavaConstant()); + args.addConst("md2", md2(targetByteArray)); + args.addConst("cache", computeCache(targetByteArray)); + template(latin1IndexOf, args).instantiate(providers.getMetaAccess(), latin1IndexOf, DEFAULT_REPLACER, args); + } + + public void lowerUTF16(SnippetLowerableMemoryNode utf16IndexOf, LoweringTool tool) { + StructuredGraph graph = utf16IndexOf.graph(); + Arguments args = new Arguments(utf16IndexOfConstant, graph.getGuardsStage(), tool.getLoweringStage()); + args.add("source", utf16IndexOf.getArgument(0)); + args.add("sourceCount", utf16IndexOf.getArgument(1)); + args.addConst("target", utf16IndexOf.getArgument(2)); + args.add("targetCount", utf16IndexOf.getArgument(3)); + args.add("origFromIndex", utf16IndexOf.getArgument(4)); + byte[] targetByteArray = snippetReflection.asObject(byte[].class, utf16IndexOf.getArgument(2).asJavaConstant()); + args.addConst("md2", md2Utf16(targetByteArray)); + args.addConst("cache", computeCacheUtf16(targetByteArray)); + template(utf16IndexOf, args).instantiate(providers.getMetaAccess(), utf16IndexOf, DEFAULT_REPLACER, args); + } } static int md2(char[] target) { @@ -96,6 +126,65 @@ return cache; } + static int md2(byte[] target) { + int c = target.length; + if (c == 0) { + return 0; + } + byte lastByte = target[c - 1]; + int md2 = c; + for (int i = 0; i < c - 1; i++) { + if (target[i] == lastByte) { + md2 = (c - 1) - i; + } + } + return md2; + } + + static long computeCache(byte[] s) { + int c = s.length; + int cache = 0; + int i; + for (i = 0; i < c - 1; i++) { + cache |= (1 << (s[i] & 63)); + } + return cache; + } + + static int md2Utf16(byte[] target) { + int c = target.length / 2; + if (c == 0) { + return 0; + } + long base = UnsafeAccess.UNSAFE.arrayBaseOffset(byte[].class); + char lastChar = UnsafeAccess.UNSAFE.getChar(target, base + (c - 1) * 2); + int md2 = c; + for (int i = 0; i < c - 1; i++) { + char currChar = UnsafeAccess.UNSAFE.getChar(target, base + i * 2); + if (currChar == lastChar) { + md2 = (c - 1) - i; + } + } + return md2; + } + + static long computeCacheUtf16(byte[] s) { + int c = s.length / 2; + int cache = 0; + int i; + long base = UnsafeAccess.UNSAFE.arrayBaseOffset(byte[].class); + for (i = 0; i < c - 1; i++) { + char currChar = UnsafeAccess.UNSAFE.getChar(s, base + i * 2); + cache |= (1 << (currChar & 63)); + } + return cache; + } + + @Fold + static int byteArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { + return arrayOffsetProvider.arrayBaseOffset(JavaKind.Byte); + } + @Fold static int charArrayBaseOffset(@InjectedParameter ArrayOffsetProvider arrayOffsetProvider) { return arrayOffsetProvider.arrayBaseOffset(JavaKind.Char); @@ -161,4 +250,120 @@ } return -1; } + + @Snippet + public static int utf16IndexOfConstant(byte[] source, int sourceCount, + @ConstantParameter byte[] target, int targetCount, + int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) { + int fromIndex = origFromIndex; + if (fromIndex >= sourceCount) { + return (targetCount == 0 ? sourceCount : -1); + } + if (fromIndex < 0) { + fromIndex = 0; + } + if (targetCount == 0) { + return fromIndex; + } + + int targetCountLess1 = targetCount - 1; + int sourceEnd = sourceCount - targetCountLess1; + + long base = byteArrayBaseOffset(INJECTED); + int lastChar = UnsafeAccess.UNSAFE.getChar(target, base + targetCountLess1 * 2); + + outer_loop: for (long i = fromIndex; i < sourceEnd;) { + int src = UnsafeAccess.UNSAFE.getChar(source, base + (i + targetCountLess1) * 2); + if (src == lastChar) { + // With random strings and a 4-character alphabet, + // reverse matching at this point sets up 0.8% fewer + // frames, but (paradoxically) makes 0.3% more probes. + // Since those probes are nearer the lastChar probe, + // there is may be a net D$ win with reverse matching. + // But, reversing loop inhibits unroll of inner loop + // for unknown reason. So, does running outer loop from + // (sourceOffset - targetCountLess1) to (sourceOffset + sourceCount) + if (targetCount <= 8) { + ExplodeLoopNode.explodeLoop(); + } + for (long j = 0; j < targetCountLess1; j++) { + char sourceChar = UnsafeAccess.UNSAFE.getChar(source, base + (i + j) * 2); + if (UnsafeAccess.UNSAFE.getChar(target, base + j * 2) != sourceChar) { + if ((cache & (1 << sourceChar)) == 0) { + if (md2 < j + 1) { + i += j + 1; + continue outer_loop; + } + } + i += md2; + continue outer_loop; + } + } + return (int) i; + } + if ((cache & (1 << src)) == 0) { + i += targetCountLess1; + } + i++; + } + return -1; + } + + @Snippet + public static int latin1IndexOfConstant(byte[] source, int sourceCount, + @ConstantParameter byte[] target, int targetCount, + int origFromIndex, @ConstantParameter int md2, @ConstantParameter long cache) { + int fromIndex = origFromIndex; + if (fromIndex >= sourceCount) { + return (targetCount == 0 ? sourceCount : -1); + } + if (fromIndex < 0) { + fromIndex = 0; + } + if (targetCount == 0) { + return fromIndex; + } + + int targetCountLess1 = targetCount - 1; + int sourceEnd = sourceCount - targetCountLess1; + + long base = byteArrayBaseOffset(INJECTED); + int lastByte = UnsafeAccess.UNSAFE.getByte(target, base + targetCountLess1); + + outer_loop: for (long i = fromIndex; i < sourceEnd;) { + int src = UnsafeAccess.UNSAFE.getByte(source, base + i + targetCountLess1); + if (src == lastByte) { + // With random strings and a 4-character alphabet, + // reverse matching at this point sets up 0.8% fewer + // frames, but (paradoxically) makes 0.3% more probes. + // Since those probes are nearer the lastByte probe, + // there is may be a net D$ win with reverse matching. + // But, reversing loop inhibits unroll of inner loop + // for unknown reason. So, does running outer loop from + // (sourceOffset - targetCountLess1) to (sourceOffset + sourceCount) + if (targetCount <= 8) { + ExplodeLoopNode.explodeLoop(); + } + for (long j = 0; j < targetCountLess1; j++) { + byte sourceByte = UnsafeAccess.UNSAFE.getByte(source, base + i + j); + if (UnsafeAccess.UNSAFE.getByte(target, base + j) != sourceByte) { + if ((cache & (1 << sourceByte)) == 0) { + if (md2 < j + 1) { + i += j + 1; + continue outer_loop; + } + } + i += md2; + continue outer_loop; + } + } + return (int) i; + } + if ((cache & (1 << src)) == 0) { + i += targetCountLess1; + } + i++; + } + return -1; + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java Fri Aug 17 13:20:53 2018 -0700 @@ -239,6 +239,10 @@ lowerBinaryMath((BinaryMathIntrinsicNode) n, tool); } else if (n instanceof StringIndexOfNode) { lowerIndexOf((StringIndexOfNode) n); + } else if (n instanceof StringLatin1IndexOfNode) { + lowerLatin1IndexOf((StringLatin1IndexOfNode) n); + } else if (n instanceof StringUTF16IndexOfNode) { + lowerUTF16IndexOf((StringUTF16IndexOfNode) n); } else if (n instanceof UnpackEndianHalfNode) { lowerSecondHalf((UnpackEndianHalfNode) n); } else { @@ -269,6 +273,40 @@ } } + private void lowerLatin1IndexOf(StringLatin1IndexOfNode n) { + if (n.getArgument(2).isConstant()) { + SnippetLowering lowering = new SnippetLowering() { + @Override + public void lower(SnippetLowerableMemoryNode node, LoweringTool tool) { + if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { + return; + } + indexOfSnippets.lowerLatin1(node, tool); + } + }; + SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), n.stamp(NodeView.DEFAULT), n.toArgumentArray()); + n.graph().add(snippetLower); + n.graph().replaceFixedWithFixed(n, snippetLower); + } + } + + private void lowerUTF16IndexOf(StringUTF16IndexOfNode n) { + if (n.getArgument(2).isConstant()) { + SnippetLowering lowering = new SnippetLowering() { + @Override + public void lower(SnippetLowerableMemoryNode node, LoweringTool tool) { + if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) { + return; + } + indexOfSnippets.lowerUTF16(node, tool); + } + }; + SnippetLowerableMemoryNode snippetLower = new SnippetLowerableMemoryNode(lowering, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), n.stamp(NodeView.DEFAULT), n.toArgumentArray()); + n.graph().add(snippetLower); + n.graph().replaceFixedWithFixed(n, snippetLower); + } + } + private void lowerBinaryMath(BinaryMathIntrinsicNode math, LoweringTool tool) { if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { return; @@ -762,7 +800,7 @@ barrierType = fieldInitializationBarrier(entryKind); } } else { - address = createOffsetAddress(graph, newObject, tool.getMetaAccess().getArrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind)); + address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind)); barrierType = arrayInitializationBarrier(entryKind); } if (address != null) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Fri Aug 17 13:20:53 2018 -0700 @@ -55,7 +55,7 @@ method.canBeInlined()) { // Test force inlining first - if (method.shouldBeInlined()) { + if (method.shouldBeInlined() && checkInliningDepth(b)) { return createStandardInlineInfo(method); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/JDK9StringSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/JDK9StringSubstitutions.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements; + +import org.graalvm.compiler.api.replacements.ClassSubstitution; +import org.graalvm.compiler.api.replacements.MethodSubstitution; +import org.graalvm.compiler.core.common.SuppressFBWarnings; +import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; +import org.graalvm.compiler.nodes.java.LoadFieldNode; +import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode; + +// JaCoCo Exclude + +/** + * Substitutions for {@link String} methods for JDK9 and later. + * + * {@link String} changed in JDK9 to contain a byte array instead of a char array. We therefore need + * new substitutions for the related methods. + */ +@ClassSubstitution(String.class) +public class JDK9StringSubstitutions { + + @MethodSubstitution(isStatic = false) + @SuppressFBWarnings(value = "ES_COMPARING_PARAMETER_STRING_WITH_EQ", justification = "reference equality on the receiver is what we want") + public static boolean equals(final String thisString, Object obj) { + if (thisString == obj) { + return true; + } + if (!(obj instanceof String)) { + return false; + } + String thatString = (String) obj; + if (thisString.length() != thatString.length()) { + return false; + } + + if (thisString.length() == 0) { + return true; + } + if (getCoder(thisString) != getCoder(thatString)) { + return false; + } + + final byte[] array1 = getValue(thisString); + final byte[] array2 = getValue(thatString); + + return ArrayEqualsNode.equals(array1, array2, array1.length); + } + + /** + * Will be intrinsified with an {@link InvocationPlugin} to a {@link LoadFieldNode}. + */ + public static native byte[] getValue(String s); + + public static native int getCoder(String s); +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Fri Aug 17 13:20:53 2018 -0700 @@ -779,6 +779,9 @@ } protected LoopScope doInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, InlineInfo inlineInfo, ValueNode[] arguments) { + if (!invokeData.invoke.useForInlining()) { + return null; + } ResolvedJavaMethod inlineMethod = inlineInfo.getMethodToInline(); EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, inlineInfo.getOriginalMethod(), inlineInfo.getIntrinsicBytecodeProvider(), graph.trackNodeSourcePosition()); if (graphToInline == null) { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Fri Aug 17 13:20:53 2018 -0700 @@ -49,6 +49,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; +import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.internal.vm.compiler.collections.EconomicMap; import jdk.internal.vm.compiler.collections.EconomicSet; import jdk.internal.vm.compiler.collections.Equivalence; @@ -515,7 +516,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { return ConstantNode.forInt(varargs.length); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Fri Aug 17 13:20:53 2018 -0700 @@ -53,6 +53,10 @@ import org.graalvm.compiler.graph.Edges; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeList; +import org.graalvm.compiler.java.IntegerExactOpSpeculation; +import org.graalvm.compiler.java.IntegerExactOpSpeculation.IntegerExactOp; +import org.graalvm.compiler.nodes.AbstractBeginNode; +import org.graalvm.compiler.nodes.BeginNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.DeoptimizeNode; import org.graalvm.compiler.nodes.EndNode; @@ -87,6 +91,7 @@ import org.graalvm.compiler.nodes.debug.SpillRegistersNode; import org.graalvm.compiler.nodes.extended.BoxNode; import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; +import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind; import org.graalvm.compiler.nodes.extended.GetClassNode; import org.graalvm.compiler.nodes.extended.MembarNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; @@ -113,8 +118,13 @@ import org.graalvm.compiler.replacements.nodes.ReverseBytesNode; import org.graalvm.compiler.replacements.nodes.VirtualizableInvokeMacroNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactSplitNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticSplitNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactSplitNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactSplitNode; import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.vm.ci.code.BytecodePosition; @@ -128,6 +138,7 @@ import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.SpeculationLog.Speculation; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; import sun.misc.Unsafe; /** @@ -161,13 +172,19 @@ } private static final Field STRING_VALUE_FIELD; + private static final Field STRING_CODER_FIELD; static { + Field coder = null; try { STRING_VALUE_FIELD = String.class.getDeclaredField("value"); + if (!Java8OrEarlier) { + coder = String.class.getDeclaredField("coder"); + } } catch (NoSuchFieldException e) { throw new GraalError(e); } + STRING_CODER_FIELD = coder; } private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, SnippetReflectionProvider snippetReflection) { @@ -186,6 +203,7 @@ if (Java8OrEarlier) { r.registerMethodSubstitution(StringSubstitutions.class, "equals", Receiver.class, Object.class); + r.register7("indexOf", char[].class, int.class, int.class, char[].class, int.class, int.class, int.class, new StringIndexOfConstantPlugin()); Registration sr = new Registration(plugins, StringSubstitutions.class); @@ -198,6 +216,34 @@ return true; } }); + } else { + r.registerMethodSubstitution(JDK9StringSubstitutions.class, "equals", Receiver.class, Object.class); + + final Registration latin1r = new Registration(plugins, "java.lang.StringLatin1", bytecodeProvider); + latin1r.register5("indexOf", byte[].class, int.class, byte[].class, int.class, int.class, new StringLatin1IndexOfConstantPlugin()); + + final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider); + utf16r.register5("indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class, new StringUTF16IndexOfConstantPlugin()); + + Registration sr = new Registration(plugins, JDK9StringSubstitutions.class); + sr.register1("getValue", String.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { + ResolvedJavaField field = b.getMetaAccess().lookupJavaField(STRING_VALUE_FIELD); + b.addPush(JavaKind.Object, LoadFieldNode.create(b.getConstantFieldProvider(), b.getConstantReflection(), b.getMetaAccess(), + b.getOptions(), b.getAssumptions(), value, field, false, false)); + return true; + } + }); + sr.register1("getCoder", String.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { + ResolvedJavaField field = b.getMetaAccess().lookupJavaField(STRING_CODER_FIELD); + b.addPush(JavaKind.Int, LoadFieldNode.create(b.getConstantFieldProvider(), b.getConstantReflection(), b.getMetaAccess(), + b.getOptions(), b.getAssumptions(), value, field, false, false)); + return true; + } + }); } } @@ -466,6 +512,59 @@ }); } + private static ValueNode createIntegerExactArithmeticNode(ValueNode x, ValueNode y, SpeculationReason speculation, IntegerExactOp op) { + switch (op) { + case INTEGER_ADD_EXACT: + case INTEGER_INCREMENT_EXACT: + return new IntegerAddExactNode(x, y, speculation); + case INTEGER_SUBTRACT_EXACT: + case INTEGER_DECREMENT_EXACT: + return new IntegerSubExactNode(x, y, speculation); + case INTEGER_MULTIPLY_EXACT: + return new IntegerMulExactNode(x, y, speculation); + default: + throw GraalError.shouldNotReachHere("Unknown integer exact operation."); + } + } + + private static IntegerExactArithmeticSplitNode createIntegerExactSplit(ValueNode x, ValueNode y, AbstractBeginNode exceptionEdge, IntegerExactOp op) { + switch (op) { + case INTEGER_ADD_EXACT: + case INTEGER_INCREMENT_EXACT: + return new IntegerAddExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); + case INTEGER_SUBTRACT_EXACT: + case INTEGER_DECREMENT_EXACT: + return new IntegerSubExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); + case INTEGER_MULTIPLY_EXACT: + return new IntegerMulExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); + default: + throw GraalError.shouldNotReachHere("Unknown integer exact operation."); + } + } + + private static void createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) { + if (b.needsExplicitException()) { + BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW; + AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind); + IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op)); + split.setNext(b.add(new BeginNode())); + } else { + SpeculationLog log = b.getGraph().getSpeculationLog(); + if (log == null || (x.isConstant() && y.isConstant())) { + b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op)); + } else { + SpeculationReason speculation = new IntegerExactOpSpeculation(b.getMethod(), op); + if (log.maySpeculate(speculation)) { + b.addPush(kind, createIntegerExactArithmeticNode(x, y, speculation, op)); + } else { + BeginNode begin = b.add(new BeginNode()); + IntegerExactArithmeticNode node = (IntegerExactArithmeticNode) b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op)); + node.setAnchor(begin); + } + } + } + } + private static void registerMathPlugins(InvocationPlugins plugins, boolean allowDeoptimization) { Registration r = new Registration(plugins, Math.class); if (allowDeoptimization) { @@ -475,7 +574,8 @@ r.register1("decrementExact", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { - b.addPush(kind, new IntegerSubExactNode(x, ConstantNode.forIntegerKind(kind, 1))); + ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT); return true; } }); @@ -483,7 +583,8 @@ r.register1("incrementExact", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { - b.addPush(kind, new IntegerAddExactNode(x, ConstantNode.forIntegerKind(kind, 1))); + ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT); return true; } }); @@ -491,7 +592,7 @@ r.register2("addExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind, new IntegerAddExactNode(x, y)); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT); return true; } }); @@ -499,7 +600,7 @@ r.register2("subtractExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind, new IntegerSubExactNode(x, y)); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT); return true; } }); @@ -507,7 +608,7 @@ r.register2("multiplyExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - b.addPush(kind, new IntegerMulExactNode(x, y)); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT); return true; } }); @@ -555,6 +656,42 @@ } } + public static final class StringLatin1IndexOfConstantPlugin implements InvocationPlugin { + @Override + public boolean inlineOnly() { + return true; + } + + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, + ValueNode source, ValueNode sourceCount, ValueNode target, ValueNode targetCount, ValueNode origFromIndex) { + if (target.isConstant()) { + b.addPush(JavaKind.Int, new StringLatin1IndexOfNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions()), + source, sourceCount, target, targetCount, origFromIndex)); + return true; + } + return false; + } + } + + public static final class StringUTF16IndexOfConstantPlugin implements InvocationPlugin { + @Override + public boolean inlineOnly() { + return true; + } + + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, + ValueNode source, ValueNode sourceCount, ValueNode target, ValueNode targetCount, ValueNode origFromIndex) { + if (target.isConstant()) { + b.addPush(JavaKind.Int, new StringUTF16IndexOfNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions()), + source, sourceCount, target, targetCount, origFromIndex)); + return true; + } + return false; + } + } + public static class UnsignedMathPlugin implements InvocationPlugin { private final Condition condition; diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringLatin1IndexOfNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringLatin1IndexOfNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import org.graalvm.compiler.core.common.type.StampPair; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.replacements.nodes.MacroStateSplitNode; + +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; + +@NodeInfo(size = SIZE_64, cycles = CYCLES_256) +public class StringLatin1IndexOfNode extends MacroStateSplitNode { + public static final NodeClass TYPE = NodeClass.create(StringLatin1IndexOfNode.class); + + public StringLatin1IndexOfNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, int bci, StampPair returnStamp, ValueNode... arguments) { + super(TYPE, invokeKind, targetMethod, bci, returnStamp, arguments); + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringUTF16IndexOfNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringUTF16IndexOfNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.replacements; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import org.graalvm.compiler.core.common.type.StampPair; +import org.graalvm.compiler.graph.NodeClass; +import org.graalvm.compiler.nodeinfo.NodeInfo; +import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; +import org.graalvm.compiler.nodes.ValueNode; +import org.graalvm.compiler.nodes.spi.LoweringTool; +import org.graalvm.compiler.replacements.nodes.MacroStateSplitNode; + +import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_256; +import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64; + +@NodeInfo(size = SIZE_64, cycles = CYCLES_256) +public class StringUTF16IndexOfNode extends MacroStateSplitNode { + public static final NodeClass TYPE = NodeClass.create(StringUTF16IndexOfNode.class); + + public StringUTF16IndexOfNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, int bci, StampPair returnStamp, ValueNode... arguments) { + super(TYPE, invokeKind, targetMethod, bci, returnStamp, arguments); + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -190,7 +190,7 @@ } @NodeIntrinsic - public static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind); + static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter JavaKind kind); public static boolean equals(boolean[] array1, boolean[] array2, int length) { return equals(array1, array2, length, JavaKind.Boolean); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/BasicObjectCloneNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -36,18 +36,23 @@ import org.graalvm.compiler.nodeinfo.NodeCycles; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind; +import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.java.LoadFieldNode; +import org.graalvm.compiler.nodes.java.LoadIndexedNode; import org.graalvm.compiler.nodes.java.MonitorIdNode; import org.graalvm.compiler.nodes.spi.ArrayLengthProvider; import org.graalvm.compiler.nodes.spi.VirtualizableAllocation; import org.graalvm.compiler.nodes.spi.VirtualizerTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.nodes.virtual.VirtualArrayNode; import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; import jdk.vm.ci.meta.Assumptions; +import jdk.vm.ci.meta.ConstantReflectionProvider; +import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; @@ -104,6 +109,10 @@ return LoadFieldNode.create(assumptions, originalAlias, field); } + protected LoadIndexedNode genLoadIndexedNode(Assumptions assumptions, ValueNode originalAlias, ValueNode index, JavaKind elementKind) { + return new LoadIndexedNode(assumptions, originalAlias, index, null, elementKind); + } + @Override public void virtualize(VirtualizerTool tool) { ValueNode originalAlias = tool.getAlias(getObject()); @@ -120,18 +129,45 @@ } } else { ResolvedJavaType type = getConcreteType(originalAlias.stamp(NodeView.DEFAULT)); - if (type != null && !type.isArray()) { + if (type == null) { + return; + } + if (!type.isArray()) { VirtualInstanceNode newVirtual = createVirtualInstanceNode(type, true); ResolvedJavaField[] fields = newVirtual.getFields(); ValueNode[] state = new ValueNode[fields.length]; - final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; for (int i = 0; i < fields.length; i++) { - state[i] = loads[i] = genLoadFieldNode(graph().getAssumptions(), originalAlias, fields[i]); - tool.addNode(loads[i]); + LoadFieldNode load = genLoadFieldNode(graph().getAssumptions(), originalAlias, fields[i]); + state[i] = load; + tool.addNode(load); } tool.createVirtualObject(newVirtual, state, Collections. emptyList(), false); tool.replaceWithVirtual(newVirtual); + } else { + ValueNode length = findLength(FindLengthMode.SEARCH_ONLY, tool.getConstantReflectionProvider()); + if (length == null) { + return; + } + ValueNode lengthAlias = tool.getAlias(length); + if (!lengthAlias.isConstant()) { + return; + } + int constantLength = lengthAlias.asJavaConstant().asInt(); + if (constantLength >= 0 && constantLength < tool.getMaximumEntryCount()) { + ValueNode[] state = new ValueNode[constantLength]; + ResolvedJavaType componentType = type.getComponentType(); + for (int i = 0; i < constantLength; i++) { + ConstantNode index = ConstantNode.forInt(i); + LoadIndexedNode load = genLoadIndexedNode(graph().getAssumptions(), originalAlias, index, componentType.getJavaKind()); + state[i] = load; + tool.addNode(index); + tool.addNode(load); + } + VirtualObjectNode virtualObject = new VirtualArrayNode(componentType, constantLength); + tool.createVirtualObject(virtualObject, state, Collections. emptyList(), false); + tool.replaceWithVirtual(virtualObject); + } } } } @@ -141,7 +177,7 @@ } @Override - public ValueNode findLength(ArrayLengthProvider.FindLengthMode mode) { - return GraphUtil.arrayLength(getObject(), mode); + public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) { + return GraphUtil.arrayLength(getObject(), mode, constantReflection); } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerAddExactNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -35,17 +35,20 @@ import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.calc.AddNode; +import org.graalvm.compiler.nodes.extended.AnchoringNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import jdk.vm.ci.code.CodeUtil; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; /** * Node representing an exact integer addition that will throw an {@link ArithmeticException} in @@ -55,10 +58,14 @@ public final class IntegerAddExactNode extends AddNode implements IntegerExactArithmeticNode { public static final NodeClass TYPE = NodeClass.create(IntegerAddExactNode.class); - public IntegerAddExactNode(ValueNode x, ValueNode y) { + @OptionalInput(InputType.Anchor) protected AnchoringNode anchor; + protected final SpeculationReason speculation; + + public IntegerAddExactNode(ValueNode x, ValueNode y, SpeculationReason speculation) { super(TYPE, x, y); setStamp(x.stamp(NodeView.DEFAULT).unrestricted()); assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp; + this.speculation = speculation; } @Override @@ -122,7 +129,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (forX.isConstant() && !forY.isConstant()) { - return new IntegerAddExactNode(forY, forX).canonical(tool); + return new IntegerAddExactNode(forY, forX, speculation).canonical(tool); } if (forX.isConstant()) { ConstantNode constantNode = canonicalXconstant(forX, forY); @@ -166,6 +173,22 @@ } @Override + public SpeculationReason getSpeculation() { + return speculation; + } + + @Override + public AnchoringNode getAnchor() { + return anchor; + } + + @Override + public void setAnchor(AnchoringNode x) { + updateUsagesInterface(this.anchor, x); + this.anchor = x; + } + + @Override public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -25,9 +25,19 @@ package org.graalvm.compiler.replacements.nodes.arithmetic; import org.graalvm.compiler.nodes.AbstractBeginNode; +import org.graalvm.compiler.nodes.extended.AnchoringNode; import org.graalvm.compiler.nodes.spi.Lowerable; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; + public interface IntegerExactArithmeticNode extends Lowerable { IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt); + + SpeculationReason getSpeculation(); + + AnchoringNode getAnchor(); + + void setAnchor(AnchoringNode x); + } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,7 @@ import jdk.vm.ci.meta.DeoptimizationAction; import jdk.vm.ci.meta.DeoptimizationReason; +import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.Value; @NodeInfo(cycles = CYCLES_2, cyclesRationale = "add+cmp", size = SIZE_2) @@ -90,6 +91,16 @@ return overflowSuccessor; } + public void setNext(AbstractBeginNode next) { + updatePredecessor(this.next, next); + this.next = next; + } + + public void setOverflowSuccessor(AbstractBeginNode overflowSuccessor) { + updatePredecessor(this.overflowSuccessor, overflowSuccessor); + this.overflowSuccessor = overflowSuccessor; + } + public ValueNode getX() { return x; } @@ -112,8 +123,10 @@ FixedWithNextNode previous = tool.lastFixedNode(); FixedNode next = previous.next(); previous.setNext(null); - DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException)); - AbstractBeginNode normalBegin = floatingNode.graph().add(new BeginNode()); + StructuredGraph graph = floatingNode.graph(); + DeoptimizeNode deopt = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException, + node.getSpeculation() == null ? SpeculationLog.NO_SPECULATION : graph.getSpeculationLog().speculate(node.getSpeculation()))); + AbstractBeginNode normalBegin = graph.add(new BeginNode()); normalBegin.setNext(next); IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt)); previous.setNext(split); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerMulExactNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -30,16 +30,19 @@ import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.calc.MulNode; +import org.graalvm.compiler.nodes.extended.AnchoringNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; /** * Node representing an exact integer multiplication that will throw an {@link ArithmeticException} @@ -49,10 +52,14 @@ public final class IntegerMulExactNode extends MulNode implements IntegerExactArithmeticNode { public static final NodeClass TYPE = NodeClass.create(IntegerMulExactNode.class); - public IntegerMulExactNode(ValueNode x, ValueNode y) { + @OptionalInput(InputType.Anchor) protected AnchoringNode anchor; + protected final SpeculationReason speculation; + + public IntegerMulExactNode(ValueNode x, ValueNode y, SpeculationReason speculation) { super(TYPE, x, y); setStamp(x.stamp(NodeView.DEFAULT).unrestricted()); assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp; + this.speculation = speculation; } @Override @@ -69,7 +76,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) { if (forX.isConstant() && !forY.isConstant()) { - return new IntegerMulExactNode(forY, forX).canonical(tool); + return new IntegerMulExactNode(forY, forX, speculation).canonical(tool); } if (forX.isConstant()) { return canonicalXconstant(forX, forY); @@ -111,6 +118,22 @@ } @Override + public SpeculationReason getSpeculation() { + return speculation; + } + + @Override + public AnchoringNode getAnchor() { + return anchor; + } + + @Override + public void setAnchor(AnchoringNode x) { + updateUsagesInterface(this.anchor, x); + this.anchor = x; + } + + @Override public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/IntegerSubExactNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -30,17 +30,20 @@ import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.spi.CanonicalizerTool; +import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.ConstantNode; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.calc.SubNode; +import org.graalvm.compiler.nodes.extended.AnchoringNode; import org.graalvm.compiler.nodes.spi.LoweringTool; import org.graalvm.compiler.nodes.util.GraphUtil; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; /** * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in @@ -50,10 +53,14 @@ public final class IntegerSubExactNode extends SubNode implements IntegerExactArithmeticNode { public static final NodeClass TYPE = NodeClass.create(IntegerSubExactNode.class); - public IntegerSubExactNode(ValueNode x, ValueNode y) { + @OptionalInput(InputType.Anchor) protected AnchoringNode anchor; + protected final SpeculationReason speculation; + + public IntegerSubExactNode(ValueNode x, ValueNode y, SpeculationReason speculation) { super(TYPE, x, y); setStamp(x.stamp(NodeView.DEFAULT).unrestricted()); assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT)) && x.stamp(NodeView.DEFAULT) instanceof IntegerStamp; + this.speculation = speculation; } @Override @@ -109,6 +116,22 @@ } @Override + public SpeculationReason getSpeculation() { + return speculation; + } + + @Override + public AnchoringNode getAnchor() { + return anchor; + } + + @Override + public void setAnchor(AnchoringNode x) { + updateUsagesInterface(this.anchor, x); + this.anchor = x; + } + + @Override public void lower(LoweringTool tool) { IntegerExactArithmeticSplitNode.lower(tool, this); } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java Fri Aug 17 13:20:53 2018 -0700 @@ -206,27 +206,6 @@ } /** - * Access to thread specific information made available via Java Management Extensions (JMX). - * Using this abstraction enables avoiding a dependency to the {@code java.management} and - * {@code jdk.management} modules on JDK 9 and later. - */ - public abstract static class JMXService { - protected abstract long getThreadAllocatedBytes(long id); - - protected abstract long getCurrentThreadCpuTime(); - - protected abstract boolean isThreadAllocatedMemorySupported(); - - protected abstract boolean isCurrentThreadCpuTimeSupported(); - - protected abstract List getInputArguments(); - - // Placing this static field in JMXService (instead of GraalServices) - // allows for lazy initialization. - static final JMXService instance = loadSingle(JMXService.class, false); - } - - /** * Returns an approximation of the total amount of memory, in bytes, allocated in heap memory * for the thread of the specified ID. The returned value is an approximation because some Java * virtual machine implementations may use object allocation mechanisms that result in a delay diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JMXService.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JMXService.java Fri Aug 17 13:20:53 2018 -0700 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 org.graalvm.compiler.serviceprovider; + +import java.util.List; + +/* This class lives in the "base" project even if it is only useful for JDK9 + * because javac only links against classes from the "base". + */ + +/** + * Access to thread specific information made available via Java Management Extensions (JMX). Using + * this abstraction enables avoiding a dependency to the {@code java.management} and + * {@code jdk.management} modules on JDK 9 and later. + */ +public abstract class JMXService { + protected abstract long getThreadAllocatedBytes(long id); + + protected abstract long getCurrentThreadCpuTime(); + + protected abstract boolean isThreadAllocatedMemorySupported(); + + protected abstract boolean isCurrentThreadCpuTimeSupported(); + + protected abstract List getInputArguments(); + + // Placing this static field in JMXService (instead of GraalServices) + // allows for lazy initialization. + static final JMXService instance = GraalServices.loadSingle(JMXService.class, false); +} diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java Fri Aug 17 13:20:53 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.concurrent.TimeUnit; import java.util.List; import org.graalvm.compiler.debug.DebugContext; @@ -47,6 +48,9 @@ import org.junit.Assert; import org.junit.internal.ComparisonCriteria; import org.junit.internal.ExactComparisonCriteria; +import org.junit.rules.DisableOnDebug; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; import jdk.vm.ci.meta.ResolvedJavaMethod; import sun.misc.Unsafe; @@ -453,4 +457,35 @@ } } } + + private static final double TIMEOUT_SCALING_FACTOR = Double.parseDouble(System.getProperty("graaltest.timeout.factor", "1.0")); + + /** + * Creates a {@link TestRule} that applies a given timeout. + * + * A test harness can scale {@code length} with a factor specified by the + * {@code graaltest.timeout.factor} system property. + */ + public static TestRule createTimeout(long length, TimeUnit timeUnit) { + Timeout timeout = new Timeout((long) (length * TIMEOUT_SCALING_FACTOR), timeUnit); + try { + return new DisableOnDebug(timeout); + } catch (LinkageError ex) { + return timeout; + } + } + + /** + * @see #createTimeout + */ + public static TestRule createTimeoutSeconds(int seconds) { + return createTimeout(seconds, TimeUnit.SECONDS); + } + + /** + * @see #createTimeout + */ + public static TestRule createTimeoutMillis(long milliseconds) { + return createTimeout(milliseconds, TimeUnit.MILLISECONDS); + } } diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Fri Aug 17 13:20:53 2018 -0700 @@ -115,22 +115,18 @@ /* * If there is a mismatch between the number of materializations and the number of * virtualizations, we need to apply effects, even if there were no other significant - * changes to the graph. + * changes to the graph. This applies to each block, since moving from one block to the + * other can also be important (if the probabilities of the block differ). */ - int delta = 0; for (Block block : cfg.getBlocks()) { GraphEffectList effects = blockEffects.get(block); if (effects != null) { - delta += effects.getVirtualizationDelta(); + if (effects.getVirtualizationDelta() != 0) { + return true; + } } } - for (Loop loop : cfg.getLoops()) { - GraphEffectList effects = loopMergeEffects.get(loop); - if (effects != null) { - delta += effects.getVirtualizationDelta(); - } - } - return delta != 0; + return false; } private final class CollectVirtualObjectsClosure extends NodeClosure { diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/WordCastNode.java Fri Aug 17 13:20:53 2018 -0700 @@ -28,6 +28,7 @@ import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1; import org.graalvm.compiler.core.common.LIRKind; +import org.graalvm.compiler.core.common.type.AbstractObjectStamp; import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.ObjectStamp; @@ -45,6 +46,7 @@ import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; +import org.graalvm.compiler.nodes.type.NarrowOopStamp; import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.JavaConstant; @@ -76,6 +78,10 @@ return new WordCastNode(StampFactory.objectNonNull(), input); } + public static WordCastNode wordToNarrowObject(ValueNode input, NarrowOopStamp stamp) { + return new WordCastNode(stamp, input); + } + public static WordCastNode addressToWord(ValueNode input, JavaKind wordKind) { assert input.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp; return new WordCastNode(StampFactory.forKind(wordKind), input); @@ -91,6 +97,11 @@ return new WordCastNode(StampFactory.forKind(wordKind), input, false); } + public static WordCastNode narrowOopToUntrackedWord(ValueNode input, JavaKind wordKind) { + assert input.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp; + return new WordCastNode(StampFactory.forKind(wordKind), input, false); + } + private WordCastNode(Stamp stamp, ValueNode input) { this(stamp, input, true); } @@ -172,7 +183,7 @@ AllocatableValue result = generator.getLIRGeneratorTool().newVariable(kind); if (stamp.equals(StampFactory.object())) { generator.getLIRGeneratorTool().emitConvertZeroToNull(result, value); - } else if (!trackedPointer && !((ObjectStamp) input.stamp(NodeView.DEFAULT)).nonNull()) { + } else if (!trackedPointer && !((AbstractObjectStamp) input.stamp(NodeView.DEFAULT)).nonNull()) { generator.getLIRGeneratorTool().emitConvertNullToZero(result, value); } else { generator.getLIRGeneratorTool().emitMove(result, value); diff -r 72c82bd05971 -r 091c0d22e735 src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java Fri Aug 17 11:56:59 2018 -0500 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java Fri Aug 17 13:20:53 2018 -0700 @@ -41,10 +41,21 @@ @State(Scope.Benchmark) public static class BenchState { char ch1 = 'Q'; + String ch1string = "Q"; char ch2 = 'X'; String s1 = "Qu"; String s2 = "ne"; + String longString; + + public BenchState() { + String str = "ab"; + for (int i = 0; i < 15; i++) { + str = str + str; + } + longString = str + "xx"; + } + // Checkstyle: stop String lorem = "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; String loremLastChar = "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum?"; @@ -59,6 +70,18 @@ @Benchmark @Warmup(iterations = 5) + public int indexOfSingleCharString(BenchState state) { + return state.lorem.indexOf(state.ch1string); + } + + @Benchmark + @Warmup(iterations = 5) + public int indexOfSingleCharStringLong(BenchState state) { + return state.longString.indexOf('x'); + } + + @Benchmark + @Warmup(iterations = 5) public int indexOfCharNotFound(BenchState state) { return state.lorem.indexOf(state.ch2); }