# HG changeset patch # User Christian Haeubl # Date 1355486569 -3600 # Node ID 8a3efb8c831d022c0405763400e8ed8a4efdb21b # Parent 31c4d9f9e9221c7adb95264f9911cb7cf7df5a81# Parent 2ed8d74e5984fc7796e9164206aa31f8f7925292 Merge. diff -r 31c4d9f9e922 -r 8a3efb8c831d README_GRAAL.txt --- a/README_GRAAL.txt Fri Dec 14 12:05:35 2012 +0100 +++ b/README_GRAAL.txt Fri Dec 14 13:02:49 2012 +0100 @@ -9,7 +9,7 @@ Building both the Java and C++ source code comprising the Graal VM can be done with the following simple command. - mx build +% mx build This builds the 'product' version of HotSpot with the Graal modifications. To build the debug or fastdebug versions: @@ -22,16 +22,49 @@ To run the VM, use 'mx vm' in place of the standard 'java' command: - mx vm ... +% mx vm ... To select the fastdebug or debug versions of the VM: - mx --fastdebug vm ... - mx --debug vm ... +% mx --fastdebug vm ... +% mx --debug vm ... Graal has an optional bootstrap step where it compiles itself before compiling any application code. This bootstrap step currently takes about 7 seconds on a fast x64 machine. It's useful to disable this bootstrap step when running small programs with the -XX:-BootstrapGraal options. For example: - mx vm -XX:-BootstrapGraal ... +% mx vm -XX:-BootstrapGraal ... + + +Other Build Configurations +-------------------------- + +By default the build commands above create a HotSpot binary where the Graal +is the only compiler. This binary is the Graal VM binary and identifies as +such with the -version option: + +% mx vm -XX:-BootstrapGraal -version +java version "1.7.0_07" +Java(TM) SE Runtime Environment (build 1.7.0_07-b10) +OpenJDK 64-Bit Graal VM (build 25.0-b10-internal, mixed mode) + +It's also possible to build and execute the standard HotSpot binaries +using the --vm option: + +% mx --vm server build +% mx --vm server vm -version +java version "1.7.0_07" +Java(TM) SE Runtime Environment (build 1.7.0_07-b10) +OpenJDK 64-Bit Server VM (build 25.0-b10-internal, mixed mode) + +These standard binaries still include the code necessary to support use of the +Graal compiler for explicit compilation requests. However, in this configuration +the Graal compiler will not service VM issued compilation requests (e.g., upon +counter overflow in the interpreter). + +To build a HotSpot binary that completely omits all VM support for Graal, +define an environment variable OMIT_GRAAL (its value does not matter) and build +with the --vm option as above (doing a clean first if necessary): + +% env OMIT_GRAAL= mx --vm server build diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Dec 14 13:02:49 2012 +0100 @@ -298,16 +298,29 @@ } } - InstalledCode installedCode = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(compilationId++), true), new Callable() { + + final int id = compilationId++; + + InstalledCode installedCode = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable() { public InstalledCode call() throws Exception { + final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed(); + if (printCompilation) { + TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature())); + } + long start = System.currentTimeMillis(); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); CompilationResult compResult = graalCompiler.compileMethod(method, graph, null, phasePlan, OptimisticOptimizations.ALL); + if (printCompilation) { + TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); + } return addMethod(method, compResult); } }); + + cache.put(method, installedCode); return installedCode; } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Dec 14 13:02:49 2012 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; @@ -212,13 +213,16 @@ // detects this case - see the definition of frame::should_be_deoptimized() Register scratch = regConfig.getScratchRegister(); + int offset = SafepointPollOffset % target.pageSize; if (config.isPollingPageFar) { - asm.movq(scratch, config.safepointPollingAddress); + asm.movq(scratch, config.safepointPollingAddress + offset); tasm.recordMark(Marks.MARK_POLL_RETURN_FAR); asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); } else { tasm.recordMark(Marks.MARK_POLL_RETURN_NEAR); - asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); + // The C++ code transforms the polling page offset into an RIP displacement + // to the real address at that offset in the polling page. + asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue(), offset)); } } } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Dec 14 13:02:49 2012 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; @@ -51,15 +52,18 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { Register scratch = tasm.frameMap.registerConfig.getScratchRegister(); int pos = asm.codeBuffer.position(); + int offset = SafepointPollOffset % tasm.target.pageSize; if (config.isPollingPageFar) { - asm.movq(scratch, config.safepointPollingAddress); + asm.movq(scratch, config.safepointPollingAddress + offset); tasm.recordMark(Marks.MARK_POLL_FAR); tasm.recordSafepoint(pos, state); asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); } else { tasm.recordMark(Marks.MARK_POLL_NEAR); tasm.recordSafepoint(pos, state); - asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); + // The C++ code transforms the polling page offset into an RIP displacement + // to the real address at that offset in the polling page. + asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue(), offset)); } } } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Dec 14 13:02:49 2012 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.graph.FieldIntrospection.*; import java.lang.reflect.*; +import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.interpreter.*; @@ -61,6 +62,29 @@ protected static void setInstance(HotSpotGraalRuntime runtime) { assert instance == null : "runtime already registered"; instance = runtime; + + // Do deferred initialization + + // Proxies for the VM/Compiler interfaces cannot be initialized + // in the constructor as proxy creation causes static + // initializers to be executed for all the types involved in the + // proxied methods. Some of these static initializers (e.g. in + // HotSpotMethodData) rely on the above instance field being set + // to retrieve config details. + VMToCompiler toCompiler = runtime.vmToCompiler; + CompilerToVM toVM = runtime.compilerToVm; + + if (CountingProxy.ENABLED) { + toCompiler = CountingProxy.getProxy(VMToCompiler.class, toCompiler); + toVM = CountingProxy.getProxy(CompilerToVM.class, toVM); + } + if (Logger.ENABLED) { + toCompiler = LoggingProxy.getProxy(VMToCompiler.class, toCompiler); + toVM = LoggingProxy.getProxy(CompilerToVM.class, toVM); + } + + runtime.vmToCompiler = toCompiler; + runtime.compilerToVm = toVM; } private static Kind wordKind; @@ -83,8 +107,8 @@ return unsafe.getInt(address); } - protected final CompilerToVM compilerToVm; - protected final VMToCompiler vmToCompiler; + protected /*final*/ CompilerToVM compilerToVm; + protected /*final*/ VMToCompiler vmToCompiler; protected final HotSpotRuntime runtime; protected final GraalCompiler compiler; @@ -101,17 +125,6 @@ // initialize VmToCompiler VMToCompiler toCompiler = new VMToCompilerImpl(this); - // logging, etc. - if (CountingProxy.ENABLED) { - toCompiler = CountingProxy.getProxy(VMToCompiler.class, toCompiler); - toVM = CountingProxy.getProxy(CompilerToVM.class, toVM); - } - if (Logger.ENABLED) { - toCompiler = LoggingProxy.getProxy(VMToCompiler.class, toCompiler); - toVM = LoggingProxy.getProxy(CompilerToVM.class, toVM); - } - - // set the final fields compilerToVm = toVM; vmToCompiler = toCompiler; config = new HotSpotVMConfig(); @@ -138,8 +151,12 @@ private static void printConfig(HotSpotVMConfig config) { Field[] fields = config.getClass().getDeclaredFields(); + Map sortedFields = new TreeMap<>(); for (Field f : fields) { f.setAccessible(true); + sortedFields.put(f.getName(), f); + } + for (Field f : sortedFields.values()) { try { Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), Logger.pretty(f.get(config)))); } catch (Exception e) { diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Dec 14 13:02:49 2012 +0100 @@ -38,8 +38,6 @@ public int codeEntryAlignment; public boolean verifyOops; public boolean useFastLocking; - public boolean useFastNewObjectArray; - public boolean useFastNewTypeArray; public boolean useTLAB; public boolean useBiasedLocking; @@ -328,8 +326,28 @@ public long logPrimitiveStub; public long logObjectStub; public long logPrintfStub; + public int deoptReasonNone; public long threadIsInterruptedStub; public long identityHashCodeStub; + + public int deoptReasonNullCheck; + public int deoptReasonRangeCheck; + public int deoptReasonClassCheck; + public int deoptReasonArrayCheck; + public int deoptReasonUnreached0; + public int deoptReasonTypeCheckInlining; + public int deoptReasonOptimizedTypeCheck; + public int deoptReasonNotCompiledExceptionHandler; + public int deoptReasonUnresolved; + public int deoptReasonJsrMismatch; + public int deoptReasonDiv0Check; + public int deoptReasonConstraint; + + public int deoptActionNone; + public int deoptActionMaybeRecompile; + public int deoptActionReinterpret; + public int deoptActionMakeNotEntrant; + public int deoptActionMakeNotCompilable; public void check() { assert vmPageSize >= 16; diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Fri Dec 14 13:02:49 2012 +0100 @@ -82,7 +82,7 @@ public int getDeoptimizationCount(DeoptimizationReason reason) { int reasonIndex = HotSpotGraalRuntime.getInstance().getRuntime().convertDeoptReason(reason); - return unsafe.getByte(null, metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; + return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; } public HotSpotMethodDataAccessor getNormalData(int position) { @@ -119,17 +119,17 @@ private int readUnsignedByte(int position, int offsetInBytes) { long fullOffsetInBytes = computeFullOffset(position, offsetInBytes); - return unsafe.getByte(null, metaspaceMethodData + fullOffsetInBytes) & 0xFF; + return unsafe.getByte(metaspaceMethodData + fullOffsetInBytes) & 0xFF; } private int readUnsignedShort(int position, int offsetInBytes) { long fullOffsetInBytes = computeFullOffset(position, offsetInBytes); - return unsafe.getShort(null, metaspaceMethodData + fullOffsetInBytes) & 0xFFFF; + return unsafe.getShort(metaspaceMethodData + fullOffsetInBytes) & 0xFFFF; } private long readUnsignedInt(int position, int offsetInBytes) { long fullOffsetInBytes = computeFullOffset(position, offsetInBytes); - return unsafe.getInt(null, metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL; + return unsafe.getInt(metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL; } private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) { @@ -139,7 +139,7 @@ private int readInt(int position, int offsetInBytes) { long fullOffsetInBytes = computeFullOffset(position, offsetInBytes); - return unsafe.getInt(null, metaspaceMethodData + fullOffsetInBytes); + return unsafe.getInt(metaspaceMethodData + fullOffsetInBytes); } private long readWord(int position, int offsetInBytes) { @@ -164,6 +164,9 @@ } private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor { + /** + * Corresponds to DS_RECOMPILE_BIT defined in deoptimization.cpp. + */ private static final int EXCEPTIONS_MASK = 0x80; private final int tag; @@ -323,9 +326,10 @@ private abstract static class AbstractTypeData extends CounterData { private static final int RECEIVER_TYPE_DATA_ROW_SIZE = cellsToBytes(2); - private static final int RECEIVER_TYPE_DATA_SIZE = cellIndexToOffset(1) + RECEIVER_TYPE_DATA_ROW_SIZE * config.typeProfileWidth; - private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = cellIndexToOffset(1); - private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = cellIndexToOffset(2); + private static final int RECEIVER_TYPE_DATA_SIZE = cellIndexToOffset(2) + RECEIVER_TYPE_DATA_ROW_SIZE * config.typeProfileWidth; + protected static final int NONPROFILED_RECEIVER_COUNT_OFFSET = cellIndexToOffset(1); + private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = cellIndexToOffset(2); + private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = cellIndexToOffset(3); protected AbstractTypeData(int tag) { super(tag, RECEIVER_TYPE_DATA_SIZE); @@ -356,11 +360,7 @@ return createTypeProfile(types, counts, totalCount, entries); } - protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { - // checkcast/aastore/instanceof profiling in the HotSpot template-based interpreter was adjusted so that the counter - // is incremented to indicate the polymorphic case instead of decrementing it for failed type checks - return getCounterValue(data, position); - } + protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position); private static JavaTypeProfile createTypeProfile(ResolvedJavaType[] types, long[] counts, long totalCount, int entries) { if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) { @@ -402,6 +402,11 @@ public int getExecutionCount(HotSpotMethodData data, int position) { return -1; } + + @Override + protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { + return data.readUnsignedIntAsSignedInt(position, NONPROFILED_RECEIVER_COUNT_OFFSET); + } } private static class VirtualCallData extends AbstractTypeData { @@ -423,6 +428,11 @@ total += getCounterValue(data, position); return truncateLongToInt(total); } + + @Override + protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) { + return getCounterValue(data, position); + } } private static class RetData extends CounterData { diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Dec 14 13:02:49 2012 +0100 @@ -74,7 +74,7 @@ @Override public int getModifiers() { HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - return unsafe.getInt(null, metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers(); + return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers(); } @Override @@ -129,13 +129,13 @@ @Override public int getMaxLocals() { HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - return unsafe.getShort(null, metaspaceMethod + config.methodMaxLocalsOffset) & 0xFFFF; + return unsafe.getShort(metaspaceMethod + config.methodMaxLocalsOffset) & 0xFFFF; } @Override public int getMaxStackSize() { HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - return config.extraStackEntries + (unsafe.getShort(null, metaspaceMethod + config.methodMaxStackOffset) & 0xFFFF); + return config.extraStackEntries + (unsafe.getShort(metaspaceMethod + config.methodMaxStackOffset) & 0xFFFF); } @Override diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Dec 14 13:02:49 2012 +0100 @@ -144,7 +144,7 @@ public int getAccessFlags() { HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - return unsafe.getInt(null, metaspaceKlass + config.klassAccessFlagsOffset); + return unsafe.getInt(metaspaceKlass + config.klassAccessFlagsOffset); } @Override @@ -468,7 +468,7 @@ public int superCheckOffset() { HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); - return unsafe.getInt(null, metaspaceKlass + config.superCheckOffsetOffset); + return unsafe.getInt(metaspaceKlass + config.superCheckOffsetOffset); } public long prototypeMarkWord() { diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Dec 14 13:02:49 2012 +0100 @@ -713,11 +713,6 @@ return guard; } - @Override - public StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List parameters) { - return null; - } - private static SafeReadNode safeRead(Graph graph, Kind kind, ValueNode value, int offset, Stamp stamp, long leafGraphId) { return graph.add(new SafeReadNode(value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph), stamp, leafGraphId)); } @@ -805,33 +800,31 @@ } public int convertDeoptAction(DeoptimizationAction action) { - // This must be kept in sync with the DeoptAction enum defined in deoptimization.hpp switch(action) { - case None: return 0; - case RecompileIfTooManyDeopts: return 1; - case InvalidateReprofile: return 2; - case InvalidateRecompile: return 3; - case InvalidateStopCompiling: return 4; + case None: return config.deoptActionNone; + case RecompileIfTooManyDeopts: return config.deoptActionMaybeRecompile; + case InvalidateReprofile: return config.deoptActionReinterpret; + case InvalidateRecompile: return config.deoptActionMakeNotEntrant; + case InvalidateStopCompiling: return config.deoptActionMakeNotCompilable; default: throw GraalInternalError.shouldNotReachHere(); } } public int convertDeoptReason(DeoptimizationReason reason) { - // This must be kept in sync with the DeoptReason enum defined in deoptimization.hpp switch(reason) { - case None: return 0; - case NullCheckException: return 1; - case BoundsCheckException: return 2; - case ClassCastException: return 3; - case ArrayStoreException: return 4; - case UnreachedCode: return 5; - case TypeCheckedInliningViolated: return 6; - case OptimizedTypeCheckViolated: return 7; - case NotCompiledExceptionHandler: return 8; - case Unresolved: return 9; - case JavaSubroutineMismatch: return 10; - case ArithmeticException: return 11; - case RuntimeConstraint: return 12; + case None: return config.deoptReasonNone; + case NullCheckException: return config.deoptReasonNullCheck; + case BoundsCheckException: return config.deoptReasonRangeCheck; + case ClassCastException: return config.deoptReasonClassCheck; + case ArrayStoreException: return config.deoptReasonArrayCheck; + case UnreachedCode: return config.deoptReasonUnreached0; + case TypeCheckedInliningViolated: return config.deoptReasonTypeCheckInlining; + case OptimizedTypeCheckViolated: return config.deoptReasonOptimizedTypeCheck; + case NotCompiledExceptionHandler: return config.deoptReasonNotCompiledExceptionHandler; + case Unresolved: return config.deoptReasonUnresolved; + case JavaSubroutineMismatch: return config.deoptReasonJsrMismatch; + case ArithmeticException: return config.deoptReasonDiv0Check; + case RuntimeConstraint: return config.deoptReasonConstraint; default: throw GraalInternalError.shouldNotReachHere(); } } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Fri Dec 14 13:02:49 2012 +0100 @@ -29,21 +29,22 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +/** + * A node that loads the {@link Thread} object for the current thread. + */ public final class CurrentThread extends FloatingNode implements LIRLowerable { - private int threadObjectOffset; - - public CurrentThread(int threadObjectOffset) { + public CurrentThread() { super(StampFactory.declaredNonNull(HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(Thread.class))); - this.threadObjectOffset = threadObjectOffset; } @Override public void generate(LIRGeneratorTool gen) { - Register thread = HotSpotGraalRuntime.getInstance().getRuntime().threadRegister(); - gen.setResult(this, gen.emitLoad(new Address(Kind.Object, thread.asValue(gen.target().wordKind), threadObjectOffset), false)); + HotSpotGraalRuntime runtime = HotSpotGraalRuntime.getInstance(); + Register thread = runtime.getRuntime().threadRegister(); + gen.setResult(this, gen.emitLoad(new Address(Kind.Object, thread.asValue(gen.target().wordKind), runtime.getConfig().threadObjectOffset), false)); } @NodeIntrinsic - public static native Thread get(@ConstantNodeParameter int threadObjectOffset); + public static native Thread get(); } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ClassSnippets.java Fri Dec 14 13:02:49 2012 +0100 @@ -28,12 +28,16 @@ import com.oracle.graal.snippets.*; +/** + * Snippets for {@link java.lang.Class} methods. + */ @ClassSubstitution(java.lang.Class.class) public class ClassSnippets implements SnippetsInterface { @InstanceMethodSubstitution public static int getModifiers(final Class thisObj) { Word klass = loadWordFromObject(thisObj, klassOffset()); if (klass == Word.zero()) { + // Class for primitive type return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; } else { return loadIntFromWord(klass, klassModifierFlagsOffset()); diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Fri Dec 14 13:02:49 2012 +0100 @@ -317,6 +317,10 @@ return loadWordFromObjectIntrinsic(object, 0, offset, wordKind()); } + public static Object readFinalObject(Word base, @ConstantNodeParameter int displacement) { + return ReadNode.read(base, displacement, LocationNode.FINAL_LOCATION, Kind.Object); + } + @NodeIntrinsic(value = RegisterNode.class, setStampFromReturnType = true) public static native Word registerAsWord(@ConstantNodeParameter Register register); @@ -329,6 +333,7 @@ @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true) static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word); + @Fold public static int log2WordSize() { @@ -343,6 +348,24 @@ @Fold public + static int klassModifierFlagsOffset() { + return config().klassModifierFlagsOffset; + } + + @Fold + public + static int klassOffset() { + return config().klassOffset; + } + + @Fold + public + static int classMirrorOffset() { + return config().classMirrorOffset; + } + + @Fold + public static int klassInstanceSizeOffset() { return config().klassInstanceSizeOffset; } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ObjectSnippets.java Fri Dec 14 13:02:49 2012 +0100 @@ -26,13 +26,17 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; +/** + * Snippets for {@link java.lang.Object} methods. + */ @ClassSubstitution(java.lang.Object.class) public class ObjectSnippets implements SnippetsInterface { @InstanceMethodSubstitution("getClass") public static Class getClassSnippet(final Object thisObj) { Word hub = loadHub(thisObj); - return (Class) loadObjectFromWord(hub, classMirrorOffset()); + return (Class) readFinalObject(hub, classMirrorOffset()); } @InstanceMethodSubstitution diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ThreadSnippets.java Fri Dec 14 13:02:49 2012 +0100 @@ -28,10 +28,12 @@ import com.oracle.graal.snippets.*; + * Snippets for {@link java.lang.Thread} methods. + */ @ClassSubstitution(java.lang.Thread.class) public class ThreadSnippets implements SnippetsInterface { public static Thread currentThread() { - return CurrentThread.get(threadObjectOffset()); + return CurrentThread.get(); } @InstanceMethodSubstitution diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Dec 14 13:02:49 2012 +0100 @@ -34,10 +34,14 @@ */ public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable { - public ReadNode(ValueNode object, ValueNode location, Stamp stamp) { + public ReadNode(ValueNode object, LocationNode location, Stamp stamp) { super(object, location, stamp); } + public ReadNode(ValueNode object, int displacement, Object locationIdentity, Kind kind) { + super(object, object.graph().add(new LocationNode(locationIdentity, kind, displacement)), StampFactory.forKind(kind)); + } + @Override public void generate(LIRGeneratorTool gen) { gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); @@ -49,33 +53,32 @@ } /** - * Utility function for reading a value of this kind using an object and a displacement. + * Utility function for reading a value of this kind using a base address and a displacement. * - * @param object the object from which the value is read + * @param base the base address from which the value is read * @param displacement the displacement within the object in bytes * @return the read value encapsulated in a {@link Constant} object */ - public static Constant readUnsafeConstant(Kind kind, Object object, long displacement) { - assert object != null; + public static Constant readUnsafeConstant(Kind kind, Object base, long displacement) { switch (kind) { case Boolean: - return Constant.forBoolean(unsafe.getBoolean(object, displacement)); + return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement)); case Byte: - return Constant.forByte(unsafe.getByte(object, displacement)); + return Constant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement)); case Char: - return Constant.forChar(unsafe.getChar(object, displacement)); + return Constant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement)); case Short: - return Constant.forShort(unsafe.getShort(object, displacement)); + return Constant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement)); case Int: - return Constant.forInt(unsafe.getInt(object, displacement)); + return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement)); case Long: - return Constant.forLong(unsafe.getLong(object, displacement)); + return Constant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement)); case Float: - return Constant.forFloat(unsafe.getFloat(object, displacement)); + return Constant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement)); case Double: - return Constant.forDouble(unsafe.getDouble(object, displacement)); + return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement)); case Object: - return Constant.forObject(unsafe.getObject(object, displacement)); + return Constant.forObject(unsafe.getObject(base, displacement)); default: throw GraalInternalError.shouldNotReachHere(); } @@ -83,24 +86,37 @@ public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && read.object() != null && read.object().isConstant() && read.object().kind() == Kind.Object) { + if (runtime != null && read.object() != null && read.object().isConstant()/* && read.object().kind() == Kind.Object*/) { if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) { - Object value = read.object().asConstant().asObject(); - if (value != null) { - long displacement = read.location().displacement(); - Kind kind = read.location().getValueKind(); - Constant constant = readUnsafeConstant(kind, value, displacement); - return ConstantNode.forConstant(constant, runtime, read.node().graph()); + long displacement = read.location().displacement(); + Kind kind = read.location().getValueKind(); + if (read.object().kind() == Kind.Object) { + Object base = read.object().asConstant().asObject(); + if (base != null) { + Constant constant = readUnsafeConstant(kind, base, displacement); + return ConstantNode.forConstant(constant, runtime, read.node().graph()); + } + } else if (read.object().kind() == Kind.Long || read.object().kind().getStackKind() == Kind.Int) { + long base = read.object().asConstant().asLong(); + if (base != 0L) { + Constant constant = readUnsafeConstant(kind, null, base + displacement); + return ConstantNode.forConstant(constant, runtime, read.node().graph()); + } } } } return (ValueNode) read; } - private ReadNode(ValueNode object, ValueNode location) { - this(object, location, StampFactory.forNodeIntrinsic()); - } - - @NodeIntrinsic - public static native T readMemory(Object object, Object location); + /** + * Reads a value from memory. + * + * @param base the base pointer for the memory access + * @param displacement the displacement of the access + * @param locationIdentity the identity of the access + * @param kind the kind of the value read + * @return the value read from memory + */ + @NodeIntrinsic(setStampFromReturnType = true) + public static native T read(Object base, @ConstantNodeParameter int displacement, @ConstantNodeParameter Object locationIdentity, @ConstantNodeParameter Kind kind); } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java Fri Dec 14 13:02:49 2012 +0100 @@ -22,12 +22,8 @@ */ package com.oracle.graal.nodes.spi; -import java.util.*; - import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; /** * Graal-specific extensions for the code cache provider interface. @@ -35,6 +31,4 @@ public interface GraalCodeCacheProvider extends CodeCacheProvider { void lower(Node n, LoweringTool tool); - - StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List parameters); } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Dec 14 13:02:49 2012 +0100 @@ -200,11 +200,11 @@ return computeInliningLevel(invoke); } - protected static StructuredGraph getGraph(final Invoke invoke, final ResolvedJavaMethod concrete, final GraalCodeCacheProvider runtime, final InliningCallback callback) { + protected static StructuredGraph getGraph(final Invoke invoke, final ResolvedJavaMethod concrete, final InliningCallback callback) { return Debug.scope("GetInliningGraph", concrete, new Callable() { @Override public StructuredGraph call() throws Exception { - StructuredGraph result = getIntrinsicGraph(invoke, concrete, runtime); + StructuredGraph result = getIntrinsicGraph(invoke, concrete); if (result == null) { assert !Modifier.isNative(concrete.getModifiers()); result = callback.buildGraph(concrete); @@ -229,7 +229,7 @@ @Override public void inline(StructuredGraph compilerGraph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) { - StructuredGraph graph = getGraph(invoke, concrete, runtime, callback); + StructuredGraph graph = getGraph(invoke, concrete, callback); assumptions.recordMethodContents(concrete); InliningUtil.inline(invoke, graph, true); } @@ -283,7 +283,7 @@ graph.addBeforeFixed(invoke.node(), guard); graph.addBeforeFixed(invoke.node(), anchor); - StructuredGraph calleeGraph = getGraph(invoke, concrete, runtime, callback); + StructuredGraph calleeGraph = getGraph(invoke, concrete, callback); assumptions.recordMethodContents(concrete); InliningUtil.inline(invoke, calleeGraph, false); } @@ -333,9 +333,9 @@ // receiver null check must be the first node InliningUtil.receiverNullCheck(invoke); if (numberOfMethods > 1 || shouldFallbackToInvoke()) { - inlineMultipleMethods(graph, runtime, callback, assumptions, numberOfMethods, hasReturnValue); + inlineMultipleMethods(graph, callback, assumptions, numberOfMethods, hasReturnValue); } else { - inlineSingleMethod(graph, runtime, callback, assumptions); + inlineSingleMethod(graph, callback, assumptions); } } @@ -343,7 +343,7 @@ return notRecordedTypeProbability > 0; } - private void inlineMultipleMethods(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions, int numberOfMethods, boolean hasReturnValue) { + private void inlineMultipleMethods(StructuredGraph graph, InliningCallback callback, Assumptions assumptions, int numberOfMethods, boolean hasReturnValue) { FixedNode continuation = invoke.next(); ValueNode originalReceiver = invoke.methodCallTarget().receiver(); @@ -410,7 +410,7 @@ StructuredGraph[] calleeGraphs = new StructuredGraph[numberOfMethods]; for (int i = 0; i < numberOfMethods; i++) { ResolvedJavaMethod concrete = concretes.get(i); - calleeGraphs[i] = getGraph(invoke, concrete, runtime, callback); + calleeGraphs[i] = getGraph(invoke, concrete, callback); assumptions.recordMethodContents(concrete); } @@ -494,7 +494,7 @@ return commonType; } - private void inlineSingleMethod(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions) { + private void inlineSingleMethod(StructuredGraph graph, InliningCallback callback, Assumptions assumptions) { assert concretes.size() == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; BeginNode calleeEntryNode = graph.add(new BeginNode()); @@ -512,7 +512,7 @@ calleeEntryNode.setNext(invoke.node()); ResolvedJavaMethod concrete = concretes.get(0); - StructuredGraph calleeGraph = getGraph(invoke, concrete, runtime, callback); + StructuredGraph calleeGraph = getGraph(invoke, concrete, callback); assumptions.recordMethodContents(concrete); InliningUtil.inline(invoke, calleeGraph, false); } @@ -704,10 +704,10 @@ return getTypeCheckedInlineInfo(invoke, inliningPolicy, caller, holder, targetMethod, optimisticOpts, runtime); } - private static InlineInfo getAssumptionInlineInfo(Invoke invoke, GraalCodeCacheProvider runtime, InliningPolicy inliningPolicy, OptimisticOptimizations optimisticOpts, + private static InlineInfo getAssumptionInlineInfo(Invoke invoke, InliningPolicy inliningPolicy, OptimisticOptimizations optimisticOpts, ResolvedJavaMethod caller, ResolvedJavaMethod concrete, Assumption takenAssumption) { assert !Modifier.isAbstract(concrete.getModifiers()); - if (!checkTargetConditions(invoke, concrete, optimisticOpts, runtime)) { + if (!checkTargetConditions(invoke, concrete, optimisticOpts)) { return null; } double weight = inliningPolicy.inliningWeight(caller, concrete, invoke); @@ -725,7 +725,7 @@ } private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, InliningPolicy inliningPolicy, ResolvedJavaMethod caller, - ResolvedJavaType holder, ResolvedJavaMethod targetMethod, OptimisticOptimizations optimisticOpts, GraalCodeCacheProvider runtime) { + ResolvedJavaType holder, ResolvedJavaMethod targetMethod, OptimisticOptimizations optimisticOpts) { ProfilingInfo profilingInfo = caller.getProfilingInfo(); JavaTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci()); if (typeProfile == null) { @@ -746,7 +746,7 @@ ResolvedJavaType type = ptypes.get(0).getType(); ResolvedJavaMethod concrete = type.resolveMethod(targetMethod); - if (!checkTargetConditions(invoke, concrete, optimisticOpts, runtime)) { + if (!checkTargetConditions(invoke, concrete, optimisticOpts)) { return null; } double weight = inliningPolicy.inliningWeight(caller, concrete, invoke); @@ -784,7 +784,7 @@ double totalWeight = 0; for (ResolvedJavaMethod concrete: concreteMethods) { - if (!checkTargetConditions(invoke, concrete, optimisticOpts, runtime)) { + if (!checkTargetConditions(invoke, concrete, optimisticOpts)) { return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined"); } totalWeight += inliningPolicy.inliningWeight(caller, concrete, invoke); @@ -832,10 +832,10 @@ } } - private static boolean checkTargetConditions(Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts, GraalCodeCacheProvider runtime) { + private static boolean checkTargetConditions(Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) { if (method == null) { return logNotInlinedMethodAndReturnFalse(invoke, method, "the method is not resolved"); - } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(invoke, method, runtime))) { + } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(invoke, method))) { return logNotInlinedMethodAndReturnFalse(invoke, method, "it is a non-intrinsic native method"); } else if (Modifier.isAbstract(method.getModifiers())) { return logNotInlinedMethodAndReturnFalse(invoke, method, "it is an abstract method"); @@ -1029,18 +1029,12 @@ } } - public static boolean canIntrinsify(Invoke invoke, ResolvedJavaMethod target, GraalCodeCacheProvider runtime) { - return getIntrinsicGraph(invoke, target, runtime) != null; + public static boolean canIntrinsify(Invoke invoke, ResolvedJavaMethod target) { + return getIntrinsicGraph(invoke, target) != null; } - public static StructuredGraph getIntrinsicGraph(Invoke invoke, ResolvedJavaMethod target, GraalCodeCacheProvider runtime) { + public static StructuredGraph getIntrinsicGraph(Invoke invoke, ResolvedJavaMethod target) { assert invoke.node().isAlive(); - - StructuredGraph intrinsicGraph = (StructuredGraph) target.getCompilerStorage().get(Graph.class); - if (intrinsicGraph == null && runtime != null) { - // TODO remove once all intrinsics are available via compilerStorage - intrinsicGraph = runtime.intrinsicGraph(invoke.stateAfter().method(), invoke.bci(), target, invoke.callTarget().arguments()); - } - return intrinsicGraph; + return (StructuredGraph) target.getCompilerStorage().get(Graph.class); } } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Dec 14 13:02:49 2012 +0100 @@ -171,6 +171,7 @@ public static boolean AlignCallsForPatching = true; public static boolean ResolveClassBeforeStaticInvoke = true; public static boolean CanOmitFrame = true; + public static int SafepointPollOffset = 256; // Translating tableswitch instructions public static int MinimumJumpTableSize = 5; diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Dec 14 13:02:49 2012 +0100 @@ -39,7 +39,6 @@ * inspected with the Ideal Graph Visualizer. */ public class GraphPrinterDumpHandler implements DebugDumpHandler { - private static final SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd-HHmm"); private GraphPrinter printer; private List previousInlineContext; @@ -66,6 +65,11 @@ } } + // This field must be lazily initialized as this class may be loaded in a version + // VM startup phase at which not all required features (such as system properties) + // are online. + private static SimpleDateFormat sdf; + private void initializeFilePrinter() { String ext; if (GraalOptions.PrintBinaryGraphs) { @@ -73,6 +77,9 @@ } else { ext = ".gv.xml"; } + if (sdf == null) { + sdf = new SimpleDateFormat("YYYY-MM-dd-HHmm"); + } String fileName = "Graphs-" + Thread.currentThread().getName() + "-" + sdf.format(new Date()) + ext; try { if (GraalOptions.PrintBinaryGraphs) { diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java Fri Dec 14 13:02:49 2012 +0100 @@ -32,4 +32,18 @@ public @interface ClassSubstitution { Class value(); + + /** + * Used to map a substitute method to an original method where the default mapping + * of name and signature is not possible due to name clashes with final methods in + * {@link Object} or signature types that are not public. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface MethodSubstitution { + /** + * Get the name of the original method. + */ + String value() default ""; + } } diff -r 31c4d9f9e922 -r 8a3efb8c831d graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Fri Dec 14 12:05:35 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Fri Dec 14 13:02:49 2012 +0100 @@ -37,6 +37,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy; import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy; diff -r 31c4d9f9e922 -r 8a3efb8c831d make/bsd/makefiles/compiler1.make --- a/make/bsd/makefiles/compiler1.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/bsd/makefiles/compiler1.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = client CFLAGS += -DCOMPILER1 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif \ No newline at end of file diff -r 31c4d9f9e922 -r 8a3efb8c831d make/bsd/makefiles/compiler2.make --- a/make/bsd/makefiles/compiler2.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/bsd/makefiles/compiler2.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = server CFLAGS += -DCOMPILER2 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif \ No newline at end of file diff -r 31c4d9f9e922 -r 8a3efb8c831d make/bsd/makefiles/tiered.make --- a/make/bsd/makefiles/tiered.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/bsd/makefiles/tiered.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = server CFLAGS += -DCOMPILER2 -DCOMPILER1 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif diff -r 31c4d9f9e922 -r 8a3efb8c831d make/bsd/makefiles/vm.make --- a/make/bsd/makefiles/vm.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/bsd/makefiles/vm.make Fri Dec 14 13:02:49 2012 +0100 @@ -180,9 +180,9 @@ # Include dirs per type. Src_Dirs/CORE := $(CORE_PATHS) -Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS) -Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS) -Src_Dirs/TIERED := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS) +Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS) $(GRAAL_PATHS) +Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS) $(GRAAL_PATHS) +Src_Dirs/TIERED := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS) $(GRAAL_PATHS) Src_Dirs/ZERO := $(CORE_PATHS) Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS) Src_Dirs/GRAAL := $(CORE_PATHS) $(GRAAL_PATHS) @@ -192,7 +192,12 @@ COMPILER1_SPECIFIC_FILES := c1_\* SHARK_SPECIFIC_FILES := shark ZERO_SPECIFIC_FILES := zero -GRAAL_SPECIFIC_FILES := graal\* + +ifdef OMIT_GRAAL + GRAAL_SPECIFIC_FILES := graal\* +else + GRAAL_SPECIFIC_FILES := +endif # Always exclude these. Src_Files_EXCLUDE += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp diff -r 31c4d9f9e922 -r 8a3efb8c831d make/linux/makefiles/compiler1.make --- a/make/linux/makefiles/compiler1.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/linux/makefiles/compiler1.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = client CFLAGS += -DCOMPILER1 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif \ No newline at end of file diff -r 31c4d9f9e922 -r 8a3efb8c831d make/linux/makefiles/compiler2.make --- a/make/linux/makefiles/compiler2.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/linux/makefiles/compiler2.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = server CFLAGS += -DCOMPILER2 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif \ No newline at end of file diff -r 31c4d9f9e922 -r 8a3efb8c831d make/linux/makefiles/tiered.make --- a/make/linux/makefiles/tiered.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/linux/makefiles/tiered.make Fri Dec 14 13:02:49 2012 +0100 @@ -29,3 +29,7 @@ VM_SUBDIR = server CFLAGS += -DCOMPILER2 -DCOMPILER1 + +ifndef OMIT_GRAAL + CFLAGS += -DGRAAL +endif \ No newline at end of file diff -r 31c4d9f9e922 -r 8a3efb8c831d make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make Fri Dec 14 12:05:35 2012 +0100 +++ b/make/linux/makefiles/vm.make Fri Dec 14 13:02:49 2012 +0100 @@ -182,9 +182,9 @@ # Include dirs per type. Src_Dirs/CORE := $(CORE_PATHS) -Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS) -Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS) -Src_Dirs/TIERED := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS) +Src_Dirs/COMPILER1 := $(CORE_PATHS) $(COMPILER1_PATHS) $(GRAAL_PATHS) +Src_Dirs/COMPILER2 := $(CORE_PATHS) $(COMPILER2_PATHS) $(GRAAL_PATHS) +Src_Dirs/TIERED := $(CORE_PATHS) $(COMPILER1_PATHS) $(COMPILER2_PATHS) $(GRAAL_PATHS) Src_Dirs/ZERO := $(CORE_PATHS) Src_Dirs/SHARK := $(CORE_PATHS) $(SHARK_PATHS) Src_Dirs/GRAAL := $(CORE_PATHS) $(GRAAL_PATHS) @@ -194,7 +194,12 @@ COMPILER1_SPECIFIC_FILES := c1_\* SHARK_SPECIFIC_FILES := shark ZERO_SPECIFIC_FILES := zero -GRAAL_SPECIFIC_FILES := graal\* + +ifdef OMIT_GRAAL + GRAAL_SPECIFIC_FILES := graal\* +else + GRAAL_SPECIFIC_FILES := +endif # Always exclude these. Src_Files_EXCLUDE += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp diff -r 31c4d9f9e922 -r 8a3efb8c831d mx/commands.py --- a/mx/commands.py Fri Dec 14 12:05:35 2012 +0100 +++ b/mx/commands.py Fri Dec 14 13:02:49 2012 +0100 @@ -550,6 +550,8 @@ env.setdefault('LANG', 'C') env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus)) env['ALT_BOOTDIR'] = jdk + if not env.has_key('OMIT_GRAAL'): + env['GRAAL'] = join(_graal_home, 'graal') # needed for TEST_IN_BUILD env.setdefault('INSTALL', 'y') if mx.get_os() == 'solaris' : # If using sparcWorks, setup flags to avoid make complaining about CC version @@ -842,6 +844,10 @@ dacapo(['pmd']) tasks.append(t.stop()) + t = Task('UnitTests:' + theVm + ':' + vmbuild) + unittest(['@-XX:CompileCommand=exclude,*::run*', 'graal.api']) + tasks.append(t.stop()) + except KeyboardInterrupt: total.abort(1) diff -r 31c4d9f9e922 -r 8a3efb8c831d src/cpu/x86/vm/graalGlobals_x86.hpp --- a/src/cpu/x86/vm/graalGlobals_x86.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/cpu/x86/vm/graalGlobals_x86.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -31,6 +31,13 @@ // Sets the default values for platform dependent flags used by the Graal compiler. // (see graalGlobals.hpp) +#ifndef COMPILER2 +define_pd_global(intx, TypeProfileWidth, 8); +#endif + +define_pd_global(intx, GraalSafepointPollOffset, 256 ); + +#if !defined(COMPILER1) && !defined(COMPILER2) define_pd_global(bool, BackgroundCompilation, true ); define_pd_global(bool, UseTLAB, true ); define_pd_global(bool, ResizeTLAB, true ); @@ -43,20 +50,17 @@ define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(intx, NewSizeThreadIncrease, 4*K ); define_pd_global(uintx,MetaspaceSize, 12*M ); -define_pd_global(bool, NeverActAsServerClassMachine, true ); +define_pd_global(bool, NeverActAsServerClassMachine, false); define_pd_global(uint64_t,MaxRAM, 1ULL*G); define_pd_global(bool, CICompileOSR, true ); - define_pd_global(bool, ProfileTraps, true ); -define_pd_global(bool, UseOnStackReplacement, true); -define_pd_global(intx, CompileThreshold, 10000 ); -define_pd_global(intx, InitialCodeCacheSize, 16*M ); +define_pd_global(bool, UseOnStackReplacement, true ); +define_pd_global(intx, CompileThreshold, 10000); +define_pd_global(intx, InitialCodeCacheSize, 16*M ); define_pd_global(intx, ReservedCodeCacheSize, 64*M ); define_pd_global(bool, ProfileInterpreter, true ); define_pd_global(intx, CodeCacheExpansionSize, 64*K ); define_pd_global(uintx,CodeCacheMinBlockLength, 4); -define_pd_global(intx, TypeProfileWidth, 8); - -define_pd_global(intx, SafepointPollOffset, 256 ); +#endif #endif // CPU_X86_VM_GRAALGLOBALS_X86_HPP diff -r 31c4d9f9e922 -r 8a3efb8c831d src/cpu/x86/vm/graalRuntime_x86.cpp --- a/src/cpu/x86/vm/graalRuntime_x86.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -111,23 +111,12 @@ if (metadata_result->is_valid()) { movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); } -#ifdef GRAAL // (thomaswue) Deoptimize in case of an exception. restore_live_registers(this, false); movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); leave(); movl(rscratch1, Deoptimization::make_trap_request(Deoptimization::Reason_constraint, Deoptimization::Action_reinterpret)); jump(RuntimeAddress(SharedRuntime::deopt_blob()->uncommon_trap())); -#else - if (frame_size() == no_frame_size) { - leave(); - jump(RuntimeAddress(StubRoutines::forward_exception_entry())); - } else if (_stub_id == GraalRuntime::forward_exception_id) { - should_not_reach_here(); - } else { - jump(RuntimeAddress(GraalRuntime::entry_for(GraalRuntime::forward_exception_id))); - } -#endif bind(L); } // get oop results if there are any and reset the values in the thread diff -r 31c4d9f9e922 -r 8a3efb8c831d src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -1149,17 +1149,15 @@ Register receiver, Register mdp, Register reg2, int start_row, Label& done, bool is_virtual_call) { -#ifdef GRAAL - // change for GRAAL (use counter to indicate polymorphic case instead of failed typechecks) - bool use_counter_for_polymorphic_case = true; -#else - bool use_counter_for_polymorphic_case = is_virtual_call; -#endif - if (TypeProfileWidth == 0) { - if (use_counter_for_polymorphic_case) { + if (is_virtual_call) { increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); } +#ifdef GRAAL + else { + increment_mdp_data_at(mdp, in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset())); + } +#endif return; } @@ -1194,11 +1192,17 @@ testptr(reg2, reg2); if (start_row == last_row) { // The only thing left to do is handle the null case. - if (use_counter_for_polymorphic_case) { + if (is_virtual_call GRAAL_ONLY(|| true)) { jccb(Assembler::zero, found_null); // Receiver did not match any saved receiver and there is no empty row for it. // Increment total counter to indicate polymorphic case. - increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); + int offset = in_bytes(CounterData::count_offset()); +#ifdef GRAAL + if (!is_virtual_call) { + offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()); + } +#endif + increment_mdp_data_at(mdp, offset); jmp(done); bind(found_null); } else { @@ -1327,8 +1331,6 @@ void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) { -// changed for GRAAL (use counter to indicate polymorphism instead of failed typechecks) -#ifndef GRAAL if (ProfileInterpreter && TypeProfileCasts) { Label profile_continue; @@ -1344,7 +1346,6 @@ bind (profile_continue); } -#endif } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -1996,7 +1996,7 @@ int vep_offset = ((intptr_t)__ pc()) - start; -#ifdef GRAAL +#ifdef GRAALVM if (InlineObjectHash && (method->intrinsic_id() == vmIntrinsics::_hashCode || method->intrinsic_id() == vmIntrinsics::_identityHashCode)) { // Object.hashCode can pull the hashCode from the header word // instead of doing a full VM transition once it's been computed. @@ -2038,7 +2038,7 @@ __ bind (slowCase); } -#endif // GRAAL +#endif // GRAALVM // The instruction at the verified entry point must be 5 bytes or longer // because it can be patched on the fly by make_non_entrant. The stack bang @@ -3420,7 +3420,7 @@ __ push(0); // Save everything in sight. - RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); + map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); // Now it is safe to overwrite any register diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/c1/c1_Compiler.cpp --- a/src/share/vm/c1/c1_Compiler.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/c1/c1_Compiler.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -44,7 +44,7 @@ volatile int Compiler::_runtimes = uninitialized; -Compiler::Compiler() { +Compiler::Compiler() : AbstractCompiler(c1) { } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/c1/c1_globals.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -56,8 +56,6 @@ // #define C1_FLAGS(develop, develop_pd, product, product_pd, notproduct) \ \ - product(bool, TraceSignals, false, \ - "Trace signals and implicit exception handling") \ /* Printing */ \ notproduct(bool, PrintC1Statistics, false, \ "Print Compiler1 statistics" ) \ diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/code/codeBlob.cpp --- a/src/share/vm/code/codeBlob.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/code/codeBlob.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -384,9 +384,7 @@ _unpack_offset = unpack_offset; _unpack_with_exception = unpack_with_exception_offset; _unpack_with_reexecution = unpack_with_reexecution_offset; -#if defined(COMPILER1) || defined(GRAAL) _unpack_with_exception_in_tls = -1; -#endif } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/code/nmethod.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -868,27 +868,28 @@ #ifdef GRAAL _graal_installed_code = installed_code(); - - // Graal might not produce any stub sections - if (offsets->value(CodeOffsets::Exceptions) != -1) { - _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); - } else { - _exception_offset = -1; - } - if (offsets->value(CodeOffsets::Deopt) != -1) { - _deoptimize_offset = code_offset() + offsets->value(CodeOffsets::Deopt); +#endif + if (compiler->is_graal()) { + // Graal might not produce any stub sections + if (offsets->value(CodeOffsets::Exceptions) != -1) { + _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); + } else { + _exception_offset = -1; + } + if (offsets->value(CodeOffsets::Deopt) != -1) { + _deoptimize_offset = code_offset() + offsets->value(CodeOffsets::Deopt); + } else { + _deoptimize_offset = -1; + } + if (offsets->value(CodeOffsets::DeoptMH) != -1) { + _deoptimize_mh_offset = code_offset() + offsets->value(CodeOffsets::DeoptMH); + } else { + _deoptimize_mh_offset = -1; + } } else { - _deoptimize_offset = -1; - } - if (offsets->value(CodeOffsets::DeoptMH) != -1) { - _deoptimize_mh_offset = code_offset() + offsets->value(CodeOffsets::DeoptMH); - } else { - _deoptimize_mh_offset = -1; - } -#else - // Exception handler and deopt handler are in the stub section - assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set"); - assert(offsets->value(CodeOffsets::Deopt ) != -1, "must be set"); + // Exception handler and deopt handler are in the stub section + assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set"); + assert(offsets->value(CodeOffsets::Deopt ) != -1, "must be set"); _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); @@ -897,7 +898,7 @@ } else { _deoptimize_mh_offset = -1; } -#endif + } if (offsets->value(CodeOffsets::UnwindHandler) != -1) { _unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler); } else { @@ -1241,9 +1242,7 @@ } void nmethod::inc_decompile_count() { -#ifndef GRAAL - if (!is_compiled_by_c2()) return; -#endif + if (!is_compiled_by_c2() && !is_compiled_by_graal()) return; // Could be gated by ProfileTraps, but do not bother... Method* m = method(); if (m == NULL) return; diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/code/nmethod.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -118,8 +118,6 @@ #ifdef GRAAL // Needed to keep nmethods alive that are not the default nmethod for the associated Method. - // This field is initialized to Universe::non_oop_word() so that a non-default nmethod - // is not unloaded between being allocated and having this field set in the Graal specific code oop _graal_installed_code; #endif diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/code/pcDesc.cpp --- a/src/share/vm/code/pcDesc.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/code/pcDesc.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -44,11 +44,11 @@ void PcDesc::print(nmethod* code) { #ifndef PRODUCT ResourceMark rm; -#ifdef GRAAL - tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x leaf_graph_id=%d):", real_pc(code), pc_offset(), _flags, leaf_graph_id()); -#else - tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags); -#endif + if (code->is_compiled_by_graal()) { + tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x leaf_graph_id=%d):", real_pc(code), pc_offset(), _flags, leaf_graph_id()); + } else { + tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags); + } if (scope_decode_offset() == DebugInformationRecorder::serialized_null) { return; diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/compiler/abstractCompiler.hpp --- a/src/share/vm/compiler/abstractCompiler.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/compiler/abstractCompiler.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -37,12 +37,20 @@ // Used for tracking global state of compiler runtime initialization enum { uninitialized, initializing, initialized }; + // The (closed set) of concrete compiler classes. Using an tag like this + // avoids a confusing use of macros around the definition of the + // 'is_' methods. + enum Type { c1, c2, shark, graal }; + // This method will call the initialization method "f" once (per compiler class/subclass) // and do so without holding any locks void initialize_runtimes(initializer f, volatile int* state); + private: + Type _type; + public: - AbstractCompiler() : _is_initialized(false) {} + AbstractCompiler(Type type) : _is_initialized(false), _type(type) {} // Name of this compiler virtual const char* name() = 0; @@ -53,37 +61,10 @@ virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } -#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !defined(GRAAL)) - virtual bool is_c1 () { return false; } - virtual bool is_c2 () { return false; } - virtual bool is_shark() { return false; } - virtual bool is_graal() { return false; } -#else -#ifdef COMPILER1 - bool is_c1 () { return true; } - bool is_c2 () { return false; } - bool is_shark() { return false; } - bool is_graal() { return false; } -#endif // COMPILER1 -#ifdef COMPILER2 - bool is_c1 () { return false; } - bool is_c2 () { return true; } - bool is_shark() { return false; } - bool is_graal() { return false; } -#endif // COMPILER2 -#ifdef SHARK - bool is_c1 () { return false; } - bool is_c2 () { return false; } - bool is_shark() { return true; } - bool is_graal() { return false; } -#endif // SHARK -#ifdef GRAAL - bool is_c1 () { return false; } - bool is_c2 () { return false; } - bool is_shark() { return false; } - bool is_graal() { return true; } -#endif // GRAAL -#endif // TIERED + bool is_c1 () { return _type == c1; } + bool is_c2 () { return _type == c2; } + bool is_shark() { return _type == shark; } + bool is_graal() { return _type == graal; } void mark_initialized() { _is_initialized = true; } bool is_initialized() { return _is_initialized; } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -753,8 +753,13 @@ // Set the interface to the current compiler(s). int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple); int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization); -#if defined(GRAAL) - _compilers[0] = new GraalCompiler(); + +#ifdef GRAAL + GraalCompiler* graal = new GraalCompiler(); +#endif + +#if defined(GRAALVM) + _compilers[0] = graal; c1_count = 0; c2_count = 0; #elif defined(COMPILER1) @@ -971,9 +976,9 @@ // Initialize the compilation queue void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) { EXCEPTION_MARK; -#if !defined(ZERO) && !defined(SHARK) && !defined(GRAAL) +#if !defined(ZERO) && !defined(SHARK) && !defined(GRAALVM) assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?"); -#endif // !ZERO && !SHARK +#endif // !ZERO && !SHARK && !GRAALVM if (c2_compiler_count > 0) { _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock); } @@ -1024,7 +1029,6 @@ // ------------------------------------------------------------------ // CompileBroker::is_idle bool CompileBroker::is_idle() { -#ifndef GRAAL if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) { return false; } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) { @@ -1037,7 +1041,6 @@ } } } -#endif // No pending or active compilations. return true; } @@ -1122,7 +1125,7 @@ if (InstanceRefKlass::owns_pending_list_lock(JavaThread::current())) { return; } -#ifdef GRAAL +#ifdef GRAALVM if (!JavaThread::current()->is_compiling()) { method->set_queued_for_compilation(); GraalCompiler::instance()->compile_method(method, osr_bci, is_compile_blocking(method, osr_bci)); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -448,6 +448,22 @@ } } +// If deoptimization happens, the interpreter should reexecute these bytecodes. +// This function mainly helps the compilers to set up the reexecute bit. +static bool bytecode_should_reexecute(Bytecodes::Code code) { + switch (code) { + case Bytecodes::_invokedynamic: + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + return false; + default: + return true; + } + return true; +} + void CodeInstaller::record_scope(jint pc_offset, oop frame, GrowableArray* objects) { assert(frame->klass() == BytecodeFrame::klass(), "BytecodeFrame expected"); oop caller_frame = BytecodePosition::caller(frame); @@ -463,7 +479,7 @@ reexecute = false; } else { Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci)); - reexecute = Interpreter::bytecode_should_reexecute(code); + reexecute = bytecode_should_reexecute(code); if (frame != NULL) { reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE); } @@ -797,7 +813,8 @@ case MARK_POLL_NEAR: { NativeInstruction* ni = nativeInstruction_at(instruction); int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); - intptr_t new_disp = (intptr_t) (os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())) - (intptr_t) ni; + int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand + intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; *disp = (int32_t)new_disp; } case MARK_POLL_FAR: @@ -806,43 +823,13 @@ case MARK_POLL_RETURN_NEAR: { NativeInstruction* ni = nativeInstruction_at(instruction); int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); - intptr_t new_disp = (intptr_t) (os::get_polling_page() + (SafepointPollOffset % os::vm_page_size())) - (intptr_t) ni; + int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand + intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; *disp = (int32_t)new_disp; } case MARK_POLL_RETURN_FAR: _instructions->relocate(instruction, relocInfo::poll_return_type); break; - case MARK_KLASS_PATCHING: - case MARK_ACCESS_FIELD_PATCHING: { - unsigned char* byte_count = (unsigned char*) (instruction - 1); - unsigned char* byte_skip = (unsigned char*) (instruction - 2); - unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3); - - assert(*byte_skip == 5, "unexpected byte_skip"); - - assert(references->length() == 2, "MARK_KLASS_PATCHING/MARK_ACCESS_FIELD_PATCHING needs 2 references"); - oop ref1 = ((oop*) references->base(T_OBJECT))[0]; - oop ref2 = ((oop*) references->base(T_OBJECT))[1]; - int i_byte_count = CompilationResult_Site::pcOffset(ref2) - CompilationResult_Site::pcOffset(ref1); - assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset"); - *byte_count = i_byte_count; - *being_initialized_entry_offset = *byte_count + *byte_skip; - - // we need to correct the offset of a field access - it's created with MAX_INT to ensure the correct size, and HotSpot expects 0 - if (id == MARK_ACCESS_FIELD_PATCHING) { - NativeMovRegMem* inst = nativeMovRegMem_at(_instructions->start() + CompilationResult_Site::pcOffset(ref1)); - assert(inst->offset() == max_jint, "unexpected offset value"); - inst->set_offset(0); - } - break; - } - case MARK_DUMMY_OOP_RELOCATION: { - _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - - RelocIterator iter(_instructions, (address) instruction, (address) (instruction + 1)); - relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none); - break; - } default: ShouldNotReachHere(); break; diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -49,9 +49,6 @@ MARK_POLL_RETURN_NEAR = 0x3002, MARK_POLL_FAR = 0x3003, MARK_POLL_RETURN_FAR = 0x3004, - MARK_KLASS_PATCHING = 0x4000, - MARK_DUMMY_OOP_RELOCATION = 0x4001, - MARK_ACCESS_FIELD_PATCHING = 0x4002 }; Arena _arena; diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -36,7 +36,7 @@ GraalCompiler* GraalCompiler::_instance = NULL; -GraalCompiler::GraalCompiler() { +GraalCompiler::GraalCompiler() : AbstractCompiler(graal) { _initialized = false; assert(_instance == NULL, "only one instance allowed"); _instance = this; diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -1,999 +1,1016 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include "precompiled.hpp" -#include "runtime/fieldDescriptor.hpp" -#include "memory/oopFactory.hpp" -#include "oops/generateOopMap.hpp" -#include "oops/fieldStreams.hpp" -#include "runtime/javaCalls.hpp" -#include "graal/graalRuntime.hpp" -#include "compiler/compileBroker.hpp" -#include "compiler/compilerOracle.hpp" -#include "graal/graalCompilerToVM.hpp" -#include "graal/graalCompiler.hpp" -#include "graal/graalEnv.hpp" -#include "graal/graalJavaAccess.hpp" -#include "graal/graalCodeInstaller.hpp" -#include "graal/graalVMToCompiler.hpp" -#include "graal/graalVmIds.hpp" - - -Method* getMethodFromHotSpotMethod(oop hotspot_method) { - assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity"); - return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method)); -} - -// Entry to native method implementation that transitions current thread to '_thread_in_vm'. -#define C2V_VMENTRY(result_type, name, signature) \ - JNIEXPORT result_type JNICALL c2v_ ## name signature { \ - TRACE_graal_3("CompilerToVM::" #name); \ - GRAAL_VM_ENTRY_MARK; \ - -// Entry to native method implementation that calls a JNI function -// and hence cannot transition current thread to '_thread_in_vm'. -#define C2V_ENTRY(result_type, name, signature) \ - JNIEXPORT result_type JNICALL c2v_ ## name signature { \ - TRACE_graal_3("CompilerToVM::" #name); \ - -#define C2V_END } - -C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result)) - methodHandle method = asMethod(metaspace_method); - ResourceMark rm; - - int code_size = method->code_size(); - jbyte* reconstituted_code = NULL; - - // replace all breakpoints - must be done before undoing any rewriting - if (method->number_of_breakpoints() > 0) { - reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size); - memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size); - BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints(); - for (; bp != NULL; bp = bp->next()) { - if (bp->match(method())) { - jbyte code = bp->orig_bytecode(); - reconstituted_code[bp->bci()] = code; - } - } - } - - // iterate over all bytecodes and replace non-Java bytecodes - if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) { - if (reconstituted_code == NULL) { - reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size); - memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size); - } - BytecodeStream s(method); - while(!s.is_last_bytecode()) { - s.next(); - Bytecodes::Code opcode = s.raw_code(); - if (!Bytecodes::is_java_code(opcode)) { - jbyte original_opcode = Bytecodes::java_code(opcode); - int bci = s.bci(); - reconstituted_code[bci] = original_opcode; - if (opcode == Bytecodes::_fast_aldc_w) { - int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1); - int i = method->constants()->object_to_cp_index(cpci); - assert(i < method->constants()->length(), "sanity check"); - Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i); - } else if (opcode == Bytecodes::_fast_aldc) { - int cpci = reconstituted_code[bci + 1] & 0xff; - int i = method->constants()->object_to_cp_index(cpci); - assert(i < method->constants()->length(), "sanity check"); - reconstituted_code[bci + 1] = (jbyte)i; - } - } - } - } - - if (reconstituted_code == NULL) { - env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base()); - } else { - env->SetByteArrayRegion(result, 0, code_size, reconstituted_code); - } - - return result; -C2V_END - -C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method)) - Method* method = asMethod(metaspace_method); - assert(method != NULL && method->signature() != NULL, "signature required"); - return VmIds::toString(method->signature(), THREAD); -C2V_END - -C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers)) - ResourceMark rm; - methodHandle method = asMethod(metaspace_method); - int handler_count = method->exception_table_length(); - objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers); - assert(array->length() == handler_count, "wrong length"); - ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start(); - - for (int i = 0; i < handler_count; i++) { - ExceptionTableElement* handler = handlers + i; - Handle entry = array->obj_at(i); - assert(!entry.is_null(), "entry should not be null"); - ExceptionHandler::set_startBCI(entry, handler->start_pc); - ExceptionHandler::set_endBCI(entry, handler->end_pc); - ExceptionHandler::set_handlerBCI(entry, handler->handler_pc); - int catch_class_index = handler->catch_type_index; - ExceptionHandler::set_catchTypeCPI(entry, catch_class_index); - - if (catch_class_index == 0) { - ExceptionHandler::set_catchType(entry, NULL); - } else { - ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants(); - KlassHandle loading_klass = method->method_holder(); - Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL); - if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) { - ExceptionHandler::set_catchType(entry, NULL); - ExceptionHandler::set_catchTypeCPI(entry, 0); - } else { - ExceptionHandler::set_catchType(entry, catch_class()); - } - } - array->obj_at_put(i, entry()); - } - - return (jobjectArray) JNIHandles::make_local(array()); -C2V_END - -C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method)) - - // Analyze the method to see if monitors are used properly. - methodHandle method(THREAD, asMethod(metaspace_method)); - assert(method->has_monitor_bytecodes(), "should have checked this"); - - // Check to see if a previous compilation computed the monitor-matching analysis. - if (method->guaranteed_monitor_matching()) { - return true; - } - - { - EXCEPTION_MARK; - ResourceMark rm(THREAD); - GeneratePairingInfo gpi(method); - gpi.compute_map(CATCH); - if (!gpi.monitor_safe()) { - return false; - } - method->set_guaranteed_monitor_matching(); - } - return true; -C2V_END - -C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder)) - oop reflection_method = JNIHandles::resolve(reflection_method_handle); - oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method); - int slot = java_lang_reflect_Method::slot(reflection_method); - Klass* holder = java_lang_Class::as_Klass(reflection_holder); - methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); - Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0); - objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); - return (jlong) (address) method(); -} - -C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder)) - oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle); - oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor); - int slot = java_lang_reflect_Constructor::slot(reflection_ctor); - Klass* holder = java_lang_Class::as_Klass(reflection_holder); - methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); - Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0); - objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); - return (jlong) (address) method(); -} - -C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle)) - oop reflection_field = JNIHandles::resolve(reflection_field_handle); - oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field); - int slot = java_lang_reflect_Field::slot(reflection_field); - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder)); - - int offset = holder->field_offset(slot); - int flags = holder->field_access_flags(slot); - Symbol* field_name = holder->field_name(slot); - Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL); - Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL); - - Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL); - return JNIHandles::make_local(THREAD, ret()); -} - -C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder)) - methodHandle method = asMethod(metaspace_method); - KlassHandle holder = method->method_holder(); - // TODO (chaeubl): check if the following is necessary - //if (holder->is_interface()) { - // // Cannot trust interfaces. Because of: - // // interface I { void foo(); } - // // class A { public void foo() {} } - // // class B extends A implements I { } - // // class C extends B { public void foo() { } } - // // class D extends B { } - // // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo(). - // return 0L; - //} - methodHandle ucm; - { - ResourceMark rm; - MutexLocker locker(Compile_lock); - ucm = Dependencies::find_unique_concrete_method(holder(), method()); - } - - if (ucm.is_null()) { - return 0L; - } - - Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0); - objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); - return (jlong) (address) ucm(); -C2V_END - -C2V_VMENTRY(jobject, getUniqueImplementor, (JNIEnv *, jobject, jobject interface_type)) - InstanceKlass* klass = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(interface_type)); - assert(klass->is_interface(), "must be"); - if (klass->nof_implementors() == 1) { - InstanceKlass* implementor = (InstanceKlass*) klass->implementor(); - if (!implementor->is_abstract() && !implementor->is_interface() && implementor->is_leaf_class()) { - Handle type = GraalCompiler::get_JavaType(implementor, CHECK_NULL); - return JNIHandles::make_local(THREAD, type()); - } - } - return NULL; -C2V_END - -C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method)) - Method* method = asMethod(metaspace_method); - return method->invocation_count(); -C2V_END - -C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method)) - methodHandle method = asMethod(metaspace_method); - Handle name = VmIds::toString(method->name(), CHECK); - InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK); - HotSpotResolvedJavaMethod::set_name(hotspot_method, name()); - HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size()); - HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length()); -C2V_END - -C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method)) - methodHandle method = asMethod(metaspace_method); - return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method); -C2V_END - -C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data)) - MethodData* method_data = asMethodData(metaspace_method_data); - HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size()); - HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size()); -C2V_END - -// ------------------------------------------------------------------ -// Adjust a CounterData count to be commensurate with -// interpreter_invocation_count. If the MDO exists for -// only 25% of the time the method exists, then the -// counts in the MDO should be scaled by 4X, so that -// they can be usefully and stably compared against the -// invocation counts in methods. -int scale_count(MethodData* method_data, int count) { - if (count > 0) { - int counter_life; - int method_life = method_data->method()->interpreter_invocation_count(); - int current_mileage = MethodData::mileage_of(method_data->method()); - int creation_mileage = method_data->creation_mileage(); - counter_life = current_mileage - creation_mileage; - - // counter_life due to backedge_counter could be > method_life - if (counter_life > method_life) - counter_life = method_life; - if (0 < counter_life && counter_life <= method_life) { - count = (int)((double)count * method_life / counter_life + 0.5); - count = (count > 0) ? count : 1; - } - } - return count; -} - -C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method)) - nmethod* code = (asMethod(metaspace_method))->code(); - return code == NULL ? 0 : code->insts_size(); -C2V_END - -C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve)) - ResourceMark rm; - - Symbol* nameSymbol = VmIds::toSymbol(jname); - Handle name = JNIHandles::resolve(jname); - assert(nameSymbol != NULL, "name to symbol creation failed"); - - oop result = NULL; - if (nameSymbol == vmSymbols::int_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD); - } else if (nameSymbol == vmSymbols::long_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD); - } else if (nameSymbol == vmSymbols::bool_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD); - } else if (nameSymbol == vmSymbols::char_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD); - } else if (nameSymbol == vmSymbols::short_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD); - } else if (nameSymbol == vmSymbols::byte_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD); - } else if (nameSymbol == vmSymbols::double_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD); - } else if (nameSymbol == vmSymbols::float_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD); - } else if (nameSymbol == vmSymbols::void_signature()) { - result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD); - } else { - Klass* resolved_type = NULL; - Handle classloader; - Handle protectionDomain; - if (JNIHandles::resolve(accessingClass) != NULL) { - classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader(); - protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain(); - } - - if (eagerResolve) { - resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD); - } else { - resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); - } - - if (!HAS_PENDING_EXCEPTION) { - if (resolved_type == NULL) { - assert(!eagerResolve, "failed eager resolution should have caused an exception"); - Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD); - result = type(); - } else { - Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL); - result = type(); - } - } - } - - return JNIHandles::make_local(THREAD, result); -C2V_END - -C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index)) - - ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); - - oop result = NULL; - constantTag tag = cp->tag_at(index); - if (tag.is_int()) { - result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0); - } else if (tag.is_long()) { - result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0); - } else if (tag.is_float()) { - result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0); - } else if (tag.is_double()) { - result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0); - } else if (tag.is_string()) { - oop string = NULL; - if (cp->is_pseudo_string_at(index)) { - int obj_index = cp->cp_to_object_index(index); - string = cp->pseudo_string_at(index, obj_index); - } else { - string = cp->string_at(index, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - // TODO: Gracefully exit compilation. - fatal("out of memory during compilation!"); - return NULL; - } - } - result = VMToCompiler::createConstantObject(string, CHECK_0); - } else if (tag.is_klass() || tag.is_unresolved_klass()) { - Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL); - result = type(); - } else if (tag.is_object()) { - oop obj = cp->object_at(index); - assert(obj->is_instance(), "must be an instance"); - result = VMToCompiler::createConstantObject(obj, CHECK_NULL); - } else { - tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string()); - ShouldNotReachHere(); - } - - return JNIHandles::make_local(THREAD, result); -C2V_END - -C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode)) - index = GraalCompiler::to_cp_index_u2(index); - constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); - instanceKlassHandle pool_holder(cp->pool_holder()); - - Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); - methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder); - if (!method.is_null()) { - Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL); - return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD)); - } else { - // Get the method's name and signature. - Handle name = VmIds::toString(cp->name_ref_at(index), CHECK_NULL); - Handle signature = VmIds::toString(cp->signature_ref_at(index), CHECK_NULL); - int holder_index = cp->klass_ref_index_at(index); - Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); - return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD)); - } -C2V_END - -C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index)) - - ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); - Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL); - return JNIHandles::make_local(THREAD, result()); -C2V_END - -C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op)) - ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); - int opcode = (op & 0xFF); - if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray - && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w) - { - index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index)); - } - constantTag tag = cp->tag_at(index); - if (tag.is_field_or_method()) { - index = cp->uncached_klass_ref_index_at(index); - tag = cp->tag_at(index); - } - - if (tag.is_unresolved_klass() || tag.is_klass()) { - Klass* klass = cp->klass_at(index, CHECK); - if (klass->oop_is_instance()) { - InstanceKlass::cast(klass)->initialize(CHECK); - } - } -C2V_END - -C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode)) - ResourceMark rm; - - index = GraalCompiler::to_cp_index_u2(index); - constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants(); - - int nt_index = cp->name_and_type_ref_index_at(index); - int sig_index = cp->signature_ref_index_at(nt_index); - Symbol* signature = cp->symbol_at(sig_index); - int name_index = cp->name_ref_index_at(nt_index); - Symbol* name = cp->symbol_at(name_index); - int holder_index = cp->klass_ref_index_at(index); - Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); - instanceKlassHandle holder_klass; - - Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF); - int offset = -1; - AccessFlags flags; - BasicType basic_type; - if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) { - FieldAccessInfo result; - LinkResolver::resolve_field(result, cp, index, - Bytecodes::java_code(code), - true, false, Thread::current()); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - } else { - offset = result.field_offset(); - flags = result.access_flags(); - holder_klass = result.klass()(); - basic_type = result.field_type(); - holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL); - } - } - - Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL); - Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD); - - return JNIHandles::make_local(THREAD, field_handle()); -C2V_END - -C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature)) - - assert(JNIHandles::resolve(resolved_type) != NULL, ""); - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type)); - Symbol* name_symbol = VmIds::toSymbol(name); - Symbol* signature_symbol = VmIds::toSymbol(signature); - methodHandle method = klass->lookup_method(name_symbol, signature_symbol); - if (method.is_null()) { - if (TraceGraal >= 3) { - ResourceMark rm; - tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string()); - } - return NULL; - } - Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL); - return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD)); -C2V_END - -C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass)) - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); - assert(klass != NULL, "method must not be called for primitive types"); - return InstanceKlass::cast(klass)->is_initialized(); -C2V_END - -C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass)) - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); - assert(klass != NULL, "method must not be called for primitive types"); - InstanceKlass::cast(klass)->initialize(JavaThread::current()); -C2V_END - -C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass)) - ResourceMark rm; - - instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)); - GrowableArray fields(k->java_fields_count()); - - for (AllFieldStream fs(k()); !fs.done(); fs.next()) { - if (!fs.access_flags().is_static()) { - Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current()); - int flags = fs.access_flags().as_int(); - bool internal = fs.access_flags().is_internal(); - Handle name = VmIds::toString(fs.name(), Thread::current()); - Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current()); - fields.append(field()); - } - } - objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL); - for (int i = 0; i < fields.length(); ++i) { - field_array->obj_at_put(i, fields.at(i)()); - } - return JNIHandles::make_local(field_array()); -C2V_END - -C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub)) - address target_addr = (address) stub; - if (target_addr != 0x0) { - int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); - int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); - return MAX2(ABS(off_low), ABS(off_high)); - } - return -1; -C2V_END - -C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass)) - oop java_mirror = JNIHandles::resolve(javaClass); - assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL"); - Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL); - return JNIHandles::make_local(THREAD, type()); -C2V_END - - -// helpers used to set fields in the HotSpotVMConfig object -jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { - jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig); - if (id == NULL) { - fatal(err_msg("field not found: %s (%s)", name, sig)); - } - return id; -} - -BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT }; -int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType); - -C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config)) - -#define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0) -#define set_int(name, value) do { env->SetIntField(config, getFieldID(env, config, name, "I"), value); } while (0) -#define set_long(name, value) do { env->SetLongField(config, getFieldID(env, config, name, "J"), value); } while (0) -#define set_object(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "Ljava/lang/Object;"), value); } while (0) -#define set_int_array(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "[I"), value); } while (0) - - guarantee(HeapWordSize == sizeof(char*), "Graal assumption that HeadWordSize == machine word size is wrong"); -#ifdef _WIN64 - set_boolean("windowsOs", true); -#else - set_boolean("windowsOs", false); -#endif - set_boolean("verifyOops", VerifyOops); - set_boolean("useFastLocking", UseFastLocking); - set_boolean("useFastNewObjectArray", UseFastNewObjectArray); - set_boolean("useBiasedLocking", UseBiasedLocking); - set_boolean("useFastNewTypeArray", UseFastNewTypeArray); - set_boolean("useTLAB", UseTLAB); - set_int("codeEntryAlignment", CodeEntryAlignment); - set_int("vmPageSize", os::vm_page_size()); - set_int("stackShadowPages", StackShadowPages); - set_int("hubOffset", oopDesc::klass_offset_in_bytes()); - set_int("markOffset", oopDesc::mark_offset_in_bytes()); - set_int("prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset())); - set_int("superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset())); - set_int("secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset())); - set_int("secondarySupersOffset", in_bytes(Klass::secondary_supers_offset())); - set_int("subklassOffset", in_bytes(Klass::subklass_offset())); - set_int("nextSiblingOffset", in_bytes(Klass::next_sibling_offset())); - set_int("arrayLengthOffset", arrayOopDesc::length_offset_in_bytes()); - set_int("klassStateOffset", in_bytes(InstanceKlass::init_state_offset())); - set_int("klassStateFullyInitialized", (int)InstanceKlass::fully_initialized); - set_int("threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset())); - set_int("threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset())); - set_int("threadObjectOffset", in_bytes(JavaThread::threadObj_offset())); - set_int("osThreadOffset", in_bytes(JavaThread::osthread_offset())); - set_int("osThreadInterruptedOffset", in_bytes(OSThread::interrupted_offset())); - set_int("unlockedMask", (int) markOopDesc::unlocked_value); - set_int("biasedLockMaskInPlace", (int) markOopDesc::biased_lock_mask_in_place); - set_int("ageMaskInPlace", (int) markOopDesc::age_mask_in_place); - set_int("epochMaskInPlace", (int) markOopDesc::epoch_mask_in_place); - set_int("biasedLockPattern", (int) markOopDesc::biased_lock_pattern); - set_int("methodMaxLocalsOffset", in_bytes(Method::size_of_locals_offset())); - set_int("methodMaxStackOffset", in_bytes(Method::max_stack_offset())); - set_int("extraStackEntries", Method::extra_stack_entries()); - set_int("methodAccessFlagsOffset", in_bytes(Method::access_flags_offset())); - set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER); - set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset())); - set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); - set_long("safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); - set_boolean("isPollingPageFar", Assembler::is_polling_page_far()); - set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset())); - set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes); - set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset())); - set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset())); - set_int("klassOffset", java_lang_Class::klass_offset_in_bytes()); - set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes()); - set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset())); - set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset())); - set_int("methodDataOffset", in_bytes(Method::method_data_offset())); - set_int("nmethodEntryOffset", nmethod::verified_entry_point_offset()); - set_int("methodCompiledEntryOffset", in_bytes(Method::from_compiled_offset())); - set_int("basicLockSize", sizeof(BasicLock)); - set_int("basicLockDisplacedHeaderOffset", BasicLock::displaced_header_offset_in_bytes()); - set_int("uninitializedIdentityHashCodeValue", markOopDesc::no_hash); - set_int("identityHashCodeShift", markOopDesc::hash_shift); - - set_int("arrayKlassLayoutHelperIdentifier", 0x80000000); - assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set"); - set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset())); - - set_int("metaspaceArrayLengthOffset", Array::length_offset_in_bytes()); - set_int("metaspaceArrayBaseOffset", Array::base_offset_in_bytes()); - set_int("methodDataOopDataOffset", in_bytes(MethodData::data_offset())); - set_int("methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset())); - set_int("dataLayoutHeaderSize", DataLayout::header_size_in_bytes()); - set_int("dataLayoutTagOffset", in_bytes(DataLayout::tag_offset())); - set_int("dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset())); - set_int("dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset())); - set_int("dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0))); - set_int("dataLayoutCellSize", DataLayout::cell_size); - set_int("bciProfileWidth", BciProfileWidth); - set_int("typeProfileWidth", TypeProfileWidth); - - set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); - set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); - set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr()); - set_long("heapEndAddress", (jlong)(address) Universe::heap()->end_addr()); - set_int("threadTlabStartOffset", in_bytes(JavaThread::tlab_start_offset())); - set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset())); - set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset())); - set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset())); - set_int("tlabFastRefillWasteOffset", in_bytes(JavaThread::tlab_fast_refill_waste_offset())); - set_int("tlabNumberOfRefillsOffset", in_bytes(JavaThread::tlab_number_of_refills_offset())); - set_int("tlabRefillWasteLimitOffset", in_bytes(JavaThread::tlab_refill_waste_limit_offset())); - set_int("tlabRefillWasteIncrement", (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment()); - set_int("klassInstanceSizeOffset", in_bytes(Klass::layout_helper_offset())); - set_boolean("tlabStats", TLABStats); - set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc()); - - set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype()); - set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift); - set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask); - set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift); - set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask); - set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift); - set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask); - set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset())); - - set_long("debugStub", VmIds::addStub((address)warning)); - set_long("instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id))); - set_long("newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id))); - set_long("newArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_array_id))); - set_long("newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id))); - set_long("identityHashCodeStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_identity_hash_code_id))); - set_long("threadIsInterruptedStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_thread_is_interrupted_id))); - set_long("inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub())); - set_long("handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id))); - set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack())); - set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id))); - set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id))); - set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id))); - set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id))); - set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap())); - set_long("unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id))); - set_long("osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id))); - set_long("registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id))); - set_long("setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id))); - set_long("createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id))); - set_long("createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id))); - set_long("javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis))); - set_long("javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos))); - set_long("arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id))); - set_long("arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id))); - set_long("arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin))); - set_long("arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); - set_long("arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); - set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id))); - set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id))); - set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id))); - - - BarrierSet* bs = Universe::heap()->barrier_set(); - switch (bs->kind()) { - case BarrierSet::CardTableModRef: - case BarrierSet::CardTableExtension: { - jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base; - assert(base != 0, "unexpected byte_map_base"); - set_long("cardtableStartAddress", base); - set_int("cardtableShift", CardTableModRefBS::card_shift); - break; - } - case BarrierSet::ModRef: - case BarrierSet::Other: - set_long("cardtableStartAddress", 0); - set_int("cardtableShift", 0); - // No post barriers - break; -#ifndef SERIALGC - case BarrierSet::G1SATBCT: - case BarrierSet::G1SATBCTLogging: -#endif // SERIALGC - default: - ShouldNotReachHere(); - break; - } - - set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset())); - -#undef set_boolean -#undef set_int -#undef set_long -#undef set_object -#undef set_int_array - -C2V_END - -C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info)) - ResourceMark rm; - HandleMark hm; - Handle compResultHandle = JNIHandles::resolve(compResult); - nmethod* nm = NULL; - methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult)); - Handle installed_code_handle = JNIHandles::resolve(installed_code); - GraalEnv::CodeInstallResult result; - CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle); - - if (result != GraalEnv::ok) { - assert(nm == NULL, "should be"); - } else { - if (info != NULL) { - arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0); - memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size()); - HotSpotCodeInfo::set_code(info, codeCopy); - HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin()); - } - - if (!installed_code_handle.is_null()) { - assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); - HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm); - HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult)); - assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable"); - } - } - return result; -C2V_END - -C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address)) - ResourceMark rm; - HandleMark hm; - - stringStream(st); - arrayOop code_oop = (arrayOop) JNIHandles::resolve(code); - int len = code_oop->length(); - address begin = (address) code_oop->base(T_BYTE); - address end = begin + len; - Disassembler::decode(begin, end, &st); - - Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); - return JNIHandles::make_local(result()); -C2V_END - -C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci)) - ResourceMark rm; - HandleMark hm; - - methodHandle method = asMethod(metaspace_method); - oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL); - return JNIHandles::make_local(element); -C2V_END - -C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args)) - ResourceMark rm; - HandleMark hm; - - assert(metaspace_method != 0, "just checking"); - methodHandle mh = asMethod(metaspace_method); - Symbol* signature = mh->signature(); - JavaCallArguments jca; - - JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static()); - JavaValue result(jap.get_ret_type()); - - nmethod* nm = (nmethod*) (address) metaspace_nmethod; - if (nm == NULL || !nm->is_alive()) { - THROW_0(vmSymbols::MethodInvalidatedException()); - } - - JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL); - - if (jap.get_ret_type() == T_VOID) { - return NULL; - } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) { - return JNIHandles::make_local((oop) result.get_jobject()); - } else { - oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); - return JNIHandles::make_local(o); - } -C2V_END - -C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3)) - ResourceMark rm; - HandleMark hm; - - methodHandle method = asMethod(metaspace_method); - assert(!method.is_null(), "just checking"); - JavaValue result(T_OBJECT); - JavaCallArguments args; - args.push_oop(JNIHandles::resolve(arg1)); - args.push_oop(JNIHandles::resolve(arg2)); - args.push_oop(JNIHandles::resolve(arg3)); - - nmethod* nm = (nmethod*) (address) metaspace_nmethod; - if (nm == NULL || !nm->is_alive()) { - THROW_0(vmSymbols::MethodInvalidatedException()); - } - - JavaCalls::call(&result, method, nm, &args, CHECK_NULL); - - return JNIHandles::make_local((oop) result.get_jobject()); -C2V_END - -C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method)) - - Method* method = asMethod(metaspace_method); - assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods"); - assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked"); - - // get entry offset in words - int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size(); - // convert to bytes - vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes(); - - return vtable_entry_offset; -C2V_END - -C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject)) - - // the contract for this method is as follows: - // returning null: no deopted leaf graphs - // returning array (size > 0): the ids of the deopted leaf graphs - // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely - - oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL); - return JNIHandles::make_local(array); -C2V_END - -C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc)) - stringStream(st); - CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc); - if (blob == NULL) { - st.print("[unidentified pc]"); - } else { - st.print(blob->name()); - - nmethod* nm = blob->as_nmethod_or_null(); - if (nm != NULL && nm->method() != NULL) { - st.print(" %s.", nm->method()->method_holder()->external_name()); - nm->method()->name()->print_symbol_on(&st); - st.print(" @ %d", pc - (jlong) nm->entry_point()); - } - } - Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); - return JNIHandles::make_local(result()); -C2V_END - - -#define CC (char*) /*cast a literal from (const char*)*/ -#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) - -#define RESOLVED_TYPE "Lcom/oracle/graal/api/meta/ResolvedJavaType;" -#define TYPE "Lcom/oracle/graal/api/meta/JavaType;" -#define METHOD "Lcom/oracle/graal/api/meta/JavaMethod;" -#define FIELD "Lcom/oracle/graal/api/meta/JavaField;" -#define SIGNATURE "Lcom/oracle/graal/api/meta/Signature;" -#define CONSTANT_POOL "Lcom/oracle/graal/api/meta/ConstantPool;" -#define CONSTANT "Lcom/oracle/graal/api/meta/Constant;" -#define KIND "Lcom/oracle/graal/api/meta/Kind;" -#define RUNTIME_CALL "Lcom/oracle/graal/api/code/RuntimeCall;" -#define EXCEPTION_HANDLERS "[Lcom/oracle/graal/api/meta/ExceptionHandler;" -#define REFLECT_METHOD "Ljava/lang/reflect/Method;" -#define REFLECT_CONSTRUCTOR "Ljava/lang/reflect/Constructor;" -#define REFLECT_FIELD "Ljava/lang/reflect/Field;" -#define STRING "Ljava/lang/String;" -#define OBJECT "Ljava/lang/Object;" -#define CLASS "Ljava/lang/Class;" -#define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" -#define HS_RESOLVED_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;" -#define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" -#define HS_RESOLVED_FIELD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;" -#define HS_COMP_RESULT "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;" -#define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" -#define HS_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;" -#define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" -#define HS_CODE_INFO "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;" -#define METHOD_DATA "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;" -#define METASPACE_METHOD "J" -#define METASPACE_METHOD_DATA "J" -#define NMETHOD "J" - -JNINativeMethod CompilerToVM_methods[] = { - {CC"initializeBytecode", CC"("METASPACE_METHOD"[B)[B", FN_PTR(initializeBytecode)}, - {CC"getSignature", CC"("METASPACE_METHOD")"STRING, FN_PTR(getSignature)}, - {CC"initializeExceptionHandlers", CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS, FN_PTR(initializeExceptionHandlers)}, - {CC"hasBalancedMonitors", CC"("METASPACE_METHOD")Z", FN_PTR(hasBalancedMonitors)}, - {CC"getUniqueConcreteMethod", CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getUniqueConcreteMethod)}, - {CC"getUniqueImplementor", CC"("HS_RESOLVED_TYPE")"RESOLVED_TYPE, FN_PTR(getUniqueImplementor)}, - {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, - {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, - {CC"initializeMethodData", CC"("METASPACE_METHOD_DATA METHOD_DATA")V", FN_PTR(initializeMethodData)}, - {CC"isMethodCompilable", CC"("METASPACE_METHOD")Z", FN_PTR(isMethodCompilable)}, - {CC"getInvocationCount", CC"("METASPACE_METHOD")I", FN_PTR(getInvocationCount)}, - {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)}, - {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, - {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, - {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)}, - {CC"lookupMethodInPool", CC"("HS_RESOLVED_TYPE"IB)"METHOD, FN_PTR(lookupMethodInPool)}, - {CC"lookupTypeInPool", CC"("HS_RESOLVED_TYPE"I)"TYPE, FN_PTR(lookupTypeInPool)}, - {CC"lookupReferencedTypeInPool", CC"("HS_RESOLVED_TYPE"IB)V", FN_PTR(lookupReferencedTypeInPool)}, - {CC"lookupFieldInPool", CC"("HS_RESOLVED_TYPE"IB)"FIELD, FN_PTR(lookupFieldInPool)}, - {CC"resolveMethod", CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD, FN_PTR(resolveMethod)}, - {CC"getInstanceFields", CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD, FN_PTR(getInstanceFields)}, - {CC"isTypeInitialized", CC"("HS_RESOLVED_TYPE")Z", FN_PTR(isTypeInitialized)}, - {CC"initializeType", CC"("HS_RESOLVED_TYPE")V", FN_PTR(initializeType)}, - {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, - {CC"getResolvedType", CC"("CLASS")"RESOLVED_TYPE, FN_PTR(getResolvedType)}, - {CC"getMetaspaceMethod", CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, - {CC"getMetaspaceConstructor", CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceConstructor)}, - {CC"getJavaField", CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD, FN_PTR(getJavaField)}, - {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, - {CC"installCode0", CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I", FN_PTR(installCode0)}, - {CC"disassembleNative", CC"([BJ)"STRING, FN_PTR(disassembleNative)}, - {CC"executeCompiledMethod", CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, - {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, - {CC"getDeoptedLeafGraphIds", CC"()[J", FN_PTR(getDeoptedLeafGraphIds)}, - {CC"decodePC", CC"(J)"STRING, FN_PTR(decodePC)}, -}; - -int CompilerToVM_methods_count() { - return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod); -} - +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "runtime/fieldDescriptor.hpp" +#include "memory/oopFactory.hpp" +#include "oops/generateOopMap.hpp" +#include "oops/fieldStreams.hpp" +#include "runtime/javaCalls.hpp" +#include "graal/graalRuntime.hpp" +#include "compiler/compileBroker.hpp" +#include "compiler/compilerOracle.hpp" +#include "graal/graalCompilerToVM.hpp" +#include "graal/graalCompiler.hpp" +#include "graal/graalEnv.hpp" +#include "graal/graalJavaAccess.hpp" +#include "graal/graalCodeInstaller.hpp" +#include "graal/graalVMToCompiler.hpp" +#include "graal/graalVmIds.hpp" + + +Method* getMethodFromHotSpotMethod(oop hotspot_method) { + assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethod::klass()), "sanity"); + return asMethod(HotSpotResolvedJavaMethod::metaspaceMethod(hotspot_method)); +} + +// Entry to native method implementation that transitions current thread to '_thread_in_vm'. +#define C2V_VMENTRY(result_type, name, signature) \ + JNIEXPORT result_type JNICALL c2v_ ## name signature { \ + TRACE_graal_3("CompilerToVM::" #name); \ + GRAAL_VM_ENTRY_MARK; \ + +// Entry to native method implementation that calls a JNI function +// and hence cannot transition current thread to '_thread_in_vm'. +#define C2V_ENTRY(result_type, name, signature) \ + JNIEXPORT result_type JNICALL c2v_ ## name signature { \ + TRACE_graal_3("CompilerToVM::" #name); \ + +#define C2V_END } + +C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result)) + methodHandle method = asMethod(metaspace_method); + ResourceMark rm; + + int code_size = method->code_size(); + jbyte* reconstituted_code = NULL; + + // replace all breakpoints - must be done before undoing any rewriting + if (method->number_of_breakpoints() > 0) { + reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size); + memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size); + BreakpointInfo* bp = InstanceKlass::cast(method->method_holder())->breakpoints(); + for (; bp != NULL; bp = bp->next()) { + if (bp->match(method())) { + jbyte code = bp->orig_bytecode(); + reconstituted_code[bp->bci()] = code; + } + } + } + + // iterate over all bytecodes and replace non-Java bytecodes + if (RewriteBytecodes || RewriteFrequentPairs || InstanceKlass::cast(method->method_holder())->is_rewritten()) { + if (reconstituted_code == NULL) { + reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size); + memcpy(reconstituted_code, (jbyte *) method->code_base(), code_size); + } + BytecodeStream s(method); + while(!s.is_last_bytecode()) { + s.next(); + Bytecodes::Code opcode = s.raw_code(); + if (!Bytecodes::is_java_code(opcode)) { + jbyte original_opcode = Bytecodes::java_code(opcode); + int bci = s.bci(); + reconstituted_code[bci] = original_opcode; + if (opcode == Bytecodes::_fast_aldc_w) { + int cpci = Bytes::get_native_u2((address) reconstituted_code + bci + 1); + int i = method->constants()->object_to_cp_index(cpci); + assert(i < method->constants()->length(), "sanity check"); + Bytes::put_Java_u2((address) reconstituted_code + bci + 1, (u2)i); + } else if (opcode == Bytecodes::_fast_aldc) { + int cpci = reconstituted_code[bci + 1] & 0xff; + int i = method->constants()->object_to_cp_index(cpci); + assert(i < method->constants()->length(), "sanity check"); + reconstituted_code[bci + 1] = (jbyte)i; + } + } + } + } + + if (reconstituted_code == NULL) { + env->SetByteArrayRegion(result, 0, code_size, (jbyte *) method->code_base()); + } else { + env->SetByteArrayRegion(result, 0, code_size, reconstituted_code); + } + + return result; +C2V_END + +C2V_VMENTRY(jstring, getSignature, (JNIEnv *env, jobject, jlong metaspace_method)) + Method* method = asMethod(metaspace_method); + assert(method != NULL && method->signature() != NULL, "signature required"); + return VmIds::toString(method->signature(), THREAD); +C2V_END + +C2V_VMENTRY(jobjectArray, initializeExceptionHandlers, (JNIEnv *, jobject, jlong metaspace_method, jobjectArray java_handlers)) + ResourceMark rm; + methodHandle method = asMethod(metaspace_method); + int handler_count = method->exception_table_length(); + objArrayHandle array = (objArrayOop) JNIHandles::resolve(java_handlers); + assert(array->length() == handler_count, "wrong length"); + ExceptionTableElement* handlers = handler_count == 0 ? NULL : method->exception_table_start(); + + for (int i = 0; i < handler_count; i++) { + ExceptionTableElement* handler = handlers + i; + Handle entry = array->obj_at(i); + assert(!entry.is_null(), "entry should not be null"); + ExceptionHandler::set_startBCI(entry, handler->start_pc); + ExceptionHandler::set_endBCI(entry, handler->end_pc); + ExceptionHandler::set_handlerBCI(entry, handler->handler_pc); + int catch_class_index = handler->catch_type_index; + ExceptionHandler::set_catchTypeCPI(entry, catch_class_index); + + if (catch_class_index == 0) { + ExceptionHandler::set_catchType(entry, NULL); + } else { + ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants(); + KlassHandle loading_klass = method->method_holder(); + Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL); + if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) { + ExceptionHandler::set_catchType(entry, NULL); + ExceptionHandler::set_catchTypeCPI(entry, 0); + } else { + ExceptionHandler::set_catchType(entry, catch_class()); + } + } + array->obj_at_put(i, entry()); + } + + return (jobjectArray) JNIHandles::make_local(array()); +C2V_END + +C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method)) + + // Analyze the method to see if monitors are used properly. + methodHandle method(THREAD, asMethod(metaspace_method)); + assert(method->has_monitor_bytecodes(), "should have checked this"); + + // Check to see if a previous compilation computed the monitor-matching analysis. + if (method->guaranteed_monitor_matching()) { + return true; + } + + { + EXCEPTION_MARK; + ResourceMark rm(THREAD); + GeneratePairingInfo gpi(method); + gpi.compute_map(CATCH); + if (!gpi.monitor_safe()) { + return false; + } + method->set_guaranteed_monitor_matching(); + } + return true; +C2V_END + +C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jobject reflection_method_handle, jobject resultHolder)) + oop reflection_method = JNIHandles::resolve(reflection_method_handle); + oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method); + int slot = java_lang_reflect_Method::slot(reflection_method); + Klass* holder = java_lang_Class::as_Klass(reflection_holder); + methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); + Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0); + objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); + return (jlong) (address) method(); +} + +C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder)) + oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle); + oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor); + int slot = java_lang_reflect_Constructor::slot(reflection_ctor); + Klass* holder = java_lang_Class::as_Klass(reflection_holder); + methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); + Handle type = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK_0); + objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); + return (jlong) (address) method(); +} + +C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle)) + oop reflection_field = JNIHandles::resolve(reflection_field_handle); + oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field); + int slot = java_lang_reflect_Field::slot(reflection_field); + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(reflection_holder)); + + int offset = holder->field_offset(slot); + int flags = holder->field_access_flags(slot); + Symbol* field_name = holder->field_name(slot); + Handle field_holder = GraalCompiler::get_JavaTypeFromClass(reflection_holder, CHECK_NULL); + Handle field_type = GraalCompiler::get_JavaTypeFromClass(java_lang_reflect_Field::type(reflection_field), CHECK_NULL); + + Handle ret = GraalCompiler::get_JavaField(offset, flags, field_name, field_holder, field_type, CHECK_NULL); + return JNIHandles::make_local(THREAD, ret()); +} + +C2V_VMENTRY(jlong, getUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method, jobject resultHolder)) + methodHandle method = asMethod(metaspace_method); + KlassHandle holder = method->method_holder(); + // TODO (chaeubl): check if the following is necessary + //if (holder->is_interface()) { + // // Cannot trust interfaces. Because of: + // // interface I { void foo(); } + // // class A { public void foo() {} } + // // class B extends A implements I { } + // // class C extends B { public void foo() { } } + // // class D extends B { } + // // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo(). + // return 0L; + //} + methodHandle ucm; + { + ResourceMark rm; + MutexLocker locker(Compile_lock); + ucm = Dependencies::find_unique_concrete_method(holder(), method()); + } + + if (ucm.is_null()) { + return 0L; + } + + Handle type = GraalCompiler::createHotSpotResolvedObjectType(ucm(), CHECK_0); + objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); + return (jlong) (address) ucm(); +C2V_END + +C2V_VMENTRY(jobject, getUniqueImplementor, (JNIEnv *, jobject, jobject interface_type)) + InstanceKlass* klass = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(interface_type)); + assert(klass->is_interface(), "must be"); + if (klass->nof_implementors() == 1) { + InstanceKlass* implementor = (InstanceKlass*) klass->implementor(); + if (!implementor->is_abstract() && !implementor->is_interface() && implementor->is_leaf_class()) { + Handle type = GraalCompiler::get_JavaType(implementor, CHECK_NULL); + return JNIHandles::make_local(THREAD, type()); + } + } + return NULL; +C2V_END + +C2V_ENTRY(jint, getInvocationCount, (JNIEnv *, jobject, jlong metaspace_method)) + Method* method = asMethod(metaspace_method); + return method->invocation_count(); +C2V_END + +C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method)) + methodHandle method = asMethod(metaspace_method); + Handle name = VmIds::toString(method->name(), CHECK); + InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK); + HotSpotResolvedJavaMethod::set_name(hotspot_method, name()); + HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size()); + HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length()); +C2V_END + +C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method)) + methodHandle method = asMethod(metaspace_method); + return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method); +C2V_END + +C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data)) + MethodData* method_data = asMethodData(metaspace_method_data); + HotSpotMethodData::set_normalDataSize(hotspot_method_data, method_data->data_size()); + HotSpotMethodData::set_extraDataSize(hotspot_method_data, method_data->extra_data_size()); +C2V_END + +// ------------------------------------------------------------------ +// Adjust a CounterData count to be commensurate with +// interpreter_invocation_count. If the MDO exists for +// only 25% of the time the method exists, then the +// counts in the MDO should be scaled by 4X, so that +// they can be usefully and stably compared against the +// invocation counts in methods. +int scale_count(MethodData* method_data, int count) { + if (count > 0) { + int counter_life; + int method_life = method_data->method()->interpreter_invocation_count(); + int current_mileage = MethodData::mileage_of(method_data->method()); + int creation_mileage = method_data->creation_mileage(); + counter_life = current_mileage - creation_mileage; + + // counter_life due to backedge_counter could be > method_life + if (counter_life > method_life) + counter_life = method_life; + if (0 < counter_life && counter_life <= method_life) { + count = (int)((double)count * method_life / counter_life + 0.5); + count = (count > 0) ? count : 1; + } + } + return count; +} + +C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method)) + nmethod* code = (asMethod(metaspace_method))->code(); + return code == NULL ? 0 : code->insts_size(); +C2V_END + +C2V_VMENTRY(jobject, lookupType, (JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve)) + ResourceMark rm; + + Symbol* nameSymbol = VmIds::toSymbol(jname); + Handle name = JNIHandles::resolve(jname); + assert(nameSymbol != NULL, "name to symbol creation failed"); + + oop result = NULL; + if (nameSymbol == vmSymbols::int_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD); + } else if (nameSymbol == vmSymbols::long_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD); + } else if (nameSymbol == vmSymbols::bool_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD); + } else if (nameSymbol == vmSymbols::char_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD); + } else if (nameSymbol == vmSymbols::short_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD); + } else if (nameSymbol == vmSymbols::byte_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD); + } else if (nameSymbol == vmSymbols::double_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD); + } else if (nameSymbol == vmSymbols::float_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD); + } else if (nameSymbol == vmSymbols::void_signature()) { + result = VMToCompiler::createPrimitiveJavaType((int) T_VOID, THREAD); + } else { + Klass* resolved_type = NULL; + Handle classloader; + Handle protectionDomain; + if (JNIHandles::resolve(accessingClass) != NULL) { + classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader(); + protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain(); + } + + if (eagerResolve) { + resolved_type = SystemDictionary::resolve_or_fail(nameSymbol, classloader, protectionDomain, true, THREAD); + } else { + resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); + } + + if (!HAS_PENDING_EXCEPTION) { + if (resolved_type == NULL) { + assert(!eagerResolve, "failed eager resolution should have caused an exception"); + Handle type = VMToCompiler::createUnresolvedJavaType(name, THREAD); + result = type(); + } else { + Handle type = GraalCompiler::createHotSpotResolvedObjectType(resolved_type, name, CHECK_NULL); + result = type(); + } + } + } + + return JNIHandles::make_local(THREAD, result); +C2V_END + +C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jobject type, jint index)) + + ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); + + oop result = NULL; + constantTag tag = cp->tag_at(index); + if (tag.is_int()) { + result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0); + } else if (tag.is_long()) { + result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0); + } else if (tag.is_float()) { + result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0); + } else if (tag.is_double()) { + result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0); + } else if (tag.is_string()) { + oop string = NULL; + if (cp->is_pseudo_string_at(index)) { + int obj_index = cp->cp_to_object_index(index); + string = cp->pseudo_string_at(index, obj_index); + } else { + string = cp->string_at(index, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + // TODO: Gracefully exit compilation. + fatal("out of memory during compilation!"); + return NULL; + } + } + result = VMToCompiler::createConstantObject(string, CHECK_0); + } else if (tag.is_klass() || tag.is_unresolved_klass()) { + Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL); + result = type(); + } else if (tag.is_object()) { + oop obj = cp->object_at(index); + assert(obj->is_instance(), "must be an instance"); + result = VMToCompiler::createConstantObject(obj, CHECK_NULL); + } else { + tty->print("unknown constant pool tag (%s) at cpi %d in %s: ", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string()); + ShouldNotReachHere(); + } + + return JNIHandles::make_local(THREAD, result); +C2V_END + +C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode)) + index = GraalCompiler::to_cp_index_u2(index); + constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); + instanceKlassHandle pool_holder(cp->pool_holder()); + + Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); + methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder); + if (!method.is_null()) { + Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD)); + } else { + // Get the method's name and signature. + Handle name = VmIds::toString(cp->name_ref_at(index), CHECK_NULL); + Handle signature = VmIds::toString(cp->signature_ref_at(index), CHECK_NULL); + int holder_index = cp->klass_ref_index_at(index); + Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMToCompiler::createUnresolvedJavaMethod(name, signature, type, THREAD)); + } +C2V_END + +C2V_VMENTRY(jobject, lookupTypeInPool, (JNIEnv *env, jobject, jobject type, jint index)) + + ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); + Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, result()); +C2V_END + +C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op)) + ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); + int opcode = (op & 0xFF); + if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray + && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w) + { + index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index_u2(index)); + } + constantTag tag = cp->tag_at(index); + if (tag.is_field_or_method()) { + index = cp->uncached_klass_ref_index_at(index); + tag = cp->tag_at(index); + } + + if (tag.is_unresolved_klass() || tag.is_klass()) { + Klass* klass = cp->klass_at(index, CHECK); + if (klass->oop_is_instance()) { + InstanceKlass::cast(klass)->initialize(CHECK); + } + } +C2V_END + +C2V_VMENTRY(jobject, lookupFieldInPool, (JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte opcode)) + ResourceMark rm; + + index = GraalCompiler::to_cp_index_u2(index); + constantPoolHandle cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(constantPoolHolder)))->constants(); + + int nt_index = cp->name_and_type_ref_index_at(index); + int sig_index = cp->signature_ref_index_at(nt_index); + Symbol* signature = cp->symbol_at(sig_index); + int name_index = cp->name_ref_index_at(nt_index); + Symbol* name = cp->symbol_at(name_index); + int holder_index = cp->klass_ref_index_at(index); + Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + instanceKlassHandle holder_klass; + + Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF); + int offset = -1; + AccessFlags flags; + BasicType basic_type; + if (holder->klass() == SystemDictionary::HotSpotResolvedObjectType_klass()) { + FieldAccessInfo result; + LinkResolver::resolve_field(result, cp, index, + Bytecodes::java_code(code), + true, false, Thread::current()); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + } else { + offset = result.field_offset(); + flags = result.access_flags(); + holder_klass = result.klass()(); + basic_type = result.field_type(); + holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL); + } + } + + Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL); + Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD); + + return JNIHandles::make_local(THREAD, field_handle()); +C2V_END + +C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature)) + + assert(JNIHandles::resolve(resolved_type) != NULL, ""); + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type)); + Symbol* name_symbol = VmIds::toSymbol(name); + Symbol* signature_symbol = VmIds::toSymbol(signature); + methodHandle method = klass->lookup_method(name_symbol, signature_symbol); + if (method.is_null()) { + if (TraceGraal >= 3) { + ResourceMark rm; + tty->print_cr("Could not resolve method %s %s on klass %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), klass->name()->as_C_string()); + } + return NULL; + } + Handle holder = GraalCompiler::get_JavaType(method->method_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMToCompiler::createResolvedJavaMethod(holder, method(), THREAD)); +C2V_END + +C2V_VMENTRY(jboolean, isTypeInitialized,(JNIEnv *, jobject, jobject hotspot_klass)) + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); + assert(klass != NULL, "method must not be called for primitive types"); + return InstanceKlass::cast(klass)->is_initialized(); +C2V_END + +C2V_VMENTRY(void, initializeType, (JNIEnv *, jobject, jobject hotspot_klass)) + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass)); + assert(klass != NULL, "method must not be called for primitive types"); + InstanceKlass::cast(klass)->initialize(JavaThread::current()); +C2V_END + +C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass)) + ResourceMark rm; + + instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)); + GrowableArray fields(k->java_fields_count()); + + for (AllFieldStream fs(k()); !fs.done(); fs.next()) { + if (!fs.access_flags().is_static()) { + Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, Thread::current()); + int flags = fs.access_flags().as_int(); + bool internal = fs.access_flags().is_internal(); + Handle name = VmIds::toString(fs.name(), Thread::current()); + Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, Thread::current()); + fields.append(field()); + } + } + objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL); + for (int i = 0; i < fields.length(); ++i) { + field_array->obj_at_put(i, fields.at(i)()); + } + return JNIHandles::make_local(field_array()); +C2V_END + +C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub)) + address target_addr = (address) stub; + if (target_addr != 0x0) { + int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); + int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); + return MAX2(ABS(off_low), ABS(off_high)); + } + return -1; +C2V_END + +C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass)) + oop java_mirror = JNIHandles::resolve(javaClass); + assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL"); + Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL); + return JNIHandles::make_local(THREAD, type()); +C2V_END + + +// helpers used to set fields in the HotSpotVMConfig object +jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { + jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig); + if (id == NULL) { + fatal(err_msg("field not found: %s (%s)", name, sig)); + } + return id; +} + +BasicType basicTypes[] = { T_BOOLEAN, T_BYTE, T_SHORT, T_CHAR, T_INT, T_FLOAT, T_LONG, T_DOUBLE, T_OBJECT }; +int basicTypeCount = sizeof(basicTypes) / sizeof(BasicType); + +C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config)) + +#define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0) +#define set_int(name, value) do { env->SetIntField(config, getFieldID(env, config, name, "I"), value); } while (0) +#define set_long(name, value) do { env->SetLongField(config, getFieldID(env, config, name, "J"), value); } while (0) +#define set_object(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "Ljava/lang/Object;"), value); } while (0) +#define set_int_array(name, value) do { env->SetObjectField(config, getFieldID(env, config, name, "[I"), value); } while (0) + + guarantee(HeapWordSize == sizeof(char*), "Graal assumption that HeadWordSize == machine word size is wrong"); +#ifdef _WIN64 + set_boolean("windowsOs", true); +#else + set_boolean("windowsOs", false); +#endif + set_boolean("verifyOops", VerifyOops); + set_boolean("useFastLocking", GraalUseFastLocking); + set_boolean("useBiasedLocking", UseBiasedLocking); + set_boolean("useTLAB", UseTLAB); + set_int("codeEntryAlignment", CodeEntryAlignment); + set_int("vmPageSize", os::vm_page_size()); + set_int("stackShadowPages", StackShadowPages); + set_int("hubOffset", oopDesc::klass_offset_in_bytes()); + set_int("markOffset", oopDesc::mark_offset_in_bytes()); + set_int("prototypeMarkWordOffset", in_bytes(Klass::prototype_header_offset())); + set_int("superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset())); + set_int("secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset())); + set_int("secondarySupersOffset", in_bytes(Klass::secondary_supers_offset())); + set_int("subklassOffset", in_bytes(Klass::subklass_offset())); + set_int("nextSiblingOffset", in_bytes(Klass::next_sibling_offset())); + set_int("arrayLengthOffset", arrayOopDesc::length_offset_in_bytes()); + set_int("klassStateOffset", in_bytes(InstanceKlass::init_state_offset())); + set_int("klassStateFullyInitialized", (int)InstanceKlass::fully_initialized); + set_int("threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset())); + set_int("threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset())); + set_int("threadObjectOffset", in_bytes(JavaThread::threadObj_offset())); + set_int("osThreadOffset", in_bytes(JavaThread::osthread_offset())); + set_int("osThreadInterruptedOffset", in_bytes(OSThread::interrupted_offset())); + set_int("unlockedMask", (int) markOopDesc::unlocked_value); + set_int("biasedLockMaskInPlace", (int) markOopDesc::biased_lock_mask_in_place); + set_int("ageMaskInPlace", (int) markOopDesc::age_mask_in_place); + set_int("epochMaskInPlace", (int) markOopDesc::epoch_mask_in_place); + set_int("biasedLockPattern", (int) markOopDesc::biased_lock_pattern); + set_int("methodMaxLocalsOffset", in_bytes(Method::size_of_locals_offset())); + set_int("methodMaxStackOffset", in_bytes(Method::max_stack_offset())); + set_int("extraStackEntries", Method::extra_stack_entries()); + set_int("methodAccessFlagsOffset", in_bytes(Method::access_flags_offset())); + set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER); + set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset())); + set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); + set_boolean("isPollingPageFar", Assembler::is_polling_page_far()); + set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset())); + set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes); + set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset())); + set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset())); + set_int("klassOffset", java_lang_Class::klass_offset_in_bytes()); + set_int("graalMirrorInClassOffset", java_lang_Class::graal_mirror_offset_in_bytes()); + set_int("klassLayoutHelperOffset", in_bytes(Klass::layout_helper_offset())); + set_int("klassSuperKlassOffset", in_bytes(Klass::super_offset())); + set_int("methodDataOffset", in_bytes(Method::method_data_offset())); + set_int("nmethodEntryOffset", nmethod::verified_entry_point_offset()); + set_int("methodCompiledEntryOffset", in_bytes(Method::from_compiled_offset())); + set_int("basicLockSize", sizeof(BasicLock)); + set_int("basicLockDisplacedHeaderOffset", BasicLock::displaced_header_offset_in_bytes()); + set_int("uninitializedIdentityHashCodeValue", markOopDesc::no_hash); + set_int("identityHashCodeShift", markOopDesc::hash_shift); + + set_int("arrayKlassLayoutHelperIdentifier", 0x80000000); + assert((Klass::_lh_array_tag_obj_value & Klass::_lh_array_tag_type_value & 0x80000000) != 0, "obj_array and type_array must have first bit set"); + set_int("arrayKlassComponentMirrorOffset", in_bytes(ArrayKlass::component_mirror_offset())); + + set_int("metaspaceArrayLengthOffset", Array::length_offset_in_bytes()); + set_int("metaspaceArrayBaseOffset", Array::base_offset_in_bytes()); + set_int("methodDataOopDataOffset", in_bytes(MethodData::data_offset())); + set_int("methodDataOopTrapHistoryOffset", in_bytes(MethodData::trap_history_offset())); + set_int("dataLayoutHeaderSize", DataLayout::header_size_in_bytes()); + set_int("dataLayoutTagOffset", in_bytes(DataLayout::tag_offset())); + set_int("dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset())); + set_int("dataLayoutBCIOffset", in_bytes(DataLayout::bci_offset())); + set_int("dataLayoutCellsOffset", in_bytes(DataLayout::cell_offset(0))); + set_int("dataLayoutCellSize", DataLayout::cell_size); + set_int("bciProfileWidth", BciProfileWidth); + set_int("typeProfileWidth", TypeProfileWidth); + + set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve()); + set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2)); + set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr()); + set_long("heapEndAddress", (jlong)(address) Universe::heap()->end_addr()); + set_int("threadTlabStartOffset", in_bytes(JavaThread::tlab_start_offset())); + set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset())); + set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset())); + set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset())); + set_int("tlabFastRefillWasteOffset", in_bytes(JavaThread::tlab_fast_refill_waste_offset())); + set_int("tlabNumberOfRefillsOffset", in_bytes(JavaThread::tlab_number_of_refills_offset())); + set_int("tlabRefillWasteLimitOffset", in_bytes(JavaThread::tlab_refill_waste_limit_offset())); + set_int("tlabRefillWasteIncrement", (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment()); + set_int("klassInstanceSizeOffset", in_bytes(Klass::layout_helper_offset())); + set_boolean("tlabStats", TLABStats); + set_boolean("inlineContiguousAllocationSupported", !CMSIncrementalMode && Universe::heap()->supports_inline_contig_alloc()); + + set_long("arrayPrototypeMarkWord", (intptr_t)markOopDesc::prototype()); + set_int("layoutHelperLog2ElementSizeShift", Klass::_lh_log2_element_size_shift); + set_int("layoutHelperLog2ElementSizeMask", Klass::_lh_log2_element_size_mask); + set_int("layoutHelperElementTypeShift", Klass::_lh_element_type_shift); + set_int("layoutHelperElementTypeMask", Klass::_lh_element_type_mask); + set_int("layoutHelperHeaderSizeShift", Klass::_lh_header_size_shift); + set_int("layoutHelperHeaderSizeMask", Klass::_lh_header_size_mask); + set_int("layoutHelperOffset", in_bytes(Klass::layout_helper_offset())); + + set_long("debugStub", VmIds::addStub((address)warning)); + set_long("instanceofStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_slow_subtype_check_id))); + set_long("newInstanceStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_instance_id))); + set_long("newArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_array_id))); + set_long("newMultiArrayStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_new_multi_array_id))); + set_long("identityHashCodeStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_identity_hash_code_id))); + set_long("threadIsInterruptedStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_thread_is_interrupted_id))); + set_long("inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub())); + set_long("handleExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_handle_exception_nofpu_id))); + set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack())); + set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id))); + set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id))); + set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id))); + set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id))); + set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap())); + set_long("unwindExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_unwind_exception_call_id))); + set_long("osrMigrationEndStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_OSR_migration_end_id))); + set_long("registerFinalizerStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_register_finalizer_id))); + set_long("setDeoptInfoStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_set_deopt_info_id))); + set_long("createNullPointerExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_null_pointer_exception_id))); + set_long("createOutOfBoundsExceptionStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_create_out_of_bounds_exception_id))); + set_long("javaTimeMillisStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeMillis))); + set_long("javaTimeNanosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, os::javaTimeNanos))); + set_long("arithmeticFremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_frem_id))); + set_long("arithmeticDremStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_arithmetic_drem_id))); + set_long("arithmeticSinStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dsin))); + set_long("arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); + set_long("arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); + set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id))); + set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id))); + set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id))); + + set_int("deoptReasonNone", Deoptimization::Reason_none); + set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check); + set_int("deoptReasonRangeCheck", Deoptimization::Reason_range_check); + set_int("deoptReasonClassCheck", Deoptimization::Reason_class_check); + set_int("deoptReasonArrayCheck", Deoptimization::Reason_array_check); + set_int("deoptReasonUnreached0", Deoptimization::Reason_unreached0); + set_int("deoptReasonTypeCheckInlining", Deoptimization::Reason_type_checked_inlining); + set_int("deoptReasonOptimizedTypeCheck", Deoptimization::Reason_optimized_type_check); + set_int("deoptReasonNotCompiledExceptionHandler", Deoptimization::Reason_not_compiled_exception_handler); + set_int("deoptReasonUnresolved", Deoptimization::Reason_unresolved); + set_int("deoptReasonJsrMismatch", Deoptimization::Reason_jsr_mismatch); + set_int("deoptReasonDiv0Check", Deoptimization::Reason_div0_check); + set_int("deoptReasonConstraint", Deoptimization::Reason_constraint); + + set_int("deoptActionNone", Deoptimization::Action_none); + set_int("deoptActionMaybeRecompile", Deoptimization::Action_maybe_recompile); + set_int("deoptActionReinterpret", Deoptimization::Action_reinterpret); + set_int("deoptActionMakeNotEntrant", Deoptimization::Action_make_not_entrant); + set_int("deoptActionMakeNotCompilable", Deoptimization::Action_make_not_compilable); + + + BarrierSet* bs = Universe::heap()->barrier_set(); + switch (bs->kind()) { + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: { + jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base; + assert(base != 0, "unexpected byte_map_base"); + set_long("cardtableStartAddress", base); + set_int("cardtableShift", CardTableModRefBS::card_shift); + break; + } + case BarrierSet::ModRef: + case BarrierSet::Other: + set_long("cardtableStartAddress", 0); + set_int("cardtableShift", 0); + // No post barriers + break; +#ifndef SERIALGC + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging: +#endif // SERIALGC + default: + ShouldNotReachHere(); + break; + } + + set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset())); + +#undef set_boolean +#undef set_int +#undef set_long +#undef set_object +#undef set_int_array + +C2V_END + +C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compResult, jobject installed_code, jobject info)) + ResourceMark rm; + HandleMark hm; + Handle compResultHandle = JNIHandles::resolve(compResult); + nmethod* nm = NULL; + methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult)); + Handle installed_code_handle = JNIHandles::resolve(installed_code); + GraalEnv::CodeInstallResult result; + CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle); + + if (result != GraalEnv::ok) { + assert(nm == NULL, "should be"); + } else { + if (info != NULL) { + arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0); + memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size()); + HotSpotCodeInfo::set_code(info, codeCopy); + HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin()); + } + + if (!installed_code_handle.is_null()) { + assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); + HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm); + HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult)); + assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable"); + } + } + return result; +C2V_END + +C2V_VMENTRY(jobject, disassembleNative, (JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address)) + ResourceMark rm; + HandleMark hm; + + stringStream(st); + arrayOop code_oop = (arrayOop) JNIHandles::resolve(code); + int len = code_oop->length(); + address begin = (address) code_oop->base(T_BYTE); + address end = begin + len; + Disassembler::decode(begin, end, &st); + + Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); + return JNIHandles::make_local(result()); +C2V_END + +C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv *env, jobject, jlong metaspace_method, int bci)) + ResourceMark rm; + HandleMark hm; + + methodHandle method = asMethod(metaspace_method); + oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL); + return JNIHandles::make_local(element); +C2V_END + +C2V_VMENTRY(jobject, executeCompiledMethodVarargs, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject args)) + ResourceMark rm; + HandleMark hm; + + assert(metaspace_method != 0, "just checking"); + methodHandle mh = asMethod(metaspace_method); + Symbol* signature = mh->signature(); + JavaCallArguments jca; + + JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static()); + JavaValue result(jap.get_ret_type()); + + nmethod* nm = (nmethod*) (address) metaspace_nmethod; + if (nm == NULL || !nm->is_alive()) { + THROW_0(vmSymbols::MethodInvalidatedException()); + } + + JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL); + + if (jap.get_ret_type() == T_VOID) { + return NULL; + } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) { + return JNIHandles::make_local((oop) result.get_jobject()); + } else { + oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); + return JNIHandles::make_local(o); + } +C2V_END + +C2V_VMENTRY(jobject, executeCompiledMethod, (JNIEnv *env, jobject, jlong metaspace_method, jlong metaspace_nmethod, jobject arg1, jobject arg2, jobject arg3)) + ResourceMark rm; + HandleMark hm; + + methodHandle method = asMethod(metaspace_method); + assert(!method.is_null(), "just checking"); + JavaValue result(T_OBJECT); + JavaCallArguments args; + args.push_oop(JNIHandles::resolve(arg1)); + args.push_oop(JNIHandles::resolve(arg2)); + args.push_oop(JNIHandles::resolve(arg3)); + + nmethod* nm = (nmethod*) (address) metaspace_nmethod; + if (nm == NULL || !nm->is_alive()) { + THROW_0(vmSymbols::MethodInvalidatedException()); + } + + JavaCalls::call(&result, method, nm, &args, CHECK_NULL); + + return JNIHandles::make_local((oop) result.get_jobject()); +C2V_END + +C2V_VMENTRY(jint, getVtableEntryOffset, (JNIEnv *, jobject, jlong metaspace_method)) + + Method* method = asMethod(metaspace_method); + assert(!InstanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods"); + assert(InstanceKlass::cast(method->method_holder())->is_linked(), "vtableEntryOffset cannot be called is holder is not linked"); + + // get entry offset in words + int vtable_entry_offset = InstanceKlass::vtable_start_offset() + method->vtable_index() * vtableEntry::size(); + // convert to bytes + vtable_entry_offset = vtable_entry_offset * wordSize + vtableEntry::method_offset_in_bytes(); + + return vtable_entry_offset; +C2V_END + +C2V_VMENTRY(jobject, getDeoptedLeafGraphIds, (JNIEnv *, jobject)) + + // the contract for this method is as follows: + // returning null: no deopted leaf graphs + // returning array (size > 0): the ids of the deopted leaf graphs + // returning array (size == 0): there was an overflow, the compiler needs to clear its cache completely + + oop array = GraalCompiler::instance()->dump_deopted_leaf_graphs(CHECK_NULL); + return JNIHandles::make_local(array); +C2V_END + +C2V_VMENTRY(jobject, decodePC, (JNIEnv *, jobject, jlong pc)) + stringStream(st); + CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc); + if (blob == NULL) { + st.print("[unidentified pc]"); + } else { + st.print(blob->name()); + + nmethod* nm = blob->as_nmethod_or_null(); + if (nm != NULL && nm->method() != NULL) { + st.print(" %s.", nm->method()->method_holder()->external_name()); + nm->method()->name()->print_symbol_on(&st); + st.print(" @ %d", pc - (jlong) nm->entry_point()); + } + } + Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL); + return JNIHandles::make_local(result()); +C2V_END + + +#define CC (char*) /*cast a literal from (const char*)*/ +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) + +#define RESOLVED_TYPE "Lcom/oracle/graal/api/meta/ResolvedJavaType;" +#define TYPE "Lcom/oracle/graal/api/meta/JavaType;" +#define METHOD "Lcom/oracle/graal/api/meta/JavaMethod;" +#define FIELD "Lcom/oracle/graal/api/meta/JavaField;" +#define SIGNATURE "Lcom/oracle/graal/api/meta/Signature;" +#define CONSTANT_POOL "Lcom/oracle/graal/api/meta/ConstantPool;" +#define CONSTANT "Lcom/oracle/graal/api/meta/Constant;" +#define KIND "Lcom/oracle/graal/api/meta/Kind;" +#define RUNTIME_CALL "Lcom/oracle/graal/api/code/RuntimeCall;" +#define EXCEPTION_HANDLERS "[Lcom/oracle/graal/api/meta/ExceptionHandler;" +#define REFLECT_METHOD "Ljava/lang/reflect/Method;" +#define REFLECT_CONSTRUCTOR "Ljava/lang/reflect/Constructor;" +#define REFLECT_FIELD "Ljava/lang/reflect/Field;" +#define STRING "Ljava/lang/String;" +#define OBJECT "Ljava/lang/Object;" +#define CLASS "Ljava/lang/Class;" +#define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" +#define HS_RESOLVED_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;" +#define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" +#define HS_RESOLVED_FIELD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;" +#define HS_COMP_RESULT "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;" +#define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" +#define HS_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;" +#define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" +#define HS_CODE_INFO "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;" +#define METHOD_DATA "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;" +#define METASPACE_METHOD "J" +#define METASPACE_METHOD_DATA "J" +#define NMETHOD "J" + +JNINativeMethod CompilerToVM_methods[] = { + {CC"initializeBytecode", CC"("METASPACE_METHOD"[B)[B", FN_PTR(initializeBytecode)}, + {CC"getSignature", CC"("METASPACE_METHOD")"STRING, FN_PTR(getSignature)}, + {CC"initializeExceptionHandlers", CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS, FN_PTR(initializeExceptionHandlers)}, + {CC"hasBalancedMonitors", CC"("METASPACE_METHOD")Z", FN_PTR(hasBalancedMonitors)}, + {CC"getUniqueConcreteMethod", CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getUniqueConcreteMethod)}, + {CC"getUniqueImplementor", CC"("HS_RESOLVED_TYPE")"RESOLVED_TYPE, FN_PTR(getUniqueImplementor)}, + {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, + {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, + {CC"initializeMethodData", CC"("METASPACE_METHOD_DATA METHOD_DATA")V", FN_PTR(initializeMethodData)}, + {CC"isMethodCompilable", CC"("METASPACE_METHOD")Z", FN_PTR(isMethodCompilable)}, + {CC"getInvocationCount", CC"("METASPACE_METHOD")I", FN_PTR(getInvocationCount)}, + {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)}, + {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, + {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, + {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)}, + {CC"lookupMethodInPool", CC"("HS_RESOLVED_TYPE"IB)"METHOD, FN_PTR(lookupMethodInPool)}, + {CC"lookupTypeInPool", CC"("HS_RESOLVED_TYPE"I)"TYPE, FN_PTR(lookupTypeInPool)}, + {CC"lookupReferencedTypeInPool", CC"("HS_RESOLVED_TYPE"IB)V", FN_PTR(lookupReferencedTypeInPool)}, + {CC"lookupFieldInPool", CC"("HS_RESOLVED_TYPE"IB)"FIELD, FN_PTR(lookupFieldInPool)}, + {CC"resolveMethod", CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD, FN_PTR(resolveMethod)}, + {CC"getInstanceFields", CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD, FN_PTR(getInstanceFields)}, + {CC"isTypeInitialized", CC"("HS_RESOLVED_TYPE")Z", FN_PTR(isTypeInitialized)}, + {CC"initializeType", CC"("HS_RESOLVED_TYPE")V", FN_PTR(initializeType)}, + {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, + {CC"getResolvedType", CC"("CLASS")"RESOLVED_TYPE, FN_PTR(getResolvedType)}, + {CC"getMetaspaceMethod", CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, + {CC"getMetaspaceConstructor", CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceConstructor)}, + {CC"getJavaField", CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD, FN_PTR(getJavaField)}, + {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, + {CC"installCode0", CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")I", FN_PTR(installCode0)}, + {CC"disassembleNative", CC"([BJ)"STRING, FN_PTR(disassembleNative)}, + {CC"executeCompiledMethod", CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT, FN_PTR(executeCompiledMethod)}, + {CC"executeCompiledMethodVarargs", CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, + {CC"getDeoptedLeafGraphIds", CC"()[J", FN_PTR(getDeoptedLeafGraphIds)}, + {CC"decodePC", CC"(J)"STRING, FN_PTR(decodePC)}, +}; + +int CompilerToVM_methods_count() { + return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod); +} + diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -442,6 +442,12 @@ MethodData* mdp = method()->method_data(); if (mdp != NULL) { mdp->inc_decompile_count(); + if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) { + // TODO (chaeubl) enable this in the fastdebug build only once we are more stable + ResourceMark m; + tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string()); + //ShouldNotReachHere(); + } } // All buffers in the CodeBuffer are allocated in the CodeCache. diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalGlobals.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -40,14 +40,16 @@ #endif // -// Defines all global flags used by the Graal compiler. +// Defines all global flags used by the Graal compiler. Only flags that need +// to be accessible to the Graal C++ code should be defined here. All other +// Graal flags should be defined in GraalOptions.java. // -#define GRAAL_FLAGS(develop, develop_pd, product, product_pd, notproduct) \ +#define GRAAL_FLAGS(develop, develop_pd, product, product_pd, notproduct) \ \ product(bool, DebugGraal, true, \ "Enable JVMTI for the compiler thread") \ \ - product(bool, BootstrapGraal, true, \ + product(bool, BootstrapGraal, GRAALVM_ONLY(true) NOT_GRAALVM(false), \ "Bootstrap Graal before running Java main method") \ \ product(ccstr, GraalClassPath, NULL, \ @@ -56,26 +58,20 @@ product(intx, TraceGraal, 0, \ "Trace level for Graal") \ \ - product(bool, TraceSignals, false, \ - "Trace signals and implicit exception handling") \ + develop(bool, GraalUseFastLocking, true, \ + "Use fast inlined locking code") \ \ - product_pd(intx, SafepointPollOffset, \ - "Offset added to polling address (Intel only)") \ - \ - develop(bool, UseFastNewTypeArray, true, \ + develop(bool, GraalUseFastNewTypeArray, true, \ "Use fast inlined type array allocation") \ \ - develop(bool, UseFastNewObjectArray, true, \ + develop(bool, GraalUseFastNewObjectArray, true, \ "Use fast inlined object array allocation") \ \ - develop(bool, UseFastLocking, true, \ - "Use fast inlined locking code") \ - \ develop(intx, GraalNMethodSizeLimit, (64*K)*wordSize, \ "Maximum size of a compiled method.") \ \ - notproduct(bool, PrintSimpleStubs, false, \ - "Print SimpleStubs") \ + notproduct(bool, GraalPrintSimpleStubs, false, \ + "Print simple Graal stubs") \ \ diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -119,7 +119,7 @@ // generate code for runtime stub OopMapSet* oop_maps; oop_maps = generate_code_for(id, sasm); - assert(oop_maps == NULL || sasm->frame_size() != no_frame_size, + assert(oop_maps == NULL || sasm->frame_size() != GraalStubAssembler::no_frame_size, "if stub has an oop map it must have a valid frame size"); #ifdef ASSERT @@ -130,14 +130,12 @@ #if defined(SPARC) || defined(PPC) case handle_exception_nofpu_id: // Unused on sparc #endif -#ifdef GRAAL case graal_verify_oop_id: case graal_unwind_exception_call_id: case graal_OSR_migration_end_id: case graal_arithmetic_frem_id: case graal_arithmetic_drem_id: case graal_set_deopt_info_id: -#endif break; // All other stubs should have oopmaps @@ -168,7 +166,7 @@ for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id); // printing #ifndef PRODUCT - if (PrintSimpleStubs) { + if (GraalPrintSimpleStubs) { ResourceMark rm; for (int id = 0; id < number_of_ids; id++) { _blobs[id]->print(); @@ -472,7 +470,7 @@ // Retry fast entry if bias is revoked to avoid unnecessary inflation ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK); } else { - if (UseFastLocking) { + if (GraalUseFastLocking) { // When using fast locking, the compiled code has already tried the fast case ObjectSynchronizer::slow_enter(h_obj, lock, THREAD); } else { @@ -503,7 +501,7 @@ } #endif - if (UseFastLocking) { + if (GraalUseFastLocking) { // When using fast locking, the compiled code has already tried the fast case ObjectSynchronizer::slow_exit(obj, lock, THREAD); } else { diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -43,6 +43,11 @@ int _stub_id; public: + + enum { + no_frame_size = -1 + }; + // creation GraalStubAssembler(CodeBuffer* code, const char * name, int stub_id); void set_info(const char* name, bool must_gc_arguments); @@ -70,9 +75,6 @@ // set frame size and return address offset to these values in blobs // (if the compiled frame uses ebp as link pointer on IA; otherwise, // the frame size must be fixed) -enum { - no_frame_size = -1 -}; // Holds all assembly stubs and VM // runtime routines needed by code code generated diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/interpreter/interpreter.cpp --- a/src/share/vm/interpreter/interpreter.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/interpreter/interpreter.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -394,26 +394,6 @@ return Interpreter::deopt_entry(vtos, 0); } -#ifdef GRAAL - - -// If deoptimization happens, the interpreter should reexecute these bytecodes. -// This function mainly helps the compilers to set up the reexecute bit. -bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { - switch (code) { - case Bytecodes::_invokedynamic: - case Bytecodes::_invokevirtual: - case Bytecodes::_invokeinterface: - case Bytecodes::_invokespecial: - case Bytecodes::_invokestatic: - return false; - default: - return true; - } - return true; -} -#else - // If deoptimization happens, the interpreter should reexecute these bytecodes. // This function mainly helps the compilers to set up the reexecute bit. bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { @@ -452,7 +432,7 @@ case Bytecodes::_getstatic : case Bytecodes::_putstatic : case Bytecodes::_aastore : -#if defined(COMPILER1) || defined(GRAAL) +#if defined(COMPILER1) //special case of reexecution case Bytecodes::_athrow : @@ -463,7 +443,6 @@ return false; } } -#endif void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { // Quick & dirty stack overflow checking: bang the stack & handle trap. diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -433,11 +433,13 @@ } } while (should_repeat == true); -#ifdef GRAAL +#ifdef GRAALVM if (h_method->method_data() != NULL) { ResourceMark rm(thread); ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci); if (pdata != NULL) { + // We re-purpose the DS_RECOMPILE_BIT to record that an exception was thrown at + // the current bci. int tstate0 = pdata->trap_state(); int tstate1 = Deoptimization::trap_state_set_recompiled(tstate0, true); if (tstate1 != tstate0) { diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/interpreter/rewriter.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -122,9 +122,7 @@ Bytecodes::Code opcode = bcs.raw_next(); switch (opcode) { case Bytecodes::_return: -#ifndef GRAAL *bcs.bcp() = Bytecodes::_return_register_finalizer; -#endif break; case Bytecodes::_istore: @@ -325,7 +323,6 @@ switch (c) { case Bytecodes::_lookupswitch : { #ifndef CC_INTERP -#ifndef GRAAL Bytecode_lookupswitch bc(method, bcp); (*bcp) = ( bc.number_of_pairs() < BinarySwitchThreshold @@ -333,7 +330,6 @@ : Bytecodes::_fast_binaryswitch ); #endif -#endif break; } case Bytecodes::_fast_linearswitch: diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/interpreter/templateTable.cpp --- a/src/share/vm/interpreter/templateTable.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/interpreter/templateTable.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -429,11 +429,7 @@ def(Bytecodes::_jsr , ubcp|disp|____|____, vtos, vtos, jsr , _ ); // result is not an oop, so do not transition to atos def(Bytecodes::_ret , ubcp|disp|____|____, vtos, vtos, ret , _ ); def(Bytecodes::_tableswitch , ubcp|disp|____|____, itos, vtos, tableswitch , _ ); -#ifdef GRAAL - def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, vtos, fast_linearswitch , _ ); -#else def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, itos, lookupswitch , _ ); -#endif def(Bytecodes::_ireturn , ____|disp|clvm|____, itos, itos, _return , itos ); def(Bytecodes::_lreturn , ____|disp|clvm|____, ltos, ltos, _return , ltos ); def(Bytecodes::_freturn , ____|disp|clvm|____, ftos, ftos, _return , ftos ); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -2161,7 +2161,7 @@ void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) { #if defined(COMPILER2) || defined(GRAAL) - // Currently only used by C2. + // Currently only used by C2 and Graal for (int m = 0; m < methods()->length(); m++) { MethodData* mdo = methods()->at(m)->method_data(); if (mdo != NULL) { diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/oops/method.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -121,6 +121,11 @@ backedge_counter()->init(); clear_number_of_breakpoints(); +#ifdef GRAAL + set_graal_invocation_time(0L); + set_graal_priority(0); +#endif + #ifdef TIERED set_rate(0); set_prev_event_count(0); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/oops/methodData.cpp --- a/src/share/vm/oops/methodData.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/oops/methodData.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -455,7 +455,7 @@ return DataLayout::compute_size_in_bytes(cell_count); } -#ifdef GRAAL +#ifdef GRAALVM int MethodData::compute_extra_data_count(int data_size, int empty_bc_count) { if (!ProfileTraps) return 0; @@ -500,7 +500,7 @@ int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); -#ifndef GRAAL +#ifndef GRAALVM // Add a cell to record information about modified arguments. int arg_size = method->size_of_parameters(); object_size += DataLayout::compute_size_in_bytes(arg_size+1); @@ -704,7 +704,7 @@ int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0); object_size += extra_size; -#ifndef GRAAL +#ifndef GRAALVM // Add a cell to record information about modified arguments. // Set up _args_modified array after traps cells so that // the code for traps cells works. @@ -728,7 +728,7 @@ } bool MethodData::is_empty_data(int size_in_bytes, Bytecodes::Code code) { -#ifdef GRAAL +#ifdef GRAALVM return size_in_bytes == 0 && Bytecodes::can_trap(code); #else return size_in_bytes == 0; @@ -762,12 +762,6 @@ void MethodData::inc_decompile_count() { _nof_decompiles += 1; if (decompile_count() > (uint)PerMethodRecompilationCutoff) { -#ifdef GRAAL - // TODO (chaeubl) enable this in the fastdebug build only once we are more stable - ResourceMark m; - tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string()); - //ShouldNotReachHere(); -#endif method()->set_not_compilable(CompLevel_full_optimization); } } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/oops/methodData.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -625,7 +625,14 @@ class ReceiverTypeData : public CounterData { protected: enum { +#ifdef GRAAL + // Graal is interested in knowing the percentage of type checks + // involving a type not explicitly in the profile + nonprofiled_receiver_count_off_set = counter_cell_count, + receiver0_offset, +#else receiver0_offset = counter_cell_count, +#endif count0_offset, receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset }; @@ -639,7 +646,7 @@ virtual bool is_ReceiverTypeData() { return true; } static int static_cell_count() { - return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; + return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count GRAAL_ONLY(+ 1); } virtual int cell_count() { @@ -710,6 +717,11 @@ static ByteSize receiver_count_offset(uint row) { return cell_offset(receiver_count_cell_index(row)); } +#ifdef GRAAL + static ByteSize nonprofiled_receiver_count_offset() { + return cell_offset(nonprofiled_receiver_count_off_set); + } +#endif static ByteSize receiver_type_data_size() { return cell_offset(static_cell_count()); } @@ -1168,11 +1180,7 @@ // Whole-method sticky bits and flags enum { -#ifdef GRAAL - _trap_hist_limit = 13, // decoupled from Deoptimization::Reason_LIMIT -#else _trap_hist_limit = 17, // decoupled from Deoptimization::Reason_LIMIT -#endif _trap_hist_mask = max_jubyte, _extra_data_count = 4 // extra DataLayout headers, for trap history }; // Public flag values diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/opto/c2compiler.hpp --- a/src/share/vm/opto/c2compiler.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/opto/c2compiler.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -33,6 +33,8 @@ static void initialize_runtime(); public: + C2Compiler() : AbstractCompiler(c2) {} + // Name const char *name() { return "C2"; } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/arguments.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -3442,9 +3442,12 @@ // which are subtlely different from each other but neither works with // biased locking. if (UseHeavyMonitors -#if defined(COMPILER1) || defined(GRAAL) +#ifdef COMPILER1 || !UseFastLocking #endif // COMPILER1 +#ifdef GRAAL + || !GraalUseFastLocking +#endif // GRAAL ) { if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) { // flag set to true on command line; warn the user that they diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/compilationPolicy.cpp --- a/src/share/vm/runtime/compilationPolicy.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/compilationPolicy.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -60,7 +60,7 @@ break; case 1: -#if defined(COMPILER2) || defined(GRAAL) +#if defined(COMPILER2) CompilationPolicy::set_policy(new StackWalkCompPolicy()); #else Unimplemented(); @@ -81,7 +81,7 @@ #endif break; case 4: -#if defined(GRAAL) +#if defined(GRAALVM) CompilationPolicy::set_policy(new GraalCompPolicy()); #else Unimplemented(); @@ -188,7 +188,7 @@ #endif #ifdef COMPILER1 - GRAAL_ONLY(ShouldNotReachHere();) + GRAALVM_ONLY(ShouldNotReachHere();) if (is_c1_compile(comp_level)) { return _compiler_count; } else { @@ -442,7 +442,7 @@ // GraalCompPolicy - compile current method -#ifdef GRAAL +#ifdef GRAALVM void GraalCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) { int hot_count = m->invocation_count(); @@ -505,12 +505,12 @@ } } -#endif // GRAAL +#endif // GRAALVM // StackWalkCompPolicy - walk up stack to find a suitable method to compile -#if defined(COMPILER2) || defined(GRAAL) +#if defined(COMPILER2) const char* StackWalkCompPolicy::_msg = NULL; @@ -737,4 +737,4 @@ -#endif // COMPILER2 || GRAAL +#endif // COMPILER2 diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/compilationPolicy.hpp --- a/src/share/vm/runtime/compilationPolicy.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/compilationPolicy.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -116,17 +116,17 @@ virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread); }; -#ifdef GRAAL +#ifdef GRAALVM class GraalCompPolicy : public NonTieredCompPolicy { public: virtual void method_invocation_event(methodHandle m, JavaThread* thread); virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread); }; -#endif // GRAAL +#endif // GRAALVM // StackWalkCompPolicy - existing C2 policy -#if defined(COMPILER2) || defined(GRAAL) +#if defined(COMPILER2) class StackWalkCompPolicy : public NonTieredCompPolicy { public: virtual void method_invocation_event(methodHandle m, JavaThread* thread); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -1316,8 +1316,8 @@ if (thread->graal_deopt_info() != NULL) { oop deopt_info = thread->graal_deopt_info(); if (java_lang_String::is_instance(deopt_info)) { - char buf[1024]; - java_lang_String::as_utf8_string(deopt_info, buf, 1024); + char buf[O_BUFLEN]; + java_lang_String::as_utf8_string(deopt_info, buf, O_BUFLEN); tty->print_cr("deopt info: %s", buf); } else { tty->print_cr("deopt info:"); @@ -1862,40 +1862,24 @@ Deoptimization::DeoptAction Deoptimization::_unloaded_action = Deoptimization::Action_reinterpret; const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { -#ifdef GRAAL + // Note: Keep this in sync. with enum DeoptReason. "none", "null_check", + "null_assert" GRAAL_ONLY("|unreached0"), "range_check", "class_check", "array_check", + "intrinsic" GRAAL_ONLY("|type_checked_inlining"), + "bimorphic" GRAAL_ONLY("|optimized_type_check"), + "unloaded", + "uninitialized" GRAAL_ONLY("|unresolved"), "unreached", - "type_checked_inlining", - "optimized_type_check", - "not_compiled_exception_handler", - "unresolved", - "jsr_mismatch", - "div0_check", - "constraint" -#else - // Note: Keep this in sync. with enum DeoptReason. - "none", - "null_check", - "null_assert", - "range_check", - "class_check", - "array_check", - "intrinsic", - "bimorphic", - "unloaded", - "uninitialized", - "unreached", - "unhandled", + "unhandled" GRAAL_ONLY("|not_compiled_exception_handler"), "constraint", "div0_check", - "age", + "age" GRAAL_ONLY("|jsr_mismatch"), "predicate", "loop_limit_check" -#endif }; const char* Deoptimization::_trap_action_name[Action_LIMIT] = { // Note: Keep this in sync. with enum DeoptAction. diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/deoptimization.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -39,7 +39,6 @@ public: // What condition caused the deoptimization enum DeoptReason { -#ifdef GRAAL Reason_many = -1, // indicates presence of several reasons Reason_none = 0, // indicates absence of a relevant deopt. // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits. @@ -49,26 +48,6 @@ // - bytecode y in method b() causes deopt // - Graal deoptimizes to bytecode x in method a() // -> the deopt reason will be recorded for method a() at bytecode x - Reason_null_check, - Reason_range_check, - Reason_class_check, - Reason_array_check, - Reason_unreached, - Reason_type_checked_inlining, - Reason_optimized_type_check, - - // recorded per method - Reason_not_compiled_exception_handler, - Reason_unresolved, - Reason_jsr_mismatch, - Reason_div0_check, - Reason_constraint, - Reason_LIMIT, - Reason_RECORDED_LIMIT = Reason_optimized_type_check -#else - Reason_many = -1, // indicates presence of several reasons - Reason_none = 0, // indicates absence of a relevant deopt. - // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits Reason_null_check, // saw unexpected null or zero divisor (@bci) Reason_null_assert, // saw unexpected non-null or non-zero (@bci) Reason_range_check, // saw unexpected array index (@bci) @@ -77,6 +56,13 @@ Reason_intrinsic, // saw unexpected operand to intrinsic (@bci) Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci) +#ifdef GRAAL + Reason_unreached0 = Reason_null_assert, + Reason_type_checked_inlining = Reason_intrinsic, + Reason_optimized_type_check = Reason_bimorphic, +#endif + + // recorded per method Reason_unloaded, // unloaded or class constant pool entry Reason_uninitialized, // bad class state (uninitialized) Reason_unreached, // code is not reached, compiler @@ -87,8 +73,14 @@ Reason_predicate, // compiler generated predicate failed Reason_loop_limit_check, // compiler generated loop limits check failed Reason_LIMIT, + +#ifdef GRAAL + Reason_not_compiled_exception_handler = Reason_unhandled, + Reason_unresolved = Reason_uninitialized, + Reason_jsr_mismatch = Reason_age, +#endif + Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc -#endif // GRAAL // Note: Keep this enum in sync. with _trap_reason_name. // Note: Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of // DataLayout::trap_bits. This dependency is enforced indirectly @@ -283,7 +275,7 @@ return (DeoptReason) ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits)); } else { -#ifdef GRAAL +#ifdef GRAALVM ShouldNotReachHere(); return Reason_none; #else @@ -297,7 +289,7 @@ return (DeoptAction) ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits)); } else { -#ifdef GRAAL +#ifdef GRAALVM ShouldNotReachHere(); return Action_make_not_compilable; #else @@ -310,7 +302,7 @@ if (trap_request < 0) { return -1; } else { -#ifdef GRAAL +#ifdef GRAALVM ShouldNotReachHere(); return -1; #else @@ -320,7 +312,7 @@ } static int make_trap_request(DeoptReason reason, DeoptAction action, int index = -1) { -#ifdef GRAAL +#ifdef GRAALVM assert(index == -1, "Graal does not use index"); #endif diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/globals.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -1219,6 +1219,9 @@ notproduct(bool, TraceJVMCalls, false, \ "Trace JVM calls") \ \ + product(bool, TraceSignals, false, \ + "Trace signals and implicit exception handling") \ + \ product(ccstr, TraceJVMTI, NULL, \ "Trace flags for JVMTI functions and events") \ \ @@ -2373,7 +2376,7 @@ product(intx, CICompilerCount, CI_COMPILER_COUNT, \ "Number of compiler threads to run") \ \ - product(intx, CompilationPolicyChoice, NOT_GRAAL(0) GRAAL_ONLY(4), \ + product(intx, CompilationPolicyChoice, NOT_GRAALVM(0) GRAALVM_ONLY(4), \ "which compilation policy (0/1)") \ \ develop(bool, UseStackBanging, true, \ diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/mutexLocker.cpp --- a/src/share/vm/runtime/mutexLocker.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/mutexLocker.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -292,7 +292,7 @@ def(JfrStream_lock , Mutex, nonleaf+4, true); def(PeriodicTask_lock , Monitor, nonleaf+5, true); #ifdef GRAAL - def(GraalDeoptLeafGraphIds_lock , Mutex, special, true); + def(GraalDeoptLeafGraphIds_lock , Mutex, special, true); #endif // GRAAL } diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -630,24 +630,25 @@ ResourceMark rm; #ifdef GRAAL - // lookup exception handler for this pc - int catch_pco = ret_pc - nm->code_begin(); - ExceptionHandlerTable table(nm); - HandlerTableEntry *t = table.entry_for(catch_pco, -1, 0); - if (t != NULL) { - return nm->code_begin() + t->pco(); - } else { - // there is no exception handler for this pc => deoptimize - nm->make_not_entrant(); - JavaThread* thread = JavaThread::current(); - RegisterMap reg_map(thread); - frame runtime_frame = thread->last_frame(); - frame caller_frame = runtime_frame.sender(®_map); - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_not_compiled_exception_handler); - return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); + if (nm->is_compiled_by_graal()) { + // lookup exception handler for this pc + int catch_pco = ret_pc - nm->code_begin(); + ExceptionHandlerTable table(nm); + HandlerTableEntry *t = table.entry_for(catch_pco, -1, 0); + if (t != NULL) { + return nm->code_begin() + t->pco(); + } else { + // there is no exception handler for this pc => deoptimize + nm->make_not_entrant(); + JavaThread* thread = JavaThread::current(); + RegisterMap reg_map(thread); + frame runtime_frame = thread->last_frame(); + frame caller_frame = runtime_frame.sender(®_map); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_not_compiled_exception_handler); + return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); + } } - -#else +#endif ScopeDesc* sd = nm->scope_desc_at(ret_pc); // determine handler bci, if any @@ -728,7 +729,6 @@ } return nm->code_begin() + t->pco(); -#endif } JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread)) @@ -871,9 +871,13 @@ _implicit_null_throws++; #endif #ifdef GRAAL - target_pc = deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check); -#else + if (nm->is_compiled_by_graal()) { + target_pc = deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check); + } else { +#endif target_pc = nm->continuation_for_implicit_exception(pc); +#ifdef GRAAL + } #endif // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal @@ -891,12 +895,16 @@ _implicit_div0_throws++; #endif #ifdef GRAAL - if (TraceSignals) { - tty->print_cr("Graal implicit div0"); + if (nm->is_compiled_by_graal()) { + if (TraceSignals) { + tty->print_cr("Graal implicit div0"); + } + target_pc = deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check); + } else { +#endif + target_pc = nm->continuation_for_implicit_exception(pc); +#ifdef GRAAL } - target_pc = deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check); -#else - target_pc = nm->continuation_for_implicit_exception(pc); #endif // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -252,7 +252,7 @@ case Deoptimization::Unpack_uncommon_trap: case Deoptimization::Unpack_reexecute: // redo last byte code -#ifdef GRAAL +#ifdef GRAALVM assert(should_reexecute(), ""); #endif pc = Interpreter::deopt_entry(vtos, 0); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/runtime/vm_version.cpp --- a/src/share/vm/runtime/vm_version.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/runtime/vm_version.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -124,7 +124,7 @@ #define VMTYPE "Zero" #endif // SHARK #else // ZERO - #ifdef GRAAL + #ifdef GRAALVM #define VMTYPE "Graal" #else // GRAAL #define VMTYPE COMPILER1_PRESENT("Client") \ diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/shark/sharkCompiler.cpp --- a/src/share/vm/shark/sharkCompiler.cpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/shark/sharkCompiler.cpp Fri Dec 14 13:02:49 2012 +0100 @@ -60,7 +60,7 @@ #endif SharkCompiler::SharkCompiler() - : AbstractCompiler() { + : AbstractCompiler(shark) { // Create the lock to protect the memory manager and execution engine _execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock"); MutexLocker locker(execution_engine_lock()); diff -r 31c4d9f9e922 -r 8a3efb8c831d src/share/vm/utilities/macros.hpp --- a/src/share/vm/utilities/macros.hpp Fri Dec 14 12:05:35 2012 +0100 +++ b/src/share/vm/utilities/macros.hpp Fri Dec 14 13:02:49 2012 +0100 @@ -182,9 +182,23 @@ #ifdef GRAAL #define GRAAL_ONLY(code) code #define NOT_GRAAL(code) +#if !defined(COMPILER1) && !defined(COMPILER2) +// Graal is the only compiler in the system and so will be used for compilation +// requests issued by the compile broker. +#define GRAALVM +#define GRAALVM_ONLY(code) code +#define NOT_GRAALVM(code) #else +// Graal is not the only compiler in the system and so will only be used for +// compilation requests issued via the Graal API +#define GRAALVM_ONLY(code) +#define NOT_GRAALVM(code) code +#endif +#else // !GRAAL #define GRAAL_ONLY(code) #define NOT_GRAAL(code) code +#define GRAALVM_ONLY(code) +#define NOT_GRAALVM(code) code #endif // GRAAL #ifdef HIGH_LEVEL_INTERPRETER