# HG changeset patch # User Michael Van De Vanter # Date 1387375612 28800 # Node ID 163b418ec0952a5f84d5ded08df161b5c7903ad5 # Parent f76593e3fedbb50c138bd8b779645e289baa5cec# Parent aba12e3603b48feda21b2a09fd4e03710c83eace Merge with aba12e3603b48feda21b2a09fd4e03710c83eace diff -r f76593e3fedb -r 163b418ec095 .hgtags --- a/.hgtags Wed Dec 18 03:16:17 2013 -0800 +++ b/.hgtags Wed Dec 18 06:06:52 2013 -0800 @@ -395,3 +395,11 @@ e510dfdec6dd701410f3398ed86ebcdff0cca63a hs25-b58 52b076e6ffae247c1c7d8b7aba995195be2b6fc2 jdk8-b116 c78d517c7ea47501b456e707afd4b78e7b5b202e hs25-b59 +f573d00213b7170c2ff856f9cd83cd148437f5b9 jdk8-b117 +abad3b2d905d9e1ad767c94baa94aba6ed5b207b hs25-b60 +c9f439732b18ea16f7e65815327d5ea7092cc258 jdk8-b118 +b2426da30009cd3069d03de073f351e6432c7682 hs25-b61 +ce42d815dd2130250acf6132b51b624001638f0d jdk8-b119 +05fedd51e40da22c9460bf17c7185889e435db3d hs25-b62 +fca262db9c4309f99d2f5542ab0780e45c2f1578 jdk8-b120 +41f4cad94c581034d4c427d2aaabcc20f26342d0 hs25-b63 diff -r f76593e3fedb -r 163b418ec095 agent/make/jsdbproc64.sh --- a/agent/make/jsdbproc64.sh Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/make/jsdbproc64.sh Wed Dec 18 06:06:52 2013 -0800 @@ -1,7 +1,7 @@ -#!/bin/sh +#!/bin/sh # -# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -21,10 +21,10 @@ # 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. -# +# # - -. `dirname $0`/saenv64.sh - -$SA_JAVA_CMD sun.jvm.hotspot.tools.JSDB $* + +. `dirname $0`/saenv64.sh + +$SA_JAVA_CMD sun.jvm.hotspot.tools.soql.JSDB $* diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java --- a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Wed Dec 18 06:06:52 2013 -0800 @@ -103,14 +103,14 @@ @Override public void remove() { /* not supported */ } - HeapRegionIterator(Address addr) { + HeapRegionIterator(long committedLength) { index = 0; - length = length(); + length = committedLength; } } - public Iterator heapRegionIterator() { - return new HeapRegionIterator(addr); + public Iterator heapRegionIterator(long committedLength) { + return new HeapRegionIterator(committedLength); } public G1HeapRegionTable(Address addr) { diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java --- a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Wed Dec 18 06:06:52 2013 -0800 @@ -42,6 +42,8 @@ public class HeapRegionSeq extends VMObject { // G1HeapRegionTable _regions static private long regionsFieldOffset; + // uint _committed_length + static private CIntegerField committedLengthField; static { VM.registerVMInitializedObserver(new Observer() { @@ -55,6 +57,7 @@ Type type = db.lookupType("HeapRegionSeq"); regionsFieldOffset = type.getField("_regions").getOffset(); + committedLengthField = type.getCIntegerField("_committed_length"); } private G1HeapRegionTable regions() { @@ -67,8 +70,12 @@ return regions().length(); } + public long committedLength() { + return committedLengthField.getValue(addr); + } + public Iterator heapRegionIterator() { - return regions().heapRegionIterator(); + return regions().heapRegionIterator(committedLength()); } public HeapRegionSeq(Address addr) { diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Wed Dec 18 06:06:52 2013 -0800 @@ -364,7 +364,7 @@ } catch (AddressException e) { // This is okay at the top of these regions - } + } catch (UnknownOopException e) { // This is okay at the top of these regions } @@ -373,7 +373,7 @@ visitor.epilogue(); } - private void addLiveRegions(List input, List output) { + private void addLiveRegions(String name, List input, List output) { for (Iterator itr = input.iterator(); itr.hasNext();) { MemRegion reg = (MemRegion) itr.next(); Address top = reg.end(); @@ -386,6 +386,9 @@ } output.add(top); output.add(bottom); + if (DEBUG) { + System.err.println("Live region: " + name + ": " + bottom + ", " + top); + } } } @@ -395,7 +398,7 @@ } public void doSpace(Space s) { - addLiveRegions(s.getLiveRegions(), liveRegions); + addLiveRegions(s.toString(), s.getLiveRegions(), liveRegions); } private List liveRegions; } @@ -426,11 +429,11 @@ ParallelScavengeHeap psh = (ParallelScavengeHeap) heap; PSYoungGen youngGen = psh.youngGen(); // Add eden space - addLiveRegions(youngGen.edenSpace().getLiveRegions(), liveRegions); + addLiveRegions("eden", youngGen.edenSpace().getLiveRegions(), liveRegions); // Add from-space but not to-space - addLiveRegions(youngGen.fromSpace().getLiveRegions(), liveRegions); + addLiveRegions("from", youngGen.fromSpace().getLiveRegions(), liveRegions); PSOldGen oldGen = psh.oldGen(); - addLiveRegions(oldGen.objectSpace().getLiveRegions(), liveRegions); + addLiveRegions("old ", oldGen.objectSpace().getLiveRegions(), liveRegions); } else if (heap instanceof G1CollectedHeap) { G1CollectedHeap g1h = (G1CollectedHeap) heap; g1h.heapRegionIterate(lrc); @@ -451,23 +454,27 @@ if (VM.getVM().getUseTLAB()) { for (JavaThread thread = VM.getVM().getThreads().first(); thread != null; thread = thread.next()) { - if (thread.isJavaThread()) { - ThreadLocalAllocBuffer tlab = thread.tlab(); - if (tlab.start() != null) { - if ((tlab.top() == null) || (tlab.end() == null)) { - System.err.print("Warning: skipping invalid TLAB for thread "); + ThreadLocalAllocBuffer tlab = thread.tlab(); + if (tlab.start() != null) { + if ((tlab.top() == null) || (tlab.end() == null)) { + System.err.print("Warning: skipping invalid TLAB for thread "); + thread.printThreadIDOn(System.err); + System.err.println(); + } else { + if (DEBUG) { + System.err.print("TLAB for " + thread.getThreadName() + ", #"); thread.printThreadIDOn(System.err); - System.err.println(); - } else { - // Go from: - // - below start() to start() - // - start() to top() - // - end() and above - liveRegions.add(tlab.start()); - liveRegions.add(tlab.start()); - liveRegions.add(tlab.top()); - liveRegions.add(tlab.hardEnd()); + System.err.print(": "); + tlab.printOn(System.err); } + // Go from: + // - below start() to start() + // - start() to top() + // - end() and above + liveRegions.add(tlab.start()); + liveRegions.add(tlab.start()); + liveRegions.add(tlab.top()); + liveRegions.add(tlab.hardEnd()); } } } @@ -480,6 +487,15 @@ Assert.that(liveRegions.size() % 2 == 0, "Must have even number of region boundaries"); } + if (DEBUG) { + System.err.println("liveRegions:"); + for (int i = 0; i < liveRegions.size(); i += 2) { + Address bottom = (Address) liveRegions.get(i); + Address top = (Address) liveRegions.get(i+1); + System.err.println(" " + bottom + " - " + top); + } + } + return liveRegions; } diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ThreadLocalAllocBuffer.java Wed Dec 18 06:06:52 2013 -0800 @@ -109,6 +109,6 @@ public void printOn(PrintStream tty) { tty.println(" [" + start() + "," + - top() + "," + end() + ")"); + top() + "," + end() + ",{" + hardEnd() + "})"); } } diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Wed Dec 18 06:06:52 2013 -0800 @@ -24,8 +24,9 @@ package sun.jvm.hotspot.tools; -import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.debugger.JVMDebugger; +import sun.jvm.hotspot.runtime.Arguments; +import sun.jvm.hotspot.runtime.VM; public class JInfo extends Tool { public JInfo() { @@ -138,14 +139,33 @@ } private void printVMFlags() { + VM.Flag[] flags = VM.getVM().getCommandLineFlags(); + System.out.print("Non-default VM flags: "); + for (VM.Flag flag : flags) { + if (flag.getOrigin() == 0) { + // only print flags which aren't their defaults + continue; + } + if (flag.isBool()) { + String onoff = flag.getBool() ? "+" : "-"; + System.out.print("-XX:" + onoff + flag.getName() + " "); + } else { + System.out.print("-XX:" + flag.getName() + "=" + + flag.getValue() + " "); + } + } + System.out.println(); + + System.out.print("Command line: "); String str = Arguments.getJVMFlags(); if (str != null) { - System.out.println(str); + System.out.print(str + " "); } str = Arguments.getJVMArgs(); if (str != null) { - System.out.println(str); + System.out.print(str); } + System.out.println(); } private int mode; diff -r f76593e3fedb -r 163b418ec095 agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Wed Dec 18 03:16:17 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Wed Dec 18 06:06:52 2013 -0800 @@ -25,11 +25,11 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; -import java.util.Hashtable; -import sun.jvm.hotspot.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.HotSpotAgent; +import sun.jvm.hotspot.debugger.DebuggerException; +import sun.jvm.hotspot.debugger.JVMDebugger; +import sun.jvm.hotspot.runtime.VM; // generic command line or GUI tool. // override run & code main as shown below. @@ -147,6 +147,7 @@ } PrintStream err = System.err; + PrintStream out = System.out; int pid = 0; String coreFileName = null; @@ -180,18 +181,18 @@ try { switch (debugeeType) { case DEBUGEE_PID: - err.println("Attaching to process ID " + pid + ", please wait..."); + out.println("Attaching to process ID " + pid + ", please wait..."); agent.attach(pid); break; case DEBUGEE_CORE: - err.println("Attaching to core " + coreFileName + + out.println("Attaching to core " + coreFileName + " from executable " + executableName + ", please wait..."); agent.attach(executableName, coreFileName); break; case DEBUGEE_REMOTE: - err.println("Attaching to remote server " + remoteServer + ", please wait..."); + out.println("Attaching to remote server " + remoteServer + ", please wait..."); agent.attach(remoteServer); break; } @@ -218,7 +219,7 @@ return 1; } - err.println("Debugger attached successfully."); + out.println("Debugger attached successfully."); startInternal(); return 0; } @@ -237,14 +238,14 @@ // Remains of the start mechanism, common to both start methods. private void startInternal() { - PrintStream err = System.err; + PrintStream out = System.out; VM vm = VM.getVM(); if (vm.isCore()) { - err.println("Core build detected."); + out.println("Core build detected."); } else if (vm.isClientCompiler()) { - err.println("Client compiler detected."); + out.println("Client compiler detected."); } else if (vm.isServerCompiler()) { - err.println("Server compiler detected."); + out.println("Server compiler detected."); } else { throw new RuntimeException("Fatal error: " + "should have been able to detect core/C1/C2 build"); @@ -252,8 +253,8 @@ String version = vm.getVMRelease(); if (version != null) { - err.print("JVM version is "); - err.println(version); + out.print("JVM version is "); + out.println(version); } run(); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Wed Dec 18 06:06:52 2013 -0800 @@ -48,7 +48,7 @@ } public HighTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); if (VerifyUsageWithEquals.getValue()) { appendPhase(new VerifyUsageWithEquals(Value.class)); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Wed Dec 18 06:06:52 2013 -0800 @@ -31,7 +31,7 @@ public class LowTier extends PhaseSuite { public LowTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); appendPhase(new LoweringPhase(canonicalizer)); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Wed Dec 18 06:06:52 2013 -0800 @@ -33,7 +33,7 @@ public class MidTier extends PhaseSuite { public MidTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); if (OptPushThroughPi.getValue()) { appendPhase(new PushThroughPiPhase()); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -201,7 +201,7 @@ StructuredGraph graph = parse(test); ResolvedJavaMethod method = graph.method(); - try (OverrideScope s = OptionValue.override(AOTCompilation, compileAOT)) { + try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) { PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Wed Dec 18 06:06:52 2013 -0800 @@ -41,11 +41,15 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.java.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; public class CompilationTask implements Runnable { @@ -62,9 +66,6 @@ } private final HotSpotBackend backend; - private final PhasePlan plan; - private final OptimisticOptimizations optimisticOpts; - private final ProfilingInfo profilingInfo; private final HotSpotResolvedJavaMethod method; private final int entryBCI; private final int id; @@ -72,18 +73,10 @@ private StructuredGraph graph; - public static CompilationTask create(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, HotSpotResolvedJavaMethod method, int entryBCI, - int id) { - return new CompilationTask(backend, plan, optimisticOpts, profilingInfo, method, entryBCI, id); - } - - protected CompilationTask(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, HotSpotResolvedJavaMethod method, int entryBCI, int id) { + public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, int id) { assert id >= 0; this.backend = backend; - this.plan = plan; this.method = method; - this.optimisticOpts = optimisticOpts; - this.profilingInfo = profilingInfo; this.entryBCI = entryBCI; this.id = id; this.status = new AtomicReference<>(CompilationStatus.Queued); @@ -124,6 +117,27 @@ return providers.getSuites().getDefaultSuites(); } + protected PhasePlan getPhasePlan(Providers providers, OptimisticOptimizations optimisticOpts) { + boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; + PhasePlan phasePlan = new PhasePlan(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), optimisticOpts)); + if (osrCompilation) { + phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase()); + } + return phasePlan; + } + + protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo) { + return new OptimisticOptimizations(profilingInfo); + } + + protected ProfilingInfo getProfilingInfo() { + boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; + return method.getCompilationProfilingInfo(osrCompilation); + } + public void runCompilation(boolean clearFromCompilationQueue) { /* * no code must be outside this try/finally because it could happen otherwise that @@ -169,7 +183,10 @@ InlinedBytecodes.add(method.getCodeSize()); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Suites suites = getSuites(providers); - result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, profilingInfo, method.getSpeculationLog(), suites, true, + ProfilingInfo profilingInfo = getProfilingInfo(); + OptimisticOptimizations optimisticOpts = getOptimisticOpts(profilingInfo); + PhasePlan phasePlan = getPhasePlan(providers, optimisticOpts); + result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, phasePlan, optimisticOpts, profilingInfo, method.getSpeculationLog(), suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default); } catch (Throwable e) { diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Wed Dec 18 06:06:52 2013 -0800 @@ -43,7 +43,6 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.options.*; import com.oracle.graal.options.OptionValue.OverrideScope; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.replacements.*; @@ -318,21 +317,30 @@ TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms)", classFileCounter, compiledMethodsCounter, compileTime); } - /** - * A compilation task that creates a fresh compilation suite for its compilation. This is - * required so that a CTW compilation can be {@linkplain Config configured} differently from a - * VM triggered compilation. - */ - static class CTWCompilationTask extends CompilationTask { + class CTWCompilationTask extends CompilationTask { - CTWCompilationTask(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, HotSpotResolvedJavaMethod method, int entryBCI, int id) { - super(backend, plan, optimisticOpts, profilingInfo, method, entryBCI, id); + CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int id) { + super(backend, method, INVOCATION_ENTRY_BCI, id); } + /** + * Returns a fresh compilation suite for its compilation so that the CTW option value + * overriding configuration has effect. + */ @Override protected Suites getSuites(HotSpotProviders providers) { + assert config.scope != null : "not inside a CTW option value overriding scope"; return providers.getSuites().createSuites(); } + + /** + * Returns empty profiling info to be as close to the CTW behavior of C1 and C2 as possible. + */ + @Override + protected ProfilingInfo getProfilingInfo() { + // Be optimistic and return false for exceptionSeen. + return DefaultProfilingInfo.get(TriState.FALSE); + } } /** @@ -342,13 +350,9 @@ try { long start = System.currentTimeMillis(); - // Be optimistic and return false for exceptionSeen. - final ProfilingInfo profilingInfo = DefaultProfilingInfo.get(TriState.FALSE); - final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(profilingInfo); int id = vmToCompiler.allocateCompileTaskId(); HotSpotBackend backend = runtime.getHostBackend(); - PhasePlan phasePlan = vmToCompiler.createPhasePlan(backend.getProviders(), optimisticOpts, false); - CompilationTask task = new CTWCompilationTask(backend, phasePlan, optimisticOpts, profilingInfo, method, INVOCATION_ENTRY_BCI, id); + CompilationTask task = new CTWCompilationTask(backend, method, id); task.runCompilation(false); compileTime += (System.currentTimeMillis() - start); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Dec 18 06:06:52 2013 -0800 @@ -35,7 +35,6 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; @@ -46,12 +45,9 @@ import com.oracle.graal.hotspot.CompileTheWorld.Config; import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.options.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; @@ -571,7 +567,7 @@ /** * Compiles a method to machine code. */ - public void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, final boolean blocking) { + void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, final boolean blocking) { boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; if (osrCompilation && bootstrapRunning) { // no OSR compilations during bootstrap - the compiler is just too slow at this point, @@ -592,11 +588,9 @@ if (method.tryToQueueForCompilation()) { assert method.isQueuedForCompilation(); - final ProfilingInfo profilingInfo = method.getCompilationProfilingInfo(osrCompilation); - final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(profilingInfo); int id = allocateCompileTaskId(); HotSpotBackend backend = runtime.getHostBackend(); - CompilationTask task = CompilationTask.create(backend, createPhasePlan(backend.getProviders(), optimisticOpts, osrCompilation), optimisticOpts, profilingInfo, method, entryBCI, id); + CompilationTask task = new CompilationTask(backend, method, entryBCI, id); if (blocking) { task.runCompilation(true); @@ -683,17 +677,6 @@ return HotSpotResolvedObjectType.fromClass(javaMirror); } - public PhasePlan createPhasePlan(HotSpotProviders providers, OptimisticOptimizations optimisticOpts, boolean onStackReplacement) { - PhasePlan phasePlan = new PhasePlan(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - ForeignCallsProvider foreignCalls = providers.getForeignCalls(); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), optimisticOpts)); - if (onStackReplacement) { - phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase()); - } - return phasePlan; - } - @Override public PrintStream log() { return log; diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Dec 18 06:06:52 2013 -0800 @@ -160,7 +160,7 @@ * in AOT mode, some fields should never be embedded even for snippets/replacements. */ private boolean isEmbeddable() { - if (AOTCompilation.getValue() && notEmbeddable.contains(this)) { + if (ImmutableCode.getValue() && notEmbeddable.contains(this)) { return false; } return true; @@ -176,7 +176,7 @@ */ @Override public Constant readConstantValue(Constant receiver) { - assert !AOTCompilation.getValue() || isCalledForSnippets() : receiver; + assert !ImmutableCode.getValue() || isCalledForSnippets() : receiver; if (receiver == null) { assert Modifier.isStatic(modifiers); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Wed Dec 18 06:06:52 2013 -0800 @@ -48,7 +48,7 @@ public Suites createSuites() { Suites ret = Suites.createDefaultSuites(); - if (AOTCompilation.getValue()) { + if (ImmutableCode.getValue()) { // lowering introduces class constants, therefore it must be after lowering ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset)); if (VerifyPhases.getValue()) { diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Wed Dec 18 06:06:52 2013 -0800 @@ -49,7 +49,7 @@ @Override public void virtualize(VirtualizerTool tool) { - if (AOTCompilation.getValue()) { + if (ImmutableCode.getValue()) { return; } State state = tool.getObjectState(getObject()); @@ -61,7 +61,7 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (AOTCompilation.getValue()) { + if (ImmutableCode.getValue()) { return this; } if (usages().isEmpty()) { diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Wed Dec 18 06:06:52 2013 -0800 @@ -65,7 +65,7 @@ @Override protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - return AOTCompilation.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(param.asObject())); + return ImmutableCode.getValue() || param.isNull() ? null : Constant.forInt(System.identityHashCode(param.asObject())); } } diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Wed Dec 18 06:06:52 2013 -0800 @@ -25,8 +25,6 @@ import static com.oracle.graal.graph.UnsafeAccess.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -36,14 +34,13 @@ * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the * value matched the expected value. */ -public class CompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single, Canonicalizable { +public class CompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { @Input private ValueNode object; @Input private ValueNode offset; @Input private ValueNode expected; @Input private ValueNode newValue; private final int displacement; - private final LocationIdentity locationIdentity; public ValueNode object() { return object; @@ -66,10 +63,6 @@ } public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) { - this(object, displacement, offset, expected, newValue, LocationIdentity.ANY_LOCATION); - } - - public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue, LocationIdentity locationIdentity) { super(StampFactory.forKind(Kind.Boolean.getStackKind())); assert expected.kind() == newValue.kind(); this.object = object; @@ -77,12 +70,11 @@ this.expected = expected; this.newValue = newValue; this.displacement = displacement; - this.locationIdentity = locationIdentity; } @Override public LocationIdentity getLocationIdentity() { - return locationIdentity; + return LocationIdentity.ANY_LOCATION; } @Override @@ -90,24 +82,6 @@ tool.getLowerer().lower(this, tool); } - @Override - public Node canonical(CanonicalizerTool tool) { - if (getLocationIdentity() == LocationIdentity.ANY_LOCATION) { - Constant offsetConstant = offset().asConstant(); - if (offsetConstant != null) { - ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object()); - if (receiverType != null) { - long constantOffset = offsetConstant.asLong(); - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset); - if (field != null && expected().kind() == field.getKind() && newValue().kind() == field.getKind()) { - return graph().add(new CompareAndSwapNode(object, displacement, offset, expected, newValue, field)); - } - } - } - } - return this; - } - // specialized on value type until boxing/unboxing is sorted out in intrinsification @NodeIntrinsic public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, Object expected, Object newValue) { diff -r f76593e3fedb -r 163b418ec095 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 Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Dec 18 06:06:52 2013 -0800 @@ -711,7 +711,7 @@ metricInliningTailDuplication.increment(); Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities); PhaseContext phaseContext = new PhaseContext(providers, assumptions); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer); } } diff -r f76593e3fedb -r 163b418ec095 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 Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Dec 18 06:06:52 2013 -0800 @@ -229,8 +229,8 @@ public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5); // Ahead of time compilation - @Option(help = "Configure compiler to emit code compatible with AOT requirements for HotSpot") - public static final OptionValue AOTCompilation = new OptionValue<>(false); + @Option(help = "Try to avoid emitting code where patching is required") + public static final OptionValue ImmutableCode = new OptionValue<>(false); // Runtime settings @Option(help = "") diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Wed Dec 18 06:06:52 2013 -0800 @@ -218,7 +218,7 @@ public void lower(BoxNode box, LoweringTool tool) { FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess()); // if in AOT mode, we don't want to embed boxed constants. - if (canonical != null && !AOTCompilation.getValue()) { + if (canonical != null && !ImmutableCode.getValue()) { box.graph().replaceFloating(box, canonical); } else { Arguments args = new Arguments(boxSnippets.get(box.getBoxingKind()), box.graph().getGuardsStage()); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CompositeValueClassSubstitutions.java Wed Dec 18 06:06:52 2013 -0800 @@ -51,7 +51,7 @@ @SuppressWarnings("unchecked") @Override protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - if (param.isNull() || AOTCompilation.getValue()) { + if (param.isNull() || ImmutableCode.getValue()) { return null; } return Constant.forObject(CompositeValueClass.get((Class) param.asObject())); diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Wed Dec 18 06:06:52 2013 -0800 @@ -55,7 +55,7 @@ @Override protected Constant evaluate(Constant param, MetaAccessProvider metaAccess) { - return param.isNull() || AOTCompilation.getValue() ? null : Constant.forObject(NodeClass.get((Class) param.asObject())); + return param.isNull() || ImmutableCode.getValue() ? null : Constant.forObject(NodeClass.get((Class) param.asObject())); } } diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Dec 18 06:06:52 2013 -0800 @@ -76,7 +76,7 @@ public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache) { this.providers = providers; CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection()); - this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer); + this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer); this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess()); this.cache = runtime.getGraphCache(); this.truffleCache = truffleCache; diff -r f76593e3fedb -r 163b418ec095 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Dec 18 03:16:17 2013 -0800 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Dec 18 06:06:52 2013 -0800 @@ -110,7 +110,7 @@ // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); - CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue()); + CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!ImmutableCode.getValue()); PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizerPhase); Mark mark = null; diff -r f76593e3fedb -r 163b418ec095 make/hotspot_version --- a/make/hotspot_version Wed Dec 18 03:16:17 2013 -0800 +++ b/make/hotspot_version Wed Dec 18 06:06:52 2013 -0800 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=59 +HS_BUILD_NUMBER=63 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r f76593e3fedb -r 163b418ec095 mx/mx_graal.py --- a/mx/mx_graal.py Wed Dec 18 03:16:17 2013 -0800 +++ b/mx/mx_graal.py Wed Dec 18 06:06:52 2013 -0800 @@ -970,8 +970,8 @@ tasks.append(t.stop()) with VM('graal', 'product'): - t = Task('BootstrapWithAOTConfiguration:product') - vm(['-G:+AOTCompilation', '-G:+VerifyPhases', '-esa', '-version']) + t = Task('BootstrapWithImmutableCode:product') + vm(['-G:+ImmutableCode', '-G:+VerifyPhases', '-esa', '-version']) tasks.append(t.stop()) with VM('server', 'product'): # hosted mode diff -r f76593e3fedb -r 163b418ec095 src/cpu/sparc/vm/vm_version_sparc.cpp --- a/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -89,6 +89,27 @@ _supports_cx8 = has_v9(); _supports_atomic_getset4 = true; // swap instruction + // There are Fujitsu Sparc64 CPUs which support blk_init as well so + // we have to take this check out of the 'is_niagara()' block below. + if (has_blk_init()) { + // When using CMS or G1, we cannot use memset() in BOT updates + // because the sun4v/CMT version in libc_psr uses BIS which + // exposes "phantom zeros" to concurrent readers. See 6948537. + if (FLAG_IS_DEFAULT(UseMemSetInBOT) && (UseConcMarkSweepGC || UseG1GC)) { + FLAG_SET_DEFAULT(UseMemSetInBOT, false); + } + // Issue a stern warning if the user has explicitly set + // UseMemSetInBOT (it is known to cause issues), but allow + // use for experimentation and debugging. + if (UseConcMarkSweepGC || UseG1GC) { + if (UseMemSetInBOT) { + assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); + warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" + " on sun4v; please understand that you are using at your own risk!"); + } + } + } + if (is_niagara()) { // Indirect branch is the same cost as direct if (FLAG_IS_DEFAULT(UseInlineCaches)) { @@ -98,12 +119,6 @@ if (FLAG_IS_DEFAULT(OptoLoopAlignment)) { FLAG_SET_DEFAULT(OptoLoopAlignment, 4); } - // When using CMS or G1, we cannot use memset() in BOT updates - // because the sun4v/CMT version in libc_psr uses BIS which - // exposes "phantom zeros" to concurrent readers. See 6948537. - if (FLAG_IS_DEFAULT(UseMemSetInBOT) && (UseConcMarkSweepGC || UseG1GC)) { - FLAG_SET_DEFAULT(UseMemSetInBOT, false); - } #ifdef _LP64 // 32-bit oops don't make sense for the 64-bit VM on sparc // since the 32-bit VM has the same registers and smaller objects. diff -r f76593e3fedb -r 163b418ec095 src/cpu/sparc/vm/vm_version_sparc.hpp --- a/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -94,7 +94,13 @@ static bool is_M_family(int features) { return (features & M_family_m) != 0; } static bool is_T_family(int features) { return (features & T_family_m) != 0; } static bool is_niagara() { return is_T_family(_features); } - DEBUG_ONLY( static bool is_niagara(int features) { return (features & sun4v_m) != 0; } ) +#ifdef ASSERT + static bool is_niagara(int features) { + // 'sun4v_m' may be defined on both Sun/Oracle Sparc CPUs as well as + // on Fujitsu Sparc64 CPUs, but only Sun/Oracle Sparcs can be 'niagaras'. + return (features & sun4v_m) != 0 && (features & sparc64_family_m) == 0; + } +#endif // Returns true if it is niagara1 (T1). static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); } diff -r f76593e3fedb -r 163b418ec095 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -1719,10 +1719,12 @@ BarrierSet* bs = Universe::heap()->barrier_set(); CardTableModRefBS* ct = (CardTableModRefBS*)bs; + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + Label done; Label runtime; - // At this point we know new_value is non-NULL and the new_value crosses regsion. + // At this point we know new_value is non-NULL and the new_value crosses regions. // Must check to see if card is already dirty const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); @@ -1735,26 +1737,17 @@ __ push(rax); __ push(rcx); - NOT_LP64(__ get_thread(thread);) - ExternalAddress cardtable((address)ct->byte_map_base); - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + const Register cardtable = rax; + const Register card_addr = rcx; - const Register card_addr = rcx; -#ifdef _LP64 - const Register tmp = rscratch1; f.load_argument(0, card_addr); - __ shrq(card_addr, CardTableModRefBS::card_shift); - __ lea(tmp, cardtable); - // get the address of the card - __ addq(card_addr, tmp); -#else - const Register card_index = rcx; - f.load_argument(0, card_index); - __ shrl(card_index, CardTableModRefBS::card_shift); + __ shrptr(card_addr, CardTableModRefBS::card_shift); + // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT + // a valid address and therefore is not properly handled by the relocation code. + __ movptr(cardtable, (intptr_t)ct->byte_map_base); + __ addptr(card_addr, cardtable); - Address index(noreg, card_index, Address::times_1); - __ leal(card_addr, __ as_Address(ArrayAddress(cardtable, index))); -#endif + NOT_LP64(__ get_thread(thread);) __ cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val()); __ jcc(Assembler::equal, done); diff -r f76593e3fedb -r 163b418ec095 src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/x86/vm/frame_x86.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -94,13 +94,6 @@ // other generic buffer blobs are more problematic so we just assume they are // ok. adapter blobs never have a frame complete and are never ok. - // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc - - if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) { - //assert(0, "Invalid frame_size"); - return false; - } - if (!_cb->is_frame_complete_at(_pc)) { if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { return false; @@ -144,6 +137,11 @@ // must be some sort of compiled/runtime frame // fp does not have to be safe (although it could be check for c1?) + // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc + if (_cb->frame_size() <= 0) { + return false; + } + sender_sp = _unextended_sp + _cb->frame_size(); // On Intel the return_address is always the word on the stack sender_pc = (address) *(sender_sp-1); diff -r f76593e3fedb -r 163b418ec095 src/cpu/x86/vm/macroAssembler_x86.cpp --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -3354,6 +3354,8 @@ BarrierSet* bs = Universe::heap()->barrier_set(); CardTableModRefBS* ct = (CardTableModRefBS*)bs; + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); + Label done; Label runtime; @@ -3371,28 +3373,16 @@ // storing region crossing non-NULL, is card already dirty? - ExternalAddress cardtable((address) ct->byte_map_base); - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); -#ifdef _LP64 const Register card_addr = tmp; - - movq(card_addr, store_addr); - shrq(card_addr, CardTableModRefBS::card_shift); - - lea(tmp2, cardtable); - - // get the address of the card - addq(card_addr, tmp2); -#else - const Register card_index = tmp; - - movl(card_index, store_addr); - shrl(card_index, CardTableModRefBS::card_shift); - - Address index(noreg, card_index, Address::times_1); - const Register card_addr = tmp; - lea(card_addr, as_Address(ArrayAddress(cardtable, index))); -#endif + const Register cardtable = tmp2; + + movptr(card_addr, store_addr); + shrptr(card_addr, CardTableModRefBS::card_shift); + // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT + // a valid address and therefore is not properly handled by the relocation code. + movptr(cardtable, (intptr_t)ct->byte_map_base); + addptr(card_addr, cardtable); + cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val()); jcc(Assembler::equal, done); @@ -3416,7 +3406,7 @@ movq(Address(tmp2, 0), card_addr); #else addl(tmp2, queue_index); - movl(Address(tmp2, 0), card_index); + movl(Address(tmp2, 0), card_addr); #endif jmp(done); @@ -3468,25 +3458,19 @@ // The calculation for byte_map_base is as follows: // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); - // So this essentially converts an address to a displacement and - // it will never need to be relocated. On 64bit however the value may be too - // large for a 32bit displacement - + // So this essentially converts an address to a displacement and it will + // never need to be relocated. On 64bit however the value may be too + // large for a 32bit displacement. intptr_t disp = (intptr_t) ct->byte_map_base; if (is_simm32(disp)) { Address cardtable(noreg, obj, Address::times_1, disp); movb(cardtable, 0); } else { - // By doing it as an ExternalAddress disp could be converted to a rip-relative - // displacement and done in a single instruction given favorable mapping and - // a smarter version of as_Address. Worst case it is two instructions which - // is no worse off then loading disp into a register and doing as a simple - // Address() as above. - // We can't do as ExternalAddress as the only style since if disp == 0 we'll - // assert since NULL isn't acceptable in a reloci (see 6644928). In any case - // in some cases we'll get a single instruction version. - - ExternalAddress cardtable((address)disp); + // By doing it as an ExternalAddress 'disp' could be converted to a rip-relative + // displacement and done in a single instruction given favorable mapping and a + // smarter version of as_Address. However, 'ExternalAddress' generates a relocation + // entry and that entry is not properly handled by the relocation code. + AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none); Address index(noreg, obj, Address::times_1); movb(as_Address(ArrayAddress(cardtable, index)), 0); } diff -r f76593e3fedb -r 163b418ec095 src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -3001,6 +3001,10 @@ // sp should be pointing at the return address to the caller (3) + // Pick up the initial fp we should save + // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); + // Stack bang to make sure there's enough room for these interpreter frames. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); @@ -3020,9 +3024,6 @@ __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); __ movl(counter, rbx); - // Pick up the initial fp we should save - __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter // frame and the stack walking of interpreter_sender will get the unextended sp @@ -3220,6 +3221,10 @@ // sp should be pointing at the return address to the caller (3) + // Pick up the initial fp we should save + // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); + // Stack bang to make sure there's enough room for these interpreter frames. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); @@ -3240,9 +3245,6 @@ __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); __ movl(counter, rbx); - // Pick up the initial fp we should save - __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter // frame and the stack walking of interpreter_sender will get the unextended sp diff -r f76593e3fedb -r 163b418ec095 src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -3542,6 +3542,10 @@ // rsp should be pointing at the return address to the caller (3) + // Pick up the initial fp we should save + // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); + // Stack bang to make sure there's enough room for these interpreter frames. if (UseStackBanging) { __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); @@ -3560,9 +3564,6 @@ // Load counter into rdx __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); - // Pick up the initial fp we should save - __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); - // Now adjust the caller's stack to make up for the extra locals // but record the original sp so that we can save it in the skeletal interpreter // frame and the stack walking of interpreter_sender will get the unextended sp @@ -3738,6 +3739,10 @@ // rsp should be pointing at the return address to the caller (3) + // Pick up the initial fp we should save + // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved) + __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); + // Stack bang to make sure there's enough room for these interpreter frames. if (UseStackBanging) { __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); @@ -3745,27 +3750,16 @@ } // Load address of array of frame pcs into rcx (address*) - __ movptr(rcx, - Address(rdi, - Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); + __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); // Trash the return pc __ addptr(rsp, wordSize); // Load address of array of frame sizes into rsi (intptr_t*) - __ movptr(rsi, Address(rdi, - Deoptimization::UnrollBlock:: - frame_sizes_offset_in_bytes())); + __ movptr(rsi, Address(rdi, Deoptimization::UnrollBlock:: frame_sizes_offset_in_bytes())); // Counter - __ movl(rdx, Address(rdi, - Deoptimization::UnrollBlock:: - number_of_frames_offset_in_bytes())); // (int) - - // Pick up the initial fp we should save - __ movptr(rbp, - Address(rdi, - Deoptimization::UnrollBlock::initial_info_offset_in_bytes())); + __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock:: number_of_frames_offset_in_bytes())); // (int) // Now adjust the caller's stack to make up for the extra locals but // record the original sp so that we can save it in the skeletal @@ -3775,9 +3769,7 @@ const Register sender_sp = r8; __ mov(sender_sp, rsp); - __ movl(rbx, Address(rdi, - Deoptimization::UnrollBlock:: - caller_adjustment_offset_in_bytes())); // (int) + __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock:: caller_adjustment_offset_in_bytes())); // (int) __ subptr(rsp, rbx); // Push interpreter frames in a loop diff -r f76593e3fedb -r 163b418ec095 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/ci/ciEnv.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -1003,21 +1003,15 @@ // Free codeBlobs code_buffer->free_blob(); - if (nm == NULL) { - // The CodeCache is full. Print out warning and disable compilation. - record_failure("code cache is full"); - { - MutexUnlocker ml(Compile_lock); - MutexUnlocker locker(MethodCompileQueue_lock); - CompileBroker::handle_full_code_cache(); - } - } else { + if (nm != NULL) { nm->set_has_unsafe_access(has_unsafe_access); nm->set_has_wide_vectors(has_wide_vectors); // Record successful registration. // (Put nm into the task handle *before* publishing to the Java heap.) - if (task() != NULL) task()->set_code(nm); + if (task() != NULL) { + task()->set_code(nm); + } if (entry_bci == InvocationEntryBci) { if (TieredCompilation) { @@ -1055,12 +1049,16 @@ method->method_holder()->add_osr_nmethod(nm); } } - } - // JVMTI -- compiled method notification (must be done outside lock) + } // safepoints are allowed again + if (nm != NULL) { + // JVMTI -- compiled method notification (must be done outside lock) nm->post_compiled_method_load_event(); + } else { + // The CodeCache is full. Print out warning and disable compilation. + record_failure("code cache is full"); + CompileBroker::handle_full_code_cache(); } - } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -4483,8 +4483,8 @@ for (int index = 0; index < num_methods; index++) { Method* m = methods->at(index); - // skip static and methods - if ((!m->is_static()) && + // skip private, static, and methods + if ((!m->is_private() && !m->is_static()) && (m->name() != vmSymbols::object_initializer_name())) { Symbol* name = m->name(); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/classLoaderData.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -62,13 +62,13 @@ #include "runtime/safepoint.hpp" #include "runtime/synchronizer.hpp" #include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" #include "utilities/ostream.hpp" #if INCLUDE_TRACE #include "trace/tracing.hpp" #endif - ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : @@ -754,7 +754,7 @@ if (Tracing::enabled()) { if (Tracing::is_event_enabled(TraceClassUnloadEvent)) { assert(_unloading != NULL, "need class loader data unload list!"); - _class_unload_time = Tracing::time(); + _class_unload_time = Ticks::now(); classes_unloading_do(&class_unload_event); } Tracing::on_unloading_classes(); @@ -832,7 +832,7 @@ #if INCLUDE_TRACE -TracingTime ClassLoaderDataGraph::_class_unload_time; +Ticks ClassLoaderDataGraph::_class_unload_time; void ClassLoaderDataGraph::class_unload_event(Klass* const k) { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/classLoaderData.hpp --- a/src/share/vm/classfile/classLoaderData.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/classLoaderData.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -33,7 +33,7 @@ #include "utilities/growableArray.hpp" #if INCLUDE_TRACE -# include "trace/traceTime.hpp" +# include "utilities/ticks.hpp" #endif // @@ -98,7 +98,7 @@ #if INCLUDE_TRACE private: - static TracingTime _class_unload_time; + static Ticks _class_unload_time; static void class_unload_event(Klass* const k); #endif }; diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -625,13 +625,13 @@ while (super != NULL) { for (int i = 0; i < super->methods()->length(); ++i) { Method* m = super->methods()->at(i); - if (m->is_overpass()) { + if (m->is_overpass() || m->is_static()) { // m is a method that would have been a miranda if not for the // default method processing that occurred on behalf of our superclass, // so it's a method we want to re-examine in this new context. That is, // unless we have a real implementation of it in the current class. Method* impl = klass->lookup_method(m->name(), m->signature()); - if (impl == NULL || impl->is_overpass()) { + if (impl == NULL || impl->is_overpass() || impl->is_static()) { if (!already_in_vtable_slots(slots, m)) { slots->append(new EmptyVtableSlot(m)); } @@ -648,7 +648,7 @@ // so it's a method we want to re-examine in this new context. That is, // unless we have a real implementation of it in the current class. Method* impl = klass->lookup_method(m->name(), m->signature()); - if (impl == NULL || impl->is_overpass()) { + if (impl == NULL || impl->is_overpass() || impl->is_static()) { if (!already_in_vtable_slots(slots, m)) { slots->append(new EmptyVtableSlot(m)); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/metadataOnStackMark.cpp --- a/src/share/vm/classfile/metadataOnStackMark.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/metadataOnStackMark.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -30,6 +30,7 @@ #include "prims/jvmtiImpl.hpp" #include "runtime/synchronizer.hpp" #include "runtime/thread.hpp" +#include "services/threadService.hpp" #include "utilities/growableArray.hpp" @@ -50,6 +51,7 @@ CodeCache::alive_nmethods_do(nmethod::mark_on_stack); CompileBroker::mark_on_stack(); JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack); + ThreadService::metadata_do(Metadata::mark_on_stack); } MetadataOnStackMark::~MetadataOnStackMark() { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -55,13 +55,13 @@ #include "runtime/signature.hpp" #include "services/classLoadingService.hpp" #include "services/threadService.hpp" +#include "utilities/macros.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_TRACE #include "trace/tracing.hpp" - #include "trace/traceMacros.hpp" #endif - Dictionary* SystemDictionary::_dictionary = NULL; PlaceholderTable* SystemDictionary::_placeholders = NULL; Dictionary* SystemDictionary::_shared_dictionary = NULL; @@ -598,7 +598,7 @@ assert(name != NULL && !FieldType::is_array(name) && !FieldType::is_obj(name), "invalid class name"); - TracingTime class_load_start_time = Tracing::time(); + Ticks class_load_start_time = Ticks::now(); // UseNewReflection // Fix for 4474172; see evaluation for more details @@ -1006,7 +1006,7 @@ TRAPS) { TempNewSymbol parsed_name = NULL; - TracingTime class_load_start_time = Tracing::time(); + Ticks class_load_start_time = Ticks::now(); ClassLoaderData* loader_data; if (host_klass.not_null()) { @@ -2665,13 +2665,12 @@ } // utility function for class load event -void SystemDictionary::post_class_load_event(TracingTime start_time, +void SystemDictionary::post_class_load_event(const Ticks& start_time, instanceKlassHandle k, Handle initiating_loader) { #if INCLUDE_TRACE EventClassLoad event(UNTIMED); if (event.should_commit()) { - event.set_endtime(Tracing::time()); event.set_starttime(start_time); event.set_loadedClass(k()); oop defining_class_loader = k->class_loader(); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -31,7 +31,6 @@ #include "oops/symbol.hpp" #include "runtime/java.hpp" #include "runtime/reflectionUtils.hpp" -#include "trace/traceTime.hpp" #include "utilities/hashtable.hpp" #include "utilities/hashtable.inline.hpp" @@ -78,6 +77,7 @@ template class HashtableBucket; class ResolutionErrorTable; class SymbolPropertyTable; +class Ticks; // Certain classes are preloaded, such as java.lang.Object and java.lang.String. // They are all "well-known", in the sense that no class loader is allowed @@ -141,7 +141,6 @@ /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \ /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \ /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \ - do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \ do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \ do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \ do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \ @@ -166,6 +165,7 @@ \ do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \ do_klass(StringBuilder_klass, java_lang_StringBuilder, Pre ) \ + do_klass(misc_Unsafe_klass, sun_misc_Unsafe, Pre ) \ \ /* It's NULL in non-1.4 JDKs. */ \ do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \ @@ -689,7 +689,7 @@ static void add_to_hierarchy(instanceKlassHandle k, TRAPS); // event based tracing - static void post_class_load_event(TracingTime start_time, instanceKlassHandle k, + static void post_class_load_event(const Ticks& start_time, instanceKlassHandle k, Handle initiating_loader); // We pass in the hashtable index so we can calculate it outside of // the SystemDictionary_lock. diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/verifier.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -188,10 +188,8 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { Symbol* name = klass->name(); Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); - Klass* lambda_magic_klass = SystemDictionary::lambda_MagicLambdaImpl_klass(); bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass); - bool is_lambda = lambda_magic_klass != NULL && klass->is_subtype_of(lambda_magic_klass); return (should_verify_for(klass->class_loader(), should_verify_class) && // return if the class is a bootstrapping class @@ -215,9 +213,7 @@ // NOTE: this is called too early in the bootstrapping process to be // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. // Also for lambda generated code, gte jdk8 - (!is_reflect || VerifyReflectionBytecodes) && - (!is_lambda || VerifyLambdaBytecodes) - ); + (!is_reflect || VerifyReflectionBytecodes)); } Symbol* Verifier::inference_verify( @@ -2306,6 +2302,24 @@ } } +bool ClassVerifier::is_same_or_direct_interface( + instanceKlassHandle klass, + VerificationType klass_type, + VerificationType ref_class_type) { + if (ref_class_type.equals(klass_type)) return true; + Array* local_interfaces = klass->local_interfaces(); + if (local_interfaces != NULL) { + for (int x = 0; x < local_interfaces->length(); x++) { + Klass* k = local_interfaces->at(x); + assert (k != NULL && k->is_interface(), "invalid interface"); + if (ref_class_type.equals(VerificationType::reference_type(k->name()))) { + return true; + } + } + } + return false; +} + void ClassVerifier::verify_invoke_instructions( RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, bool *this_uninit, VerificationType return_type, @@ -2436,23 +2450,38 @@ return; } } else if (opcode == Bytecodes::_invokespecial - && !ref_class_type.equals(current_type()) + && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) && !ref_class_type.equals(VerificationType::reference_type( current_class()->super()->name()))) { bool subtype = false; + bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; if (!current_class()->is_anonymous()) { subtype = ref_class_type.is_assignable_from( current_type(), this, CHECK_VERIFY(this)); } else { - subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( - current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); + VerificationType host_klass_type = + VerificationType::reference_type(current_class()->host_klass()->name()); + subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this)); + + // If invokespecial of IMR, need to recheck for same or + // direct interface relative to the host class + have_imr_indirect = (have_imr_indirect && + !is_same_or_direct_interface( + InstanceKlass::cast(current_class()->host_klass()), + host_klass_type, ref_class_type)); } if (!subtype) { verify_error(ErrorContext::bad_code(bci), "Bad invokespecial instruction: " "current class isn't assignable to reference class."); return; + } else if (have_imr_indirect) { + verify_error(ErrorContext::bad_code(bci), + "Bad invokespecial instruction: " + "interface method reference is in an indirect superinterface."); + return; } + } // Match method descriptor with operand stack for (int i = nargs - 1; i >= 0; i--) { // Run backwards diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/verifier.hpp --- a/src/share/vm/classfile/verifier.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/verifier.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -345,6 +345,9 @@ // that a class has been verified and prepared for execution. bool was_recursively_verified() { return _klass->is_rewritten(); } + bool is_same_or_direct_interface(instanceKlassHandle klass, + VerificationType klass_type, VerificationType ref_class_type); + public: enum { BYTECODE_OFFSET = 1, diff -r f76593e3fedb -r 163b418ec095 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -273,7 +273,6 @@ template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ - template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \ /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \ template(findMethodHandleType_name, "findMethodHandleType") \ template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \ @@ -425,6 +424,7 @@ template(findNative_name, "findNative") \ template(deadChild_name, "deadChild") \ template(addClass_name, "addClass") \ + template(throwIllegalAccessError_name, "throwIllegalAccessError") \ template(getFromClass_name, "getFromClass") \ template(dispatch_name, "dispatch") \ template(getSystemClassLoader_name, "getSystemClassLoader") \ diff -r f76593e3fedb -r 163b418ec095 src/share/vm/code/compiledIC.cpp --- a/src/share/vm/code/compiledIC.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/code/compiledIC.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -427,7 +427,7 @@ TRAPS) { nmethod* method_code = method->code(); address entry = NULL; - if (method_code != NULL) { + if (method_code != NULL && method_code->is_in_use()) { // Call to compiled code if (static_bound || is_optimized) { entry = method_code->verified_entry_point(); @@ -554,7 +554,7 @@ void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info) { nmethod* m_code = m->code(); info._callee = m; - if (m_code != NULL) { + if (m_code != NULL && m_code->is_in_use()) { info._to_interpreter = false; info._entry = m_code->verified_entry_point(); } else { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/code/nmethod.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -504,7 +504,7 @@ // Fill in default values for various flag fields void nmethod::init_defaults() { - _state = alive; + _state = in_use; _marked_for_reclamation = 0; _has_flushed_dependencies = 0; _has_unsafe_access = 0; @@ -1790,8 +1790,8 @@ CompiledICHolder* cichk_oop = ic->cached_icholder(); if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) && cichk_oop->holder_klass()->is_loader_alive(is_alive)) { - continue; - } + continue; + } } else { Metadata* ic_oop = ic->cached_metadata(); if (ic_oop != NULL) { @@ -1807,8 +1807,8 @@ ShouldNotReachHere(); } } - } - ic->set_to_clean(); + } + ic->set_to_clean(); } } } @@ -2532,8 +2532,8 @@ void nmethod::verify_interrupt_point(address call_site) { // Verify IC only when nmethod installation is finished. - bool is_installed = (method()->code() == this) // nmethod is in state 'alive' and installed - || !this->is_in_use(); // nmethod is installed, but not in 'alive' state + bool is_installed = (method()->code() == this) // nmethod is in state 'in_use' and installed + || !this->is_in_use(); // nmethod is installed, but not in 'in_use' state if (is_installed) { Thread *cur = Thread::current(); if (CompiledIC_lock->owner() == cur || diff -r f76593e3fedb -r 163b418ec095 src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/code/nmethod.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -192,11 +192,12 @@ bool _oops_are_stale; // indicates that it's no longer safe to access oops section #endif - enum { alive = 0, - not_entrant = 1, // uncommon trap has happened but activations may still exist - zombie = 2, - unloaded = 3 }; - + enum { in_use = 0, // executable nmethod + not_entrant = 1, // marked for deoptimization but activations may still exist, + // will be transformed to zombie when all activations are gone + zombie = 2, // no activations exist, nmethod is ready for purge + unloaded = 3 }; // there should be no activations, should not be called, + // will be transformed to zombie immediately jbyte _scavenge_root_state; @@ -430,8 +431,8 @@ address verified_entry_point() const { return _verified_entry_point; } // if klass is correct // flag accessing and manipulation - bool is_in_use() const { return _state == alive; } - bool is_alive() const { return _state == alive || _state == not_entrant; } + bool is_in_use() const { return _state == in_use; } + bool is_alive() const { return _state == in_use || _state == not_entrant; } bool is_not_entrant() const { return _state == not_entrant; } bool is_zombie() const { return _state == zombie; } bool is_unloaded() const { return _state == unloaded; } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -1993,7 +1993,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); STWGCTimer* gc_timer = GenMarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); @@ -2089,7 +2089,7 @@ size_policy()->msc_collection_end(gch->gc_cause()); } - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); @@ -2475,7 +2475,7 @@ void CMSCollector::register_gc_start(GCCause::Cause cause) { _cms_start_registered = true; - _gc_timer_cm->register_gc_start(os::elapsed_counter()); + _gc_timer_cm->register_gc_start(); _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start()); } @@ -2483,7 +2483,7 @@ if (_cms_start_registered) { report_heap_summary(GCWhen::AfterGC); - _gc_timer_cm->register_gc_end(os::elapsed_counter()); + _gc_timer_cm->register_gc_end(); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _cms_start_registered = false; } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -145,7 +145,7 @@ ); #endif /* USDT2 */ - _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark"); GenCollectedHeap* gch = GenCollectedHeap::heap(); GCCauseSetter gccs(gch, GCCause::_cms_initial_mark); @@ -157,7 +157,7 @@ VM_CMS_Operation::verify_after_gc(); - _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_end(); #ifndef USDT2 HS_DTRACE_PROBE(hs_private, cms__initmark__end); @@ -182,7 +182,7 @@ ); #endif /* USDT2 */ - _collector->_gc_timer_cm->register_gc_pause_start("Final Mark", os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_start("Final Mark"); GenCollectedHeap* gch = GenCollectedHeap::heap(); GCCauseSetter gccs(gch, GCCause::_cms_final_remark); @@ -195,7 +195,7 @@ VM_CMS_Operation::verify_after_gc(); _collector->save_heap_summary(); - _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_end(); #ifndef USDT2 HS_DTRACE_PROBE(hs_private, cms__remark__end); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp --- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -27,6 +27,7 @@ #include "gc_implementation/g1/concurrentG1RefineThread.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1HotCardCache.hpp" +#include "runtime/java.hpp" ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) : _threads(NULL), _n_threads(0), @@ -62,6 +63,10 @@ for (int i = _n_threads - 1; i >= 0; i--) { ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i); assert(t != NULL, "Conc refine should have been created"); + if (t->osthread() == NULL) { + vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread"); + } + assert(t->cg1r() == this, "Conc refine thread should refer to this"); _threads[i] = t; next = t; diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -553,6 +553,9 @@ _cmThread = new ConcurrentMarkThread(this); assert(cmThread() != NULL, "CM Thread should have been created"); assert(cmThread()->cm() != NULL, "CM Thread should refer to this cm"); + if (_cmThread->osthread() == NULL) { + vm_shutdown_during_initialization("Could not create ConcurrentMarkThread"); + } assert(CGC_lock != NULL, "Where's the CGC_lock?"); assert(_markBitMap1.covers(heap_rs), "_markBitMap1 inconsistency"); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -56,6 +56,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.pcgc.inline.hpp" #include "runtime/vmThread.hpp" +#include "utilities/ticks.hpp" size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; @@ -1284,7 +1285,7 @@ } STWGCTimer* gc_timer = G1MarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer(); gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start()); @@ -1552,7 +1553,7 @@ post_full_gc_dump(gc_timer); - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); } @@ -2492,7 +2493,7 @@ FullGCCount_lock->notify_all(); } -void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) { +void G1CollectedHeap::register_concurrent_cycle_start(const Ticks& start_time) { _concurrent_cycle_started = true; _gc_timer_cm->register_gc_start(start_time); @@ -2506,7 +2507,7 @@ _gc_tracer_cm->report_concurrent_mode_failure(); } - _gc_timer_cm->register_gc_end(os::elapsed_counter()); + _gc_timer_cm->register_gc_end(); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _concurrent_cycle_started = false; @@ -3897,7 +3898,7 @@ return false; } - _gc_timer_stw->register_gc_start(os::elapsed_counter()); + _gc_timer_stw->register_gc_start(); _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start()); @@ -4275,7 +4276,7 @@ _gc_tracer_stw->report_evacuation_info(&evacuation_info); _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold()); - _gc_timer_stw->register_gc_end(os::elapsed_counter()); + _gc_timer_stw->register_gc_end(); _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions()); } // It should now be safe to tell the concurrent mark thread to start diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -72,6 +72,7 @@ class G1OldTracer; class EvacuationFailedInfo; class nmethod; +class Ticks; typedef OverflowTaskQueue RefToScanQueue; typedef GenericTaskQueueSet RefToScanQueueSet; @@ -751,7 +752,7 @@ return _old_marking_cycles_completed; } - void register_concurrent_cycle_start(jlong start_time); + void register_concurrent_cycle_start(const Ticks& start_time); void register_concurrent_cycle_end(); void trace_heap_after_concurrent_cycle(); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -915,7 +915,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); assert(gch->kind() == CollectedHeap::GenCollectedHeap, "not a CMS generational heap"); @@ -1091,7 +1091,7 @@ gch->trace_heap_after_gc(&gc_tracer); gc_tracer.report_tenuring_threshold(tenuring_threshold()); - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -114,7 +114,7 @@ assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); GCCause::Cause gc_cause = heap->gc_cause(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start()); PSAdaptiveSizePolicy* size_policy = heap->size_policy(); @@ -390,7 +390,7 @@ ParallelTaskTerminator::print_termination_counts(); #endif - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -2006,7 +2006,7 @@ ParallelScavengeHeap* heap = gc_heap(); - _gc_timer.register_gc_start(os::elapsed_counter()); + _gc_timer.register_gc_start(); _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start()); TimeStamp marking_start; @@ -2244,7 +2244,7 @@ ParallelTaskTerminator::print_termination_counts(); #endif - _gc_timer.register_gc_end(os::elapsed_counter()); + _gc_timer.register_gc_end(); _gc_tracer.report_dense_prefix(dense_prefix(old_space_id)); _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); @@ -2433,20 +2433,6 @@ _gc_tracer.report_object_count_after_gc(is_alive_closure()); } -void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - PSParallelCompact::follow_class_loader(cm, cld); -} - -void PSParallelCompact::adjust_klass(ParCompactionManager* cm, Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - PSParallelCompact::adjust_class_loader(cm, cld); -} - void PSParallelCompact::follow_class_loader(ParCompactionManager* cm, ClassLoaderData* cld) { PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); @@ -2455,13 +2441,6 @@ cld->oops_do(&mark_and_push_closure, &follow_klass_closure, true); } -void PSParallelCompact::adjust_class_loader(ParCompactionManager* cm, - ClassLoaderData* cld) { - cld->oops_do(PSParallelCompact::adjust_pointer_closure(), - PSParallelCompact::adjust_klass_closure(), - true); -} - // This should be moved to the shared markSweep code! class PSAlwaysTrueClosure: public BoolObjectClosure { public: diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -1200,13 +1200,10 @@ T* p); template static inline void adjust_pointer(T* p); - static void follow_klass(ParCompactionManager* cm, Klass* klass); - static void adjust_klass(ParCompactionManager* cm, Klass* klass); + static inline void follow_klass(ParCompactionManager* cm, Klass* klass); static void follow_class_loader(ParCompactionManager* cm, ClassLoaderData* klass); - static void adjust_class_loader(ParCompactionManager* cm, - ClassLoaderData* klass); // Compaction support. // Return true if p is in the range [beg_addr, end_addr). @@ -1380,6 +1377,11 @@ } } +inline void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) { + oop holder = klass->klass_holder(); + PSParallelCompact::mark_and_push(cm, &holder); +} + template inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) { mark_and_push(_compaction_manager, p); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -263,7 +263,7 @@ assert(_preserved_mark_stack.is_empty(), "should be empty"); assert(_preserved_oop_stack.is_empty(), "should be empty"); - _gc_timer.register_gc_start(os::elapsed_counter()); + _gc_timer.register_gc_start(); TimeStamp scavenge_entry; TimeStamp scavenge_midpoint; @@ -691,7 +691,7 @@ #endif - _gc_timer.register_gc_end(os::elapsed_counter()); + _gc_timer.register_gc_end(); _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTimer.cpp --- a/src/share/vm/gc_implementation/shared/gcTimer.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTimer.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -25,52 +25,55 @@ #include "precompiled.hpp" #include "gc_implementation/shared/gcTimer.hpp" #include "utilities/growableArray.hpp" +#include "utilities/ticks.inline.hpp" -void GCTimer::register_gc_start(jlong time) { +// the "time" parameter for most functions +// has a default value set by Ticks::now() + +void GCTimer::register_gc_start(const Ticks& time) { _time_partitions.clear(); _gc_start = time; } -void GCTimer::register_gc_end(jlong time) { +void GCTimer::register_gc_end(const Ticks& time) { assert(!_time_partitions.has_active_phases(), "We should have ended all started phases, before ending the GC"); _gc_end = time; } -void GCTimer::register_gc_pause_start(const char* name, jlong time) { +void GCTimer::register_gc_pause_start(const char* name, const Ticks& time) { _time_partitions.report_gc_phase_start(name, time); } -void GCTimer::register_gc_pause_end(jlong time) { +void GCTimer::register_gc_pause_end(const Ticks& time) { _time_partitions.report_gc_phase_end(time); } -void GCTimer::register_gc_phase_start(const char* name, jlong time) { +void GCTimer::register_gc_phase_start(const char* name, const Ticks& time) { _time_partitions.report_gc_phase_start(name, time); } -void GCTimer::register_gc_phase_end(jlong time) { +void GCTimer::register_gc_phase_end(const Ticks& time) { _time_partitions.report_gc_phase_end(time); } - -void STWGCTimer::register_gc_start(jlong time) { +void STWGCTimer::register_gc_start(const Ticks& time) { GCTimer::register_gc_start(time); register_gc_pause_start("GC Pause", time); } -void STWGCTimer::register_gc_end(jlong time) { +void STWGCTimer::register_gc_end(const Ticks& time) { register_gc_pause_end(time); GCTimer::register_gc_end(time); } -void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) { - GCTimer::register_gc_pause_start(name, time); +void ConcurrentGCTimer::register_gc_pause_start(const char* name) { + GCTimer::register_gc_pause_start(name); } -void ConcurrentGCTimer::register_gc_pause_end(jlong time) { - GCTimer::register_gc_pause_end(time); +void ConcurrentGCTimer::register_gc_pause_end() { + GCTimer::register_gc_pause_end(); } void PhasesStack::clear() { @@ -111,11 +114,11 @@ void TimePartitions::clear() { _phases->clear(); _active_phases.clear(); - _sum_of_pauses = 0; - _longest_pause = 0; + _sum_of_pauses = Tickspan(); + _longest_pause = Tickspan(); } -void TimePartitions::report_gc_phase_start(const char* name, jlong time) { +void TimePartitions::report_gc_phase_start(const char* name, const Ticks& time) { assert(_phases->length() <= 1000, "Too many recored phases?"); int level = _active_phases.count(); @@ -133,13 +136,13 @@ void TimePartitions::update_statistics(GCPhase* phase) { // FIXME: This should only be done for pause phases if (phase->level() == 0) { - jlong pause = phase->end() - phase->start(); + const Tickspan pause = phase->end() - phase->start(); _sum_of_pauses += pause; _longest_pause = MAX2(pause, _longest_pause); } } -void TimePartitions::report_gc_phase_end(jlong time) { +void TimePartitions::report_gc_phase_end(const Ticks& time) { int phase_index = _active_phases.pop(); GCPhase* phase = _phases->adr_at(phase_index); phase->set_end(time); @@ -157,14 +160,6 @@ return _phases->adr_at(index); } -jlong TimePartitions::sum_of_pauses() { - return _sum_of_pauses; -} - -jlong TimePartitions::longest_pause() { - return _longest_pause; -} - bool TimePartitions::has_active_phases() { return _active_phases.count() > 0; } @@ -194,7 +189,7 @@ max_nested_pause_phases(); } - static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) { + static void validate_pause_phase(GCPhase* phase, int level, const char* name, const Ticks& start, const Ticks& end) { assert(phase->level() == level, "Incorrect level"); assert(strcmp(phase->name(), name) == 0, "Incorrect name"); assert(phase->start() == start, "Incorrect start"); @@ -209,8 +204,8 @@ TimePartitionPhasesIterator iter(&time_partitions); validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8); - assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect"); - assert(time_partitions.longest_pause() == 8-2, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(8) - Ticks(2), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(8) - Ticks(2), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -227,8 +222,8 @@ validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3); validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6); - assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); - assert(time_partitions.longest_pause() == 2, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(2) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -245,8 +240,8 @@ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5); validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4); - assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); - assert(time_partitions.longest_pause() == 3, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(3) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -269,8 +264,8 @@ validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7); validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6); - assert(time_partitions.sum_of_pauses() == 7, "Incorrect"); - assert(time_partitions.longest_pause() == 7, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(7) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(7) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -298,8 +293,8 @@ validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8); validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10); - assert(time_partitions.sum_of_pauses() == 9, "Incorrect"); - assert(time_partitions.longest_pause() == 9, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(9) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(9) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -336,8 +331,8 @@ validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13); validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16); - assert(time_partitions.sum_of_pauses() == 15, "Incorrect"); - assert(time_partitions.longest_pause() == 15, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(15) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(15) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTimer.hpp --- a/src/share/vm/gc_implementation/shared/gcTimer.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTimer.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "prims/jni_md.h" #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" class ConcurrentPhase; class GCPhase; @@ -45,21 +46,21 @@ class GCPhase { const char* _name; int _level; - jlong _start; - jlong _end; + Ticks _start; + Ticks _end; public: void set_name(const char* name) { _name = name; } - const char* name() { return _name; } + const char* name() const { return _name; } - int level() { return _level; } + int level() const { return _level; } void set_level(int level) { _level = level; } - jlong start() { return _start; } - void set_start(jlong time) { _start = time; } + const Ticks start() const { return _start; } + void set_start(const Ticks& time) { _start = time; } - jlong end() { return _end; } - void set_end(jlong time) { _end = time; } + const Ticks end() const { return _end; } + void set_end(const Ticks& time) { _end = time; } virtual void accept(PhaseVisitor* visitor) = 0; }; @@ -102,22 +103,22 @@ GrowableArray* _phases; PhasesStack _active_phases; - jlong _sum_of_pauses; - jlong _longest_pause; + Tickspan _sum_of_pauses; + Tickspan _longest_pause; public: TimePartitions(); ~TimePartitions(); void clear(); - void report_gc_phase_start(const char* name, jlong time); - void report_gc_phase_end(jlong time); + void report_gc_phase_start(const char* name, const Ticks& time); + void report_gc_phase_end(const Ticks& time); int num_phases() const; GCPhase* phase_at(int index) const; - jlong sum_of_pauses(); - jlong longest_pause(); + const Tickspan sum_of_pauses() const { return _sum_of_pauses; } + const Tickspan longest_pause() const { return _longest_pause; } bool has_active_phases(); private: @@ -133,40 +134,37 @@ class GCTimer : public ResourceObj { NOT_PRODUCT(friend class GCTimerTest;) protected: - jlong _gc_start; - jlong _gc_end; + Ticks _gc_start; + Ticks _gc_end; TimePartitions _time_partitions; public: - virtual void register_gc_start(jlong time); - virtual void register_gc_end(jlong time); + virtual void register_gc_start(const Ticks& time = Ticks::now()); + virtual void register_gc_end(const Ticks& time = Ticks::now()); - void register_gc_phase_start(const char* name, jlong time); - void register_gc_phase_end(jlong time); + void register_gc_phase_start(const char* name, const Ticks& time); + void register_gc_phase_end(const Ticks& time); - jlong gc_start() { return _gc_start; } - jlong gc_end() { return _gc_end; } + const Ticks gc_start() const { return _gc_start; } + const Ticks gc_end() const { return _gc_end; } TimePartitions* time_partitions() { return &_time_partitions; } - long longest_pause(); - long sum_of_pauses(); - protected: - void register_gc_pause_start(const char* name, jlong time); - void register_gc_pause_end(jlong time); + void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now()); + void register_gc_pause_end(const Ticks& time = Ticks::now()); }; class STWGCTimer : public GCTimer { public: - virtual void register_gc_start(jlong time); - virtual void register_gc_end(jlong time); + virtual void register_gc_start(const Ticks& time = Ticks::now()); + virtual void register_gc_end(const Ticks& time = Ticks::now()); }; class ConcurrentGCTimer : public GCTimer { public: - void register_gc_pause_start(const char* name, jlong time); - void register_gc_pause_end(jlong time); + void register_gc_pause_start(const char* name); + void register_gc_pause_end(); }; class TimePartitionPhasesIterator { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTrace.cpp --- a/src/share/vm/gc_implementation/shared/gcTrace.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -32,6 +32,7 @@ #include "memory/referenceProcessorStats.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.inline.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/g1/evacuationInfo.hpp" @@ -45,7 +46,7 @@ return GCTracer_next_gc_id++; } -void GCTracer::report_gc_start_impl(GCCause::Cause cause, jlong timestamp) { +void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) { assert_unset_gc_id(); GCId gc_id = create_new_gc_id(); @@ -54,7 +55,7 @@ _shared_gc_info.set_start_timestamp(timestamp); } -void GCTracer::report_gc_start(GCCause::Cause cause, jlong timestamp) { +void GCTracer::report_gc_start(GCCause::Cause cause, const Ticks& timestamp) { assert_unset_gc_id(); report_gc_start_impl(cause, timestamp); @@ -64,7 +65,7 @@ return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID; } -void GCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void GCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses()); @@ -75,7 +76,7 @@ send_garbage_collection_event(); } -void GCTracer::report_gc_end(jlong timestamp, TimePartitions* time_partitions) { +void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); report_gc_end_impl(timestamp, time_partitions); @@ -97,10 +98,10 @@ const GCId _gc_id; const double _size_threshold_percentage; const size_t _total_size_in_words; - const jlong _timestamp; + const Ticks _timestamp; public: - ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, jlong timestamp) : + ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, const Ticks& timestamp) : _gc_id(gc_id), _size_threshold_percentage(ObjectCountCutOffPercent / 100), _total_size_in_words(total_size_in_words), @@ -131,9 +132,7 @@ if (!cit.allocation_failed()) { HeapInspection hi(false, false, false, NULL); hi.populate_table(&cit, is_alive_cl); - - jlong timestamp = os::elapsed_counter(); - ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), timestamp); + ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), Ticks::now()); cit.iterate(&event_sender); } } @@ -147,7 +146,7 @@ send_meta_space_summary_event(when, meta_space_summary); } -void YoungGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported"); @@ -167,14 +166,14 @@ _tenuring_threshold = tenuring_threshold; } -void OldGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); GCTracer::report_gc_end_impl(timestamp, time_partitions); send_old_gc_event(); } -void ParallelOldTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void ParallelOldTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); OldGCTracer::report_gc_end_impl(timestamp, time_partitions); @@ -200,7 +199,7 @@ _g1_young_gc_info.set_type(type); } -void G1NewTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void G1NewTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); YoungGCTracer::report_gc_end_impl(timestamp, time_partitions); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTrace.hpp --- a/src/share/vm/gc_implementation/shared/gcTrace.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -35,6 +35,7 @@ #include "gc_implementation/g1/g1YCTypes.hpp" #endif #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" typedef uint GCId; @@ -47,8 +48,6 @@ class BoolObjectClosure; class SharedGCInfo VALUE_OBJ_CLASS_SPEC { - static const jlong UNSET_TIMESTAMP = -1; - public: static const GCId UNSET_GCID = (GCId)-1; @@ -56,23 +55,30 @@ GCId _id; GCName _name; GCCause::Cause _cause; - jlong _start_timestamp; - jlong _end_timestamp; - jlong _sum_of_pauses; - jlong _longest_pause; + Ticks _start_timestamp; + Ticks _end_timestamp; + Tickspan _sum_of_pauses; + Tickspan _longest_pause; public: - SharedGCInfo(GCName name) : _id(UNSET_GCID), _name(name), _cause(GCCause::_last_gc_cause), - _start_timestamp(UNSET_TIMESTAMP), _end_timestamp(UNSET_TIMESTAMP), _sum_of_pauses(0), _longest_pause(0) {} + SharedGCInfo(GCName name) : + _id(UNSET_GCID), + _name(name), + _cause(GCCause::_last_gc_cause), + _start_timestamp(), + _end_timestamp(), + _sum_of_pauses(), + _longest_pause() { + } void set_id(GCId id) { _id = id; } GCId id() const { return _id; } - void set_start_timestamp(jlong timestamp) { _start_timestamp = timestamp; } - jlong start_timestamp() const { return _start_timestamp; } + void set_start_timestamp(const Ticks& timestamp) { _start_timestamp = timestamp; } + const Ticks start_timestamp() const { return _start_timestamp; } - void set_end_timestamp(jlong timestamp) { _end_timestamp = timestamp; } - jlong end_timestamp() const { return _end_timestamp; } + void set_end_timestamp(const Ticks& timestamp) { _end_timestamp = timestamp; } + const Ticks end_timestamp() const { return _end_timestamp; } void set_name(GCName name) { _name = name; } GCName name() const { return _name; } @@ -80,11 +86,11 @@ void set_cause(GCCause::Cause cause) { _cause = cause; } GCCause::Cause cause() const { return _cause; } - void set_sum_of_pauses(jlong duration) { _sum_of_pauses = duration; } - jlong sum_of_pauses() const { return _sum_of_pauses; } + void set_sum_of_pauses(const Tickspan& duration) { _sum_of_pauses = duration; } + const Tickspan sum_of_pauses() const { return _sum_of_pauses; } - void set_longest_pause(jlong duration) { _longest_pause = duration; } - jlong longest_pause() const { return _longest_pause; } + void set_longest_pause(const Tickspan& duration) { _longest_pause = duration; } + const Tickspan longest_pause() const { return _longest_pause; } }; class ParallelOldGCInfo VALUE_OBJ_CLASS_SPEC { @@ -116,8 +122,8 @@ SharedGCInfo _shared_gc_info; public: - void report_gc_start(GCCause::Cause cause, jlong timestamp); - void report_gc_end(jlong timestamp, TimePartitions* time_partitions); + void report_gc_start(GCCause::Cause cause, const Ticks& timestamp); + void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions); void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const; void report_gc_reference_stats(const ReferenceProcessorStats& rp) const; void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN; @@ -125,8 +131,8 @@ protected: GCTracer(GCName name) : _shared_gc_info(name) {} - virtual void report_gc_start_impl(GCCause::Cause cause, jlong timestamp); - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); private: void send_garbage_collection_event() const; @@ -143,7 +149,7 @@ protected: YoungGCTracer(GCName name) : GCTracer(name), _tenuring_threshold(UNSET_TENURING_THRESHOLD) {} - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); public: void report_promotion_failed(const PromotionFailedInfo& pf_info); @@ -157,7 +163,7 @@ class OldGCTracer : public GCTracer { protected: OldGCTracer(GCName name) : GCTracer(name) {} - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); public: void report_concurrent_mode_failure(); @@ -175,7 +181,7 @@ void report_dense_prefix(void* dense_prefix); protected: - void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); private: void send_parallel_old_event() const; @@ -209,7 +215,7 @@ G1NewTracer() : YoungGCTracer(G1New) {} void report_yc_type(G1YCType type); - void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); void report_evacuation_info(EvacuationInfo* info); void report_evacuation_failed(EvacuationFailedInfo& ef_info); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTraceSend.cpp --- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -55,12 +55,11 @@ } void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const { - EventGCReferenceStatistics e(UNTIMED); + EventGCReferenceStatistics e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_type((u1)type); e.set_count(count); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -107,22 +106,20 @@ } void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const { - EventPromotionFailed e(UNTIMED); + EventPromotionFailed e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(pf_info)); e.set_thread(pf_info.thread()->thread_id()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } // Common to CMS and G1 void OldGCTracer::send_concurrent_mode_failure_event() { - EventConcurrentModeFailure e(UNTIMED); + EventConcurrentModeFailure e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -140,7 +137,7 @@ } void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) { - EventEvacuationInfo e(UNTIMED); + EventEvacuationInfo e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_cSetRegions(info->collectionset_regions()); @@ -151,17 +148,15 @@ e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied()); e.set_bytesCopied(info->bytes_copied()); e.set_regionsFreed(info->regions_freed()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const { - EventEvacuationFailed e(UNTIMED); + EventEvacuationFailed e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(ef_info)); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -195,13 +190,12 @@ void visit(const GCHeapSummary* heap_summary) const { const VirtualSpaceSummary& heap_space = heap_summary->heap(); - EventGCHeapSummary e(UNTIMED); + EventGCHeapSummary e; if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); e.set_heapSpace(to_trace_struct(heap_space)); e.set_heapUsed(heap_summary->used()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -216,7 +210,7 @@ const SpaceSummary& from_space = ps_heap_summary->from(); const SpaceSummary& to_space = ps_heap_summary->to(); - EventPSHeapSummary e(UNTIMED); + EventPSHeapSummary e; if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); @@ -227,7 +221,6 @@ e.set_edenSpace(to_trace_struct(ps_heap_summary->eden())); e.set_fromSpace(to_trace_struct(ps_heap_summary->from())); e.set_toSpace(to_trace_struct(ps_heap_summary->to())); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -249,14 +242,13 @@ } void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const { - EventMetaspaceSummary e(UNTIMED); + EventMetaspaceSummary e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_when((u1) when); e.set_metaspace(to_trace_struct(meta_space_summary.meta_space())); e.set_dataSpace(to_trace_struct(meta_space_summary.data_space())); e.set_classSpace(to_trace_struct(meta_space_summary.class_space())); - e.set_endtime(os::elapsed_counter()); e.commit(); } } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTraceTime.cpp --- a/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -31,12 +31,13 @@ #include "runtime/thread.inline.hpp" #include "runtime/timer.hpp" #include "utilities/ostream.hpp" +#include "utilities/ticks.inline.hpp" GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) : - _title(title), _doit(doit), _print_cr(print_cr), _timer(timer) { + _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() { if (_doit || _timer != NULL) { - _start_counter = os::elapsed_counter(); + _start_counter.stamp(); } if (_timer != NULL) { @@ -57,10 +58,10 @@ } GCTraceTime::~GCTraceTime() { - jlong stop_counter = 0; + Ticks stop_counter; if (_doit || _timer != NULL) { - stop_counter = os::elapsed_counter(); + stop_counter.stamp(); } if (_timer != NULL) { @@ -68,11 +69,12 @@ } if (_doit) { - double seconds = TimeHelper::counter_to_seconds(stop_counter - _start_counter); + const Tickspan duration = stop_counter - _start_counter; + double duration_in_seconds = TicksToTimeHelper::seconds(duration); if (_print_cr) { - gclog_or_tty->print_cr(", %3.7f secs]", seconds); + gclog_or_tty->print_cr(", %3.7f secs]", duration_in_seconds); } else { - gclog_or_tty->print(", %3.7f secs]", seconds); + gclog_or_tty->print(", %3.7f secs]", duration_in_seconds); } gclog_or_tty->flush(); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/gcTraceTime.hpp --- a/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP #include "prims/jni_md.h" +#include "utilities/ticks.hpp" class GCTimer; @@ -34,7 +35,7 @@ bool _doit; bool _print_cr; GCTimer* _timer; - jlong _start_counter; + Ticks _start_counter; public: GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/markSweep.cpp --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -66,29 +66,10 @@ klass->oops_do(&MarkSweep::adjust_pointer_closure); } -void MarkSweep::follow_klass(Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - MarkSweep::follow_class_loader(cld); -} - -void MarkSweep::adjust_klass(Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - MarkSweep::adjust_class_loader(cld); -} - void MarkSweep::follow_class_loader(ClassLoaderData* cld) { cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true); } -void MarkSweep::adjust_class_loader(ClassLoaderData* cld) { - cld->oops_do(&MarkSweep::adjust_pointer_closure, &MarkSweep::adjust_klass_closure, true); -} - - void MarkSweep::follow_stack() { do { while (!_marking_stack.is_empty()) { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/markSweep.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -172,10 +172,8 @@ static void follow_stack(); // Empty marking stack. static void follow_klass(Klass* klass); - static void adjust_klass(Klass* klass); static void follow_class_loader(ClassLoaderData* cld); - static void adjust_class_loader(ClassLoaderData* cld); static void preserve_mark(oop p, markOop mark); // Save the mark word so it can be restored later diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/markSweep.inline.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -44,6 +44,11 @@ } } +inline void MarkSweep::follow_klass(Klass* klass) { + oop op = klass->klass_holder(); + MarkSweep::mark_and_push(&op); +} + template inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/objectCountEventSender.cpp --- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -28,10 +28,11 @@ #include "memory/heapInspection.hpp" #include "trace/tracing.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_SERVICES -void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { +void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) { #if INCLUDE_TRACE assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/gc_implementation/shared/objectCountEventSender.hpp --- a/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -32,10 +32,11 @@ #if INCLUDE_SERVICES class KlassInfoEntry; +class Ticks; class ObjectCountEventSender : public AllStatic { public: - static void send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp); + static void send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp); static bool should_send_event(); }; diff -r f76593e3fedb -r 163b418ec095 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/interpreter/linkResolver.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -242,8 +242,20 @@ // Look up method in klasses, including static methods // Then look up local default methods -void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) { Method* result_oop = klass->uncached_lookup_method(name, signature); + + // JDK 8, JVMS 5.4.3.4: Interface method resolution should + // ignore static and non-public methods of java.lang.Object, + // like clone, finalize, registerNatives. + if (in_imethod_resolve && + result_oop != NULL && + klass->is_interface() && + (result_oop->is_static() || !result_oop->is_public()) && + result_oop->method_holder() == SystemDictionary::Object_klass()) { + result_oop = NULL; + } + if (result_oop == NULL) { Array* default_methods = InstanceKlass::cast(klass())->default_methods(); if (default_methods != NULL) { @@ -251,7 +263,7 @@ } } - if (EnableInvokeDynamic && result_oop != NULL) { + if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) { vmIntrinsics::ID iid = result_oop->intrinsic_id(); if (MethodHandles::is_signature_polymorphic(iid)) { // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. @@ -267,8 +279,8 @@ Method* result_oop = klass->uncached_lookup_method(name, signature); result = methodHandle(THREAD, result_oop); while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { - klass = KlassHandle(THREAD, result->method_holder()->super()); - result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); + KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); + result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); } if (result.is_null()) { @@ -420,28 +432,18 @@ AccessFlags flags = sel_method->access_flags(); - // Special case #1: arrays always override "clone". JVMS 2.15. + // Special case: arrays always override "clone". JVMS 2.15. // If the resolved klass is an array class, and the declaring class // is java.lang.Object and the method is "clone", set the flags // to public. - // Special case #2: If the resolved klass is an interface, and - // the declaring class is java.lang.Object, and the method is - // "clone" or "finalize", set the flags to public. If the - // resolved interface does not contain "clone" or "finalize" - // methods, the method/interface method resolution looks to - // the interface's super class, java.lang.Object. With JDK 8 - // interface accessability check requirement, special casing - // this scenario is necessary to avoid an IAE. // - // We'll check for each method name first and then java.lang.Object - // to best short-circuit out of these tests. - if (((sel_method->name() == vmSymbols::clone_name() && - (resolved_klass->oop_is_array() || resolved_klass->is_interface())) || - (sel_method->name() == vmSymbols::finalize_method_name() && - resolved_klass->is_interface())) && - sel_klass() == SystemDictionary::Object_klass()) { + // We'll check for the method name first, as that's most likely + // to be false (so we'll short-circuit out of these tests). + if (sel_method->name() == vmSymbols::clone_name() && + sel_klass() == SystemDictionary::Object_klass() && + resolved_klass->oop_is_array()) { // We need to change "protected" to "public". - assert(flags.is_protected(), "clone or finalize not protected?"); + assert(flags.is_protected(), "clone not protected?"); jint new_flags = flags.as_int(); new_flags = new_flags & (~JVM_ACC_PROTECTED); new_flags = new_flags | JVM_ACC_PUBLIC; @@ -503,11 +505,14 @@ } if (code == Bytecodes::_invokeinterface) { - resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); } else if (code == Bytecodes::_invokevirtual) { resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); + } else if (!resolved_klass->is_interface()) { + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); } else { - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK); + bool nostatics = (code == Bytecodes::_invokestatic) ? false : true; + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK); } } @@ -528,7 +533,7 @@ } // 2. lookup method in resolved klass and its super klasses - lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK); if (resolved_method.is_null()) { // not found in the class hierarchy // 3. lookup method in all the interfaces implemented by the resolved klass @@ -612,7 +617,8 @@ Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, - bool check_access, TRAPS) { + bool check_access, + bool nostatics, TRAPS) { // check if klass is interface if (!resolved_klass->is_interface()) { @@ -623,7 +629,8 @@ } // lookup method in this interface or its super, java.lang.Object - lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); + // JDK8: also look for static methods + lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK); if (resolved_method.is_null()) { // lookup method in all the super-interfaces @@ -638,6 +645,16 @@ } } + if (nostatics && resolved_method->is_static()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature())); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + + if (check_access) { // JDK8 adds non-public interface methods, and accessability check requirement assert(current_klass.not_null() , "current_klass should not be null"); @@ -868,7 +885,11 @@ Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); + if (!resolved_klass->is_interface()) { + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); + } else { + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); + } assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); // check if static @@ -902,7 +923,11 @@ // and the selected method is recalculated relative to the direct superclass // superinterface.method, which explicitly does not check shadowing - resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); + if (!resolved_klass->is_interface()) { + resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK); + } else { + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); + } // check if method name is , that it is found in same klass as static type if (resolved_method->name() == vmSymbols::object_initializer_name() && @@ -919,6 +944,34 @@ return; } + // check if invokespecial's interface method reference is in an indirect superinterface + if (!current_klass.is_null() && resolved_klass->is_interface()) { + Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ? + current_klass() : + InstanceKlass::cast(current_klass())->host_klass(); + // As of the fix for 4486457 we disable verification for all of the + // dynamically-generated bytecodes associated with the 1.4 + // reflection implementation, not just those associated with + // sun/reflect/SerializationConstructorAccessor. + bool is_reflect = JDK_Version::is_gte_jdk14x_version() && + UseNewReflection && + klass_to_check->is_subclass_of( + SystemDictionary::reflect_MagicAccessorImpl_klass()); + + if (!is_reflect && + !InstanceKlass::cast(klass_to_check)->is_same_or_direct_interface(resolved_klass())) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), + "Interface method reference: %s, is in an indirect superinterface of %s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + current_klass->external_name()); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + } + // check if not static if (resolved_method->is_static()) { ResourceMark rm(THREAD); @@ -1204,7 +1257,7 @@ void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { // normal interface method resolution - resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); + resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK); assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/interpreter/linkResolver.hpp --- a/src/share/vm/interpreter/linkResolver.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/interpreter/linkResolver.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -124,7 +124,7 @@ friend class klassItable; private: - static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); + static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS); static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_polymorphic_method (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, @@ -134,7 +134,7 @@ static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); - static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS); static void resolve_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS); static void linktime_resolve_static_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/interpreter/rewriter.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -70,12 +70,14 @@ } // Unrewrite the bytecodes if an error occurs. -void Rewriter::restore_bytecodes(TRAPS) { +void Rewriter::restore_bytecodes() { int len = _methods->length(); + bool invokespecial_error = false; for (int i = len-1; i >= 0; i--) { Method* method = _methods->at(i); - scan_method(method, true, CHECK); + scan_method(method, true, &invokespecial_error); + assert(!invokespecial_error, "reversing should not get an invokespecial error"); } } @@ -160,22 +162,21 @@ // These cannot share cpCache entries. It's unclear if all invokespecial to // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry // is created for each one. This was added with lambda. -void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS) { - static int count = 0; +void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) { address p = bcp + offset; if (!reverse) { int cp_index = Bytes::get_Java_u2(p); + if (_pool->tag_at(cp_index).is_interface_method()) { int cache_index = add_invokespecial_cp_cache_entry(cp_index); if (cache_index != (int)(jushort) cache_index) { - THROW_MSG(vmSymbols::java_lang_InternalError(), - "This classfile overflows invokespecial for interfaces " - "and cannot be loaded"); + *invokespecial_error = true; } Bytes::put_native_u2(p, cache_index); } else { - int cache_index = Bytes::get_native_u2(p); - int cp_index = cp_cache_entry_pool_index(cache_index); - Bytes::put_Java_u2(p, cp_index); + rewrite_member_reference(bcp, offset, reverse); + } + } else { + rewrite_member_reference(bcp, offset, reverse); } } @@ -329,7 +330,7 @@ // Rewrites a method given the index_map information -void Rewriter::scan_method(Method* method, bool reverse, TRAPS) { +void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_error) { int nof_jsrs = 0; bool has_monitor_bytecodes = false; @@ -391,15 +392,7 @@ } case Bytecodes::_invokespecial : { - int offset = prefix_length + 1; - address p = bcp + offset; - int cp_index = Bytes::get_Java_u2(p); - // InterfaceMethodref - if (_pool->tag_at(cp_index).is_interface_method()) { - rewrite_invokespecial(bcp, offset, reverse, CHECK); - } else { - rewrite_member_reference(bcp, offset, reverse); - } + rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error); break; } @@ -496,11 +489,20 @@ // rewrite methods, in two passes int len = _methods->length(); + bool invokespecial_error = false; for (int i = len-1; i >= 0; i--) { Method* method = _methods->at(i); - scan_method(method, false, CHECK); // If you get an error here, - // there is no reversing bytecodes + scan_method(method, false, &invokespecial_error); + if (invokespecial_error) { + // If you get an error here, there is no reversing bytecodes + // This exception is stored for this class and no further attempt is + // made at verifying or rewriting. + THROW_MSG(vmSymbols::java_lang_InternalError(), + "This classfile overflows invokespecial for interfaces " + "and cannot be loaded"); + return; + } } // May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref @@ -513,7 +515,7 @@ // Restore bytecodes to their unrewritten state if there are exceptions // rewriting bytecodes or allocating the cpCache if (HAS_PENDING_EXCEPTION) { - restore_bytecodes(CATCH); + restore_bytecodes(); return; } @@ -530,7 +532,7 @@ // relocating bytecodes. If some are relocated, that is ok because that // doesn't affect constant pool to cpCache rewriting. if (HAS_PENDING_EXCEPTION) { - restore_bytecodes(CATCH); + restore_bytecodes(); return; } // Method might have gotten rewritten. diff -r f76593e3fedb -r 163b418ec095 src/share/vm/interpreter/rewriter.hpp --- a/src/share/vm/interpreter/rewriter.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/interpreter/rewriter.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -189,18 +189,18 @@ void compute_index_maps(); void make_constant_pool_cache(TRAPS); - void scan_method(Method* m, bool reverse, TRAPS); + void scan_method(Method* m, bool reverse, bool* invokespecial_error); void rewrite_Object_init(methodHandle m, TRAPS); void rewrite_member_reference(address bcp, int offset, bool reverse); void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse); void rewrite_invokedynamic(address bcp, int offset, bool reverse); void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse); - void rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS); + void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error); void patch_invokedynamic_bytecodes(); // Revert bytecodes in case of an exception. - void restore_bytecodes(TRAPS); + void restore_bytecodes(); static methodHandle rewrite_jsrs(methodHandle m, TRAPS); public: diff -r f76593e3fedb -r 163b418ec095 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/memory/defNewGeneration.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -562,7 +562,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); DefNewTracer gc_tracer; gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); @@ -709,7 +709,7 @@ gch->trace_heap_after_gc(&gc_tracer); gc_tracer.report_tenuring_threshold(tenuring_threshold()); - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/memory/generation.cpp --- a/src/share/vm/memory/generation.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/memory/generation.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -635,16 +635,16 @@ x(ref_processor(), gch->reserved_region()); STWGCTimer* gc_timer = GenMarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); - gc_tracer->report_gc_end(os::elapsed_counter(), gc_timer->time_partitions()); + gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); SpecializationStats::print(); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/memory/metaspace.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -287,7 +287,7 @@ VirtualSpace* virtual_space() const { return (VirtualSpace*) &_virtual_space; } // Returns true if "word_size" is available in the VirtualSpace - bool is_available(size_t word_size) { return _top + word_size <= end(); } + bool is_available(size_t word_size) { return word_size <= pointer_delta(end(), _top, sizeof(MetaWord)); } MetaWord* top() const { return _top; } void inc_top(size_t word_size) { _top += word_size; } @@ -3641,10 +3641,82 @@ } } + +#define assert_is_available_positive(word_size) \ + assert(vsn.is_available(word_size), \ + err_msg(#word_size ": " PTR_FORMAT " bytes were not available in " \ + "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \ + (uintptr_t)(word_size * BytesPerWord), vsn.bottom(), vsn.end())); + +#define assert_is_available_negative(word_size) \ + assert(!vsn.is_available(word_size), \ + err_msg(#word_size ": " PTR_FORMAT " bytes should not be available in " \ + "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \ + (uintptr_t)(word_size * BytesPerWord), vsn.bottom(), vsn.end())); + + static void test_is_available_positive() { + // Reserve some memory. + VirtualSpaceNode vsn(os::vm_allocation_granularity()); + assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); + + // Commit some memory. + size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; + bool expanded = vsn.expand_by(commit_word_size, commit_word_size); + assert(expanded, "Failed to commit"); + + // Check that is_available accepts the committed size. + assert_is_available_positive(commit_word_size); + + // Check that is_available accepts half the committed size. + size_t expand_word_size = commit_word_size / 2; + assert_is_available_positive(expand_word_size); + } + + static void test_is_available_negative() { + // Reserve some memory. + VirtualSpaceNode vsn(os::vm_allocation_granularity()); + assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); + + // Commit some memory. + size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; + bool expanded = vsn.expand_by(commit_word_size, commit_word_size); + assert(expanded, "Failed to commit"); + + // Check that is_available doesn't accept a too large size. + size_t two_times_commit_word_size = commit_word_size * 2; + assert_is_available_negative(two_times_commit_word_size); + } + + static void test_is_available_overflow() { + // Reserve some memory. + VirtualSpaceNode vsn(os::vm_allocation_granularity()); + assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); + + // Commit some memory. + size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; + bool expanded = vsn.expand_by(commit_word_size, commit_word_size); + assert(expanded, "Failed to commit"); + + // Calculate a size that will overflow the virtual space size. + void* virtual_space_max = (void*)(uintptr_t)-1; + size_t bottom_to_max = pointer_delta(virtual_space_max, vsn.bottom(), 1); + size_t overflow_size = bottom_to_max + BytesPerWord; + size_t overflow_word_size = overflow_size / BytesPerWord; + + // Check that is_available can handle the overflow. + assert_is_available_negative(overflow_word_size); + } + + static void test_is_available() { + TestVirtualSpaceNodeTest::test_is_available_positive(); + TestVirtualSpaceNodeTest::test_is_available_negative(); + TestVirtualSpaceNodeTest::test_is_available_overflow(); + } }; void TestVirtualSpaceNode_test() { TestVirtualSpaceNodeTest::test(); + TestVirtualSpaceNodeTest::test_is_available(); } #endif diff -r f76593e3fedb -r 163b418ec095 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/memory/universe.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -120,6 +120,7 @@ oop Universe::_arithmetic_exception_instance = NULL; oop Universe::_virtual_machine_error_instance = NULL; oop Universe::_vm_exception = NULL; +Method* Universe::_throw_illegal_access_error = NULL; Array* Universe::_the_empty_int_array = NULL; Array* Universe::_the_empty_short_array = NULL; Array* Universe::_the_empty_klass_array = NULL; @@ -1096,6 +1097,18 @@ Universe::_finalizer_register_cache->init( SystemDictionary::Finalizer_klass(), m); + InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->link_class(CHECK_false); + m = InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->find_method( + vmSymbols::throwIllegalAccessError_name(), + vmSymbols::void_method_signature()); + if (m != NULL && !m->is_static()) { + // Note null is okay; this method is used in itables, and if it is null, + // then AbstractMethodError is thrown instead. + tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method"); + return false; // initialization failed (cannot throw exception yet) + } + Universe::_throw_illegal_access_error = m; + // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/memory/universe.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -149,6 +149,8 @@ static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes + static Method* _throw_illegal_access_error; + // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_metaspace; @@ -305,6 +307,7 @@ static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; } static oop vm_exception() { return _vm_exception; } + static Method* throw_illegal_access_error() { return _throw_illegal_access_error; } static Array* the_empty_int_array() { return _the_empty_int_array; } static Array* the_empty_short_array() { return _the_empty_short_array; } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/instanceClassLoaderKlass.cpp --- a/src/share/vm/oops/instanceClassLoaderKlass.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/instanceClassLoaderKlass.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -150,10 +150,6 @@ int InstanceClassLoaderKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { InstanceKlass::oop_update_pointers(cm, obj); - ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj); - if (loader_data != NULL) { - PSParallelCompact::adjust_class_loader(cm, loader_data); - } return size_helper(); } #endif // INCLUDE_ALL_GCS diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -1051,6 +1051,18 @@ return false; } +bool InstanceKlass::is_same_or_direct_interface(Klass *k) const { + // Verify direct super interface + if (this == k) return true; + assert(k->is_interface(), "should be an interface class"); + for (int i = 0; i < local_interfaces()->length(); i++) { + if (local_interfaces()->at(i) == k) { + return true; + } + } + return false; +} + objArrayOop InstanceKlass::allocate_objArray(int n, int length, TRAPS) { if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); if (length > arrayOopDesc::max_array_length(T_OBJECT)) { @@ -1415,6 +1427,17 @@ return InstanceKlass::find_method(methods(), name, signature); } +// find_instance_method looks up the name/signature in the local methods array +// and skips over static methods +Method* InstanceKlass::find_instance_method( + Array* methods, Symbol* name, Symbol* signature) { + Method* meth = InstanceKlass::find_method(methods, name, signature); + if (meth != NULL && meth->is_static()) { + meth = NULL; + } + return meth; +} + // find_method looks up the name/signature in the local methods array Method* InstanceKlass::find_method( Array* methods, Symbol* name, Symbol* signature) { @@ -2157,7 +2180,6 @@ obj, \ MarkSweep::adjust_pointer(p), \ assert_is_in) - MarkSweep::adjust_klass(obj->klass()); return size; } @@ -2177,7 +2199,6 @@ obj, \ PSParallelCompact::adjust_pointer(p), \ assert_is_in) - obj->update_header(cm); return size; } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -515,6 +515,7 @@ // find a local method (returns NULL if not found) Method* find_method(Symbol* name, Symbol* signature) const; static Method* find_method(Array* methods, Symbol* name, Symbol* signature); + static Method* find_instance_method(Array* methods, Symbol* name, Symbol* signature); // find a local method index in default_methods (returns -1 if not found) static int find_method_index(Array* methods, Symbol* name, Symbol* signature); @@ -777,6 +778,7 @@ // subclass/subinterface checks bool implements_interface(Klass* k) const; + bool is_same_or_direct_interface(Klass* k) const; // Access to the implementor of an interface. Klass* implementor() const diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/instanceMirrorKlass.cpp --- a/src/share/vm/oops/instanceMirrorKlass.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/instanceMirrorKlass.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -155,7 +155,18 @@ // Follow the klass field in the mirror. Klass* klass = java_lang_Class::as_Klass(obj); if (klass != NULL) { - MarkSweep::follow_klass(klass); + // An anonymous class doesn't have its own class loader, so the call + // to follow_klass will mark and push its java mirror instead of the + // class loader. When handling the java mirror for an anonymous class + // we need to make sure its class loader data is claimed, this is done + // by calling follow_class_loader explicitly. For non-anonymous classes + // the call to follow_class_loader is made when the class loader itself + // is handled. + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { + MarkSweep::follow_class_loader(klass->class_loader_data()); + } else { + MarkSweep::follow_klass(klass); + } } else { // If klass is NULL then this a mirror for a primitive type. // We don't have to follow them, since they are handled as strong @@ -177,7 +188,18 @@ // Follow the klass field in the mirror. Klass* klass = java_lang_Class::as_Klass(obj); if (klass != NULL) { - PSParallelCompact::follow_klass(cm, klass); + // An anonymous class doesn't have its own class loader, so the call + // to follow_klass will mark and push its java mirror instead of the + // class loader. When handling the java mirror for an anonymous class + // we need to make sure its class loader data is claimed, this is done + // by calling follow_class_loader explicitly. For non-anonymous classes + // the call to follow_class_loader is made when the class loader itself + // is handled. + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { + PSParallelCompact::follow_class_loader(cm, klass->class_loader_data()); + } else { + PSParallelCompact::follow_klass(cm, klass); + } } else { // If klass is NULL then this a mirror for a primitive type. // We don't have to follow them, since they are handled as strong @@ -196,17 +218,6 @@ int size = oop_size(obj); InstanceKlass::oop_adjust_pointers(obj); - // Follow the klass field in the mirror. - Klass* klass = java_lang_Class::as_Klass(obj); - if (klass != NULL) { - MarkSweep::adjust_klass(klass); - } else { - // If klass is NULL then this a mirror for a primitive type. - // We don't have to follow them, since they are handled as strong - // roots in Universe::oops_do. - assert(java_lang_Class::is_primitive(obj), "Sanity check"); - } - InstanceMirrorKlass_OOP_ITERATE( \ start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ MarkSweep::adjust_pointer(p), \ @@ -337,17 +348,6 @@ int size = oop_size(obj); InstanceKlass::oop_update_pointers(cm, obj); - // Follow the klass field in the mirror. - Klass* klass = java_lang_Class::as_Klass(obj); - if (klass != NULL) { - PSParallelCompact::adjust_klass(cm, klass); - } else { - // If klass is NULL then this a mirror for a primitive type. - // We don't have to follow them, since they are handled as strong - // roots in Universe::oops_do. - assert(java_lang_Class::is_primitive(obj), "Sanity check"); - } - InstanceMirrorKlass_OOP_ITERATE( \ start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ PSParallelCompact::adjust_pointer(p), \ diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/klassVtable.cpp --- a/src/share/vm/oops/klassVtable.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/klassVtable.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -665,6 +665,11 @@ // check if a method is a miranda method, given a class's methods table, // its default_method table and its super +// Miranda methods are calculated twice: +// first: before vtable size calculation: including abstract and default +// This is seen by default method creation +// Second: recalculated during vtable initialization: only abstract +// This is seen by link resolution and selection. // "miranda" means not static, not defined by this class. // private methods in interfaces do not belong in the miranda list. // the caller must make sure that the method belongs to an interface implemented by the class @@ -678,7 +683,8 @@ } Symbol* name = m->name(); Symbol* signature = m->signature(); - if (InstanceKlass::find_method(class_methods, name, signature) == NULL) { + + if (InstanceKlass::find_instance_method(class_methods, name, signature) == NULL) { // did not find it in the method table of the current class if ((default_methods == NULL) || InstanceKlass::find_method(default_methods, name, signature) == NULL) { @@ -688,6 +694,12 @@ } Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature); + while (mo != NULL && mo->access_flags().is_static() + && mo->method_holder() != NULL + && mo->method_holder()->super() != NULL) + { + mo = mo->method_holder()->super()->uncached_lookup_method(name, signature); + } if (mo == NULL || mo->access_flags().is_private() ) { // super class hierarchy does not implement it or protection is different return true; @@ -1076,7 +1088,12 @@ LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK); } if (target == NULL || !target->is_public() || target->is_abstract()) { - // Entry do not resolve. Leave it empty + // Entry does not resolve. Leave it empty for AbstractMethodError. + if (!(target == NULL) && !target->is_public()) { + // Stuff an IllegalAccessError throwing method in there instead. + itableOffsetEntry::method_entry(_klass(), method_table_offset)[m->itable_index()]. + initialize(Universe::throw_illegal_access_error()); + } } else { // Entry did resolve, check loader constraints before initializing // if checkconstraints requested diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/objArrayKlass.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -569,7 +569,6 @@ // Get size before changing pointers. // Don't call size() or oop_size() since that is a virtual call. int size = a->object_size(); - MarkSweep::adjust_klass(a->klass()); ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) return size; } @@ -588,7 +587,6 @@ assert (obj->is_objArray(), "obj must be obj array"); objArrayOop a = objArrayOop(obj); int size = a->object_size(); - a->update_header(cm); ObjArrayKlass_OOP_ITERATE(a, p, PSParallelCompact::adjust_pointer(p)) return size; } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/oop.hpp --- a/src/share/vm/oops/oop.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/oop.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -328,11 +328,6 @@ // return the size of this oop. This is used by the MarkSweep collector. int adjust_pointers(); -#if INCLUDE_ALL_GCS - // Parallel old - void update_header(ParCompactionManager* cm); -#endif // INCLUDE_ALL_GCS - // mark-sweep support void follow_body(int begin, int end); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/oops/oop.pcgc.inline.hpp --- a/src/share/vm/oops/oop.pcgc.inline.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/oops/oop.pcgc.inline.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -80,8 +80,4 @@ return forwardee(); } -inline void oopDesc::update_header(ParCompactionManager* cm) { - PSParallelCompact::adjust_klass(cm, klass()); -} - #endif // SHARE_VM_OOPS_OOP_PCGC_INLINE_HPP diff -r f76593e3fedb -r 163b418ec095 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/opto/c2_globals.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -637,7 +637,7 @@ diagnostic(bool, OptimizeExpensiveOps, true, \ "Find best control for expensive operations") \ \ - product(bool, UseMathExactIntrinsics, true, \ + experimental(bool, UseMathExactIntrinsics, false, \ "Enables intrinsification of various java.lang.Math functions") \ \ experimental(bool, ReplaceInParentMaps, false, \ diff -r f76593e3fedb -r 163b418ec095 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/opto/compile.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -42,6 +42,7 @@ #include "runtime/deoptimization.hpp" #include "runtime/vmThread.hpp" #include "trace/tracing.hpp" +#include "utilities/ticks.hpp" class Block; class Bundle; @@ -597,20 +598,19 @@ bool has_method_handle_invokes() const { return _has_method_handle_invokes; } void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } - jlong _latest_stage_start_counter; + Ticks _latest_stage_start_counter; void begin_method() { #ifndef PRODUCT if (_printer) _printer->begin_method(this); #endif - C->_latest_stage_start_counter = os::elapsed_counter(); + C->_latest_stage_start_counter.stamp(); } void print_method(CompilerPhaseType cpt, int level = 1) { - EventCompilerPhase event(UNTIMED); + EventCompilerPhase event; if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); - event.set_endtime(os::elapsed_counter()); event.set_phase((u1) cpt); event.set_compileID(C->_compile_id); event.set_phaseLevel(level); @@ -621,14 +621,13 @@ #ifndef PRODUCT if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level); #endif - C->_latest_stage_start_counter = os::elapsed_counter(); + C->_latest_stage_start_counter.stamp(); } void end_method(int level = 1) { - EventCompilerPhase event(UNTIMED); + EventCompilerPhase event; if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); - event.set_endtime(os::elapsed_counter()); event.set_phase((u1) PHASE_END); event.set_compileID(C->_compile_id); event.set_phaseLevel(level); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/opto/memnode.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -2071,6 +2071,11 @@ if (t != NULL) { // constant oop => constant klass if (offset == java_lang_Class::array_klass_offset_in_bytes()) { + if (t->is_void()) { + // We cannot create a void array. Since void is a primitive type return null + // klass. Users of this result need to do a null check on the returned klass. + return TypePtr::NULL_PTR; + } return TypeKlassPtr::make(ciArrayKlass::make(t)); } if (!t->is_klass()) { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/prims/jvmtiEnvThreadState.cpp --- a/src/share/vm/prims/jvmtiEnvThreadState.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/prims/jvmtiEnvThreadState.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -269,11 +269,20 @@ void doit() { ResourceMark rmark; // _thread != Thread::current() RegisterMap rm(_thread, false); - javaVFrame* vf = _thread->last_java_vframe(&rm); - assert(vf != NULL, "must have last java frame"); - Method* method = vf->method(); - _method_id = method->jmethod_id(); - _bci = vf->bci(); + // There can be a race condition between a VM_Operation reaching a safepoint + // and the target thread exiting from Java execution. + // We must recheck the last Java frame still exists. + if (_thread->has_last_Java_frame()) { + javaVFrame* vf = _thread->last_java_vframe(&rm); + assert(vf != NULL, "must have last java frame"); + Method* method = vf->method(); + _method_id = method->jmethod_id(); + _bci = vf->bci(); + } else { + // Clear current location as the target thread has no Java frames anymore. + _method_id = (jmethodID)NULL; + _bci = 0; + } } void get_current_location(jmethodID *method_id, int *bci) { *method_id = _method_id; diff -r f76593e3fedb -r 163b418ec095 src/share/vm/prims/jvmtiImpl.hpp --- a/src/share/vm/prims/jvmtiImpl.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/prims/jvmtiImpl.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -299,7 +299,7 @@ static inline bool is_breakpoint(address bcp); static void oops_do(OopClosure* f); - static void metadata_do(void f(Metadata*)); + static void metadata_do(void f(Metadata*)) NOT_JVMTI_RETURN; static void gc_epilogue(); }; diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/arguments.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -2297,18 +2297,6 @@ status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio"); status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount"); -#ifdef SPARC - if (UseConcMarkSweepGC || UseG1GC) { - // Issue a stern warning if the user has explicitly set - // UseMemSetInBOT (it is known to cause issues), but allow - // use for experimentation and debugging. - if (VM_Version::is_sun4v() && UseMemSetInBOT) { - assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); - warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" - " on sun4v; please understand that you are using at your own risk!"); - } - } -#endif // SPARC if (PrintNMTStatistics) { #if INCLUDE_NMT diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/globals.cpp --- a/src/share/vm/runtime/globals.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/globals.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -325,6 +325,8 @@ { KIND_PRODUCT, "product" }, { KIND_MANAGEABLE, "manageable" }, { KIND_DIAGNOSTIC, "diagnostic" }, + { KIND_EXPERIMENTAL, "experimental" }, + { KIND_COMMERCIAL, "commercial" }, { KIND_NOT_PRODUCT, "notproduct" }, { KIND_DEVELOP, "develop" }, { KIND_LP64_PRODUCT, "lp64_product" }, diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/globals.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -3646,9 +3646,6 @@ "Temporary flag for transition to AbstractMethodError wrapped " \ "in InvocationTargetException. See 6531596") \ \ - develop(bool, VerifyLambdaBytecodes, false, \ - "Force verification of jdk 8 lambda metafactory bytecodes") \ - \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ \ diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/reflection.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -470,12 +470,6 @@ return true; } - // Also allow all accesses from - // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. - if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { - return true; - } - return can_relax_access_check_for(current_class, new_class, classloader_only); } @@ -543,15 +537,26 @@ return true; } + Klass* host_class = current_class; + while (host_class->oop_is_instance() && + InstanceKlass::cast(host_class)->is_anonymous()) { + Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass(); + if (next_host_class == NULL) break; + host_class = next_host_class; + } + if (host_class == field_class) { + return true; + } + if (access.is_protected()) { if (!protected_restriction) { - // See if current_class is a subclass of field_class - if (current_class->is_subclass_of(field_class)) { + // See if current_class (or outermost host class) is a subclass of field_class + if (host_class->is_subclass_of(field_class)) { if (access.is_static() || // static fields are ok, see 6622385 current_class == resolved_class || field_class == resolved_class || - current_class->is_subclass_of(resolved_class) || - resolved_class->is_subclass_of(current_class)) { + host_class->is_subclass_of(resolved_class) || + resolved_class->is_subclass_of(host_class)) { return true; } } @@ -570,12 +575,6 @@ return true; } - // Also allow all accesses from - // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. - if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { - return true; - } - return can_relax_access_check_for( current_class, field_class, classloader_only); } diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -84,6 +84,7 @@ // Shared stub locations RuntimeStub* SharedRuntime::_wrong_method_blob; +RuntimeStub* SharedRuntime::_wrong_method_abstract_blob; RuntimeStub* SharedRuntime::_ic_miss_blob; RuntimeStub* SharedRuntime::_resolve_opt_virtual_call_blob; RuntimeStub* SharedRuntime::_resolve_virtual_call_blob; @@ -101,11 +102,12 @@ //----------------------------generate_stubs----------------------------------- void SharedRuntime::generate_stubs() { - _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method), "wrong_method_stub"); - _ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss), "ic_miss_stub"); - _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C), "resolve_opt_virtual_call"); - _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), "resolve_virtual_call"); - _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call"); + _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method), "wrong_method_stub"); + _wrong_method_abstract_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_abstract), "wrong_method_abstract_stub"); + _ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss), "ic_miss_stub"); + _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C), "resolve_opt_virtual_call"); + _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), "resolve_virtual_call"); + _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call"); #ifdef COMPILER2 // Vectors are generated only by C2. @@ -1238,12 +1240,12 @@ CodeBlob* caller_cb = caller_frame.cb(); guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); nmethod* caller_nm = caller_cb->as_nmethod_or_null(); + // make sure caller is not getting deoptimized // and removed before we are done with it. // CLEANUP - with lazy deopt shouldn't need this lock nmethodLocker caller_lock(caller_nm); - // determine call info & receiver // note: a) receiver is NULL for static calls // b) an exception is thrown if receiver is NULL for non-static calls @@ -1258,6 +1260,11 @@ (!is_virtual && invoke_code == Bytecodes::_invokedynamic) || ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode"); + // We do not patch the call site if the caller nmethod has been made non-entrant. + if (!caller_nm->is_in_use()) { + return callee_method; + } + #ifndef PRODUCT // tracing/debugging/statistics int *addr = (is_optimized) ? (&_resolve_opt_virtual_ctr) : @@ -1297,6 +1304,10 @@ // Make sure the callee nmethod does not get deoptimized and removed before // we are done patching the code. nmethod* callee_nm = callee_method->code(); + if (callee_nm != NULL && !callee_nm->is_in_use()) { + // Patch call site to C2I adapter if callee nmethod is deoptimized or unloaded. + callee_nm = NULL; + } nmethodLocker nl_callee(callee_nm); #ifdef ASSERT address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below @@ -1318,15 +1329,24 @@ { MutexLocker ml_patch(CompiledIC_lock); + // Lock blocks for safepoint during which both nmethods can change state. + // Now that we are ready to patch if the Method* was redefined then // don't update call site and let the caller retry. - - if (!callee_method->is_old()) { + // Don't update call site if caller nmethod has been made non-entrant + // as it is a waste of time. + // Don't update call site if callee nmethod was unloaded or deoptimized. + // Don't update call site if callee nmethod was replaced by an other nmethod + // which may happen when multiply alive nmethod (tiered compilation) + // will be supported. + if (!callee_method->is_old() && caller_nm->is_in_use() && + (callee_nm == NULL || callee_nm->is_in_use() && (callee_method->code() == callee_nm))) { #ifdef ASSERT // We must not try to patch to jump to an already unloaded method. if (dest_entry_point != 0) { - assert(CodeCache::find_blob(dest_entry_point) != NULL, - "should not unload nmethod while locked"); + CodeBlob* cb = CodeCache::find_blob(dest_entry_point); + assert((cb != NULL) && cb->is_nmethod() && (((nmethod*)cb) == callee_nm), + "should not call unloaded nmethod"); } #endif if (is_virtual) { @@ -1407,6 +1427,11 @@ return callee_method->verified_code_entry(); JRT_END +// Handle abstract method call +JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method_abstract(JavaThread* thread)) + return StubRoutines::throw_AbstractMethodError_entry(); +JRT_END + // resolve a static call and patch code JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread *thread )) @@ -2403,12 +2428,13 @@ // Create a special handler for abstract methods. Abstract methods // are never compiled so an i2c entry is somewhat meaningless, but - // fill it in with something appropriate just in case. Pass handle - // wrong method for the c2i transitions. - address wrong_method = SharedRuntime::get_handle_wrong_method_stub(); + // throw AbstractMethodError just in case. + // Pass wrong_method_abstract for the c2i transitions to return + // AbstractMethodError for invalid invocations. + address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub(); _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL), StubRoutines::throw_AbstractMethodError_entry(), - wrong_method, wrong_method); + wrong_method_abstract, wrong_method_abstract); } AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint, diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/sharedRuntime.hpp --- a/src/share/vm/runtime/sharedRuntime.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/sharedRuntime.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -56,6 +56,7 @@ // Shared stub locations static RuntimeStub* _wrong_method_blob; + static RuntimeStub* _wrong_method_abstract_blob; static RuntimeStub* _ic_miss_blob; static RuntimeStub* _resolve_opt_virtual_call_blob; static RuntimeStub* _resolve_virtual_call_blob; @@ -210,6 +211,11 @@ return _wrong_method_blob->entry_point(); } + static address get_handle_wrong_method_abstract_stub() { + assert(_wrong_method_abstract_blob!= NULL, "oops"); + return _wrong_method_abstract_blob->entry_point(); + } + #ifdef COMPILER2 static void generate_uncommon_trap_blob(void); static UncommonTrapBlob* uncommon_trap_blob() { return _uncommon_trap_blob; } @@ -485,6 +491,7 @@ // handle ic miss with caller being compiled code // wrong method handling (inline cache misses, zombie methods) static address handle_wrong_method(JavaThread* thread); + static address handle_wrong_method_abstract(JavaThread* thread); static address handle_wrong_method_ic_miss(JavaThread* thread); #ifndef PRODUCT diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/sweeper.cpp --- a/src/share/vm/runtime/sweeper.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/sweeper.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -38,6 +38,7 @@ #include "runtime/vm_operations.hpp" #include "trace/tracing.hpp" #include "utilities/events.hpp" +#include "utilities/ticks.inline.hpp" #include "utilities/xmlstream.hpp" #ifdef ASSERT @@ -144,10 +145,10 @@ // 3) zombie -> marked_for_reclamation int NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed -jlong NMethodSweeper::_total_time_sweeping = 0; // Accumulated time sweeping -jlong NMethodSweeper::_total_time_this_sweep = 0; // Total time this sweep -jlong NMethodSweeper::_peak_sweep_time = 0; // Peak time for a full sweep -jlong NMethodSweeper::_peak_sweep_fraction_time = 0; // Peak time sweeping one fraction +Tickspan NMethodSweeper::_total_time_sweeping; // Accumulated time sweeping +Tickspan NMethodSweeper::_total_time_this_sweep; // Total time this sweep +Tickspan NMethodSweeper::_peak_sweep_time; // Peak time for a full sweep +Tickspan NMethodSweeper::_peak_sweep_fraction_time; // Peak time sweeping one fraction int NMethodSweeper::_hotness_counter_reset_val = 0; @@ -209,7 +210,7 @@ _sweep_fractions_left = NmethodSweepFraction; _current = CodeCache::first_nmethod(); _traversals += 1; - _total_time_this_sweep = 0; + _total_time_this_sweep = Tickspan(); if (PrintMethodFlushing) { tty->print_cr("### Sweep: stack traversal %d", _traversals); @@ -231,7 +232,8 @@ */ void NMethodSweeper::possibly_sweep() { assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); - if (!MethodFlushing || !sweep_in_progress()) { + // Only compiler threads are allowed to sweep + if (!MethodFlushing || !sweep_in_progress() || !Thread::current()->is_Compiler_thread()) { return; } @@ -302,7 +304,7 @@ } void NMethodSweeper::sweep_code_cache() { - jlong sweep_start_counter = os::elapsed_counter(); + Ticks sweep_start_counter = Ticks::now(); _flushed_count = 0; _zombified_count = 0; @@ -366,8 +368,8 @@ assert(_sweep_fractions_left > 1 || _current == NULL, "must have scanned the whole cache"); - jlong sweep_end_counter = os::elapsed_counter(); - jlong sweep_time = sweep_end_counter - sweep_start_counter; + const Ticks sweep_end_counter = Ticks::now(); + const Tickspan sweep_time = sweep_end_counter - sweep_start_counter; _total_time_sweeping += sweep_time; _total_time_this_sweep += sweep_time; _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time); @@ -388,7 +390,8 @@ #ifdef ASSERT if(PrintMethodFlushing) { - tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time); + tty->print_cr("### sweeper: sweep time(%d): " + INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value()); } #endif diff -r f76593e3fedb -r 163b418ec095 src/share/vm/runtime/sweeper.hpp --- a/src/share/vm/runtime/sweeper.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/runtime/sweeper.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_RUNTIME_SWEEPER_HPP #define SHARE_VM_RUNTIME_SWEEPER_HPP +#include "utilities/ticks.hpp" // An NmethodSweeper is an incremental cleaner for: // - cleanup inline caches // - reclamation of nmethods @@ -71,10 +72,10 @@ // 3) zombie -> marked_for_reclamation // Stat counters static int _total_nof_methods_reclaimed; // Accumulated nof methods flushed - static jlong _total_time_sweeping; // Accumulated time sweeping - static jlong _total_time_this_sweep; // Total time this sweep - static jlong _peak_sweep_time; // Peak time for a full sweep - static jlong _peak_sweep_fraction_time; // Peak time sweeping one fraction + static Tickspan _total_time_sweeping; // Accumulated time sweeping + static Tickspan _total_time_this_sweep; // Total time this sweep + static Tickspan _peak_sweep_time; // Peak time for a full sweep + static Tickspan _peak_sweep_fraction_time; // Peak time sweeping one fraction static int process_nmethod(nmethod *nm); static void release_nmethod(nmethod* nm); @@ -87,9 +88,9 @@ public: static long traversal_count() { return _traversals; } static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } - static jlong total_time_sweeping() { return _total_time_sweeping; } - static jlong peak_sweep_time() { return _peak_sweep_time; } - static jlong peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } + static const Tickspan total_time_sweeping() { return _total_time_sweeping; } + static const Tickspan peak_sweep_time() { return _peak_sweep_time; } + static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } static void log_sweep(const char* msg, const char* format = NULL, ...); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/services/threadService.cpp Wed Dec 18 06:06:52 2013 -0800 @@ -200,6 +200,12 @@ } } +void ThreadService::metadata_do(void f(Metadata*)) { + for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) { + dump->metadata_do(f); + } +} + void ThreadService::add_thread_dump(ThreadDumpResult* dump) { MutexLocker ml(Management_lock); if (_threaddump_list == NULL) { @@ -451,9 +457,16 @@ } } +void ThreadDumpResult::metadata_do(void f(Metadata*)) { + for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) { + ts->metadata_do(f); + } +} + StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) { _method = jvf->method(); _bci = jvf->bci(); + _class_holder = _method->method_holder()->klass_holder(); _locked_monitors = NULL; if (with_lock_info) { ResourceMark rm; @@ -477,6 +490,11 @@ f->do_oop((oop*) _locked_monitors->adr_at(i)); } } + f->do_oop(&_class_holder); +} + +void StackFrameInfo::metadata_do(void f(Metadata*)) { + f(_method); } void StackFrameInfo::print_on(outputStream* st) const { @@ -620,6 +638,14 @@ } } +void ThreadStackTrace::metadata_do(void f(Metadata*)) { + int length = _frames->length(); + for (int i = 0; i < length; i++) { + _frames->at(i)->metadata_do(f); + } +} + + ConcurrentLocksDump::~ConcurrentLocksDump() { if (_retain_map_on_free) { return; @@ -823,6 +849,13 @@ } } +void ThreadSnapshot::metadata_do(void f(Metadata*)) { + if (_stack_trace != NULL) { + _stack_trace->metadata_do(f); + } +} + + DeadlockCycle::DeadlockCycle() { _is_deadlock = false; _threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(INITIAL_ARRAY_SIZE, true); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/services/threadService.hpp --- a/src/share/vm/services/threadService.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/services/threadService.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -113,6 +113,7 @@ // GC support static void oops_do(OopClosure* f); + static void metadata_do(void f(Metadata*)); }; // Per-thread Statistics for synchronization @@ -242,6 +243,7 @@ void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors); void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); }; class ThreadStackTrace : public CHeapObj { @@ -265,6 +267,7 @@ void dump_stack_at_safepoint(int max_depth); Handle allocate_fill_stack_trace_element_array(TRAPS); void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); GrowableArray* jni_locked_monitors() { return _jni_locked_monitors; } int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); } @@ -280,6 +283,9 @@ Method* _method; int _bci; GrowableArray* _locked_monitors; // list of object monitors locked by this frame + // We need to save the mirrors in the backtrace to keep the class + // from being unloaded while we still have this stack trace. + oop _class_holder; public: @@ -289,9 +295,10 @@ delete _locked_monitors; } }; - Method* method() const { return _method; } + Method* method() const { return _method; } int bci() const { return _bci; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); } GrowableArray* locked_monitors() { return _locked_monitors; } @@ -354,6 +361,7 @@ int num_snapshots() { return _num_snapshots; } ThreadSnapshot* snapshots() { return _snapshots; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); }; class DeadlockCycle : public CHeapObj { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/noTraceBackend.hpp --- a/src/share/vm/trace/noTraceBackend.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/noTraceBackend.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -25,9 +25,7 @@ #define SHARE_VM_TRACE_NOTRACEBACKEND_HPP #include "prims/jni.h" - -typedef jlong TracingTime; -typedef jlong RelativeTracingTime; +#include "trace/traceTime.hpp" class NoTraceBackend { public: @@ -44,5 +42,3 @@ typedef NoTraceBackend Tracing; #endif - - diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/trace.xml --- a/src/share/vm/trace/trace.xml Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/trace.xml Wed Dec 18 06:06:52 2013 -0800 @@ -176,8 +176,8 @@ - - + + class TraceEvent : public StackObj { - protected: - jlong _startTime; - jlong _endTime; - private: bool _started; #ifdef ASSERT @@ -54,6 +51,18 @@ bool _ignore_check; #endif + protected: + jlong _startTime; + jlong _endTime; + + void set_starttime(const TracingTime& time) { + _startTime = time; + } + + void set_endtime(const TracingTime& time) { + _endTime = time; + } + public: TraceEvent(EventStartTime timing=TIMED) : _startTime(0), @@ -100,12 +109,12 @@ set_commited(); } - void set_starttime(jlong time) { - _startTime = time; + void set_starttime(const Ticks& time) { + _startTime = time.value(); } - void set_endtime(jlong time) { - _endTime = time; + void set_endtime(const Ticks& time) { + _endTime = time.value(); } TraceEventId id() const { diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/traceEventClasses.xsl --- a/src/share/vm/trace/traceEventClasses.xsl Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/traceEventClasses.xsl Wed Dec 18 06:06:52 2013 -0800 @@ -40,6 +40,7 @@ #include "tracefiles/traceTypes.hpp" #include "trace/traceEvent.hpp" #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_TRACE @@ -55,8 +56,8 @@ class TraceEvent { public: TraceEvent() {} - void set_starttime(jlong time) const {} - void set_endtime(jlong time) const {} + void set_starttime(const Ticks& time) {} + void set_endtime(const Ticks& time) {} bool should_commit() const { return false; } void commit() const {} }; @@ -170,23 +171,23 @@ - #if INCLUDE_TRACE - + #else - + #endif - + #if INCLUDE_TRACE - + #else - + #endif + @@ -226,7 +227,17 @@ - + + + + + + + + + + + ts.print(", "); diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/traceTime.hpp --- a/src/share/vm/trace/traceTime.hpp Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/traceTime.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -28,6 +28,5 @@ #include "prims/jni.h" typedef jlong TracingTime; -typedef jlong RelativeTracingTime; -#endif +#endif // SHARE_VM_TRACE_TRACETIME_HPP diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/traceTypes.xsl --- a/src/share/vm/trace/traceTypes.xsl Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/traceTypes.xsl Wed Dec 18 06:06:52 2013 -0800 @@ -32,9 +32,11 @@ #ifndef TRACEFILES_JFRTYPES_HPP #define TRACEFILES_JFRTYPES_HPP +#include "oops/symbol.hpp" #include "trace/traceDataTypes.hpp" #include "utilities/globalDefinitions.hpp" -#include "oops/symbol.hpp" +#include "utilities/ticks.hpp" + enum JVMContentType { _not_a_content_type = (JVM_CONTENT_TYPES_START - 1), diff -r f76593e3fedb -r 163b418ec095 src/share/vm/trace/tracetypes.xml --- a/src/share/vm/trace/tracetypes.xml Wed Dec 18 03:16:17 2013 -0800 +++ b/src/share/vm/trace/tracetypes.xml Wed Dec 18 06:06:52 2013 -0800 @@ -249,13 +249,13 @@ - + + type="Ticks" sizeop="sizeof(s8)"/> - - + + = start, "negative time!"); + + _span_ticks = end.value() - start.value(); +} + +template +static ReturnType time_conversion(const Tickspan& span, TicksToTimeHelper::Unit unit) { + assert(TicksToTimeHelper::SECONDS == unit || + TicksToTimeHelper::MILLISECONDS == unit, "invalid unit!"); + + ReturnType frequency_per_unit = (ReturnType)os::elapsed_frequency() / (ReturnType)unit; + + return (ReturnType) ((ReturnType)span.value() / frequency_per_unit); +} + +double TicksToTimeHelper::seconds(const Tickspan& span) { + return time_conversion(span, SECONDS); +} + +jlong TicksToTimeHelper::milliseconds(const Tickspan& span) { + return time_conversion(span, MILLISECONDS); +} diff -r f76593e3fedb -r 163b418ec095 src/share/vm/utilities/ticks.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/ticks.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TICKS_HPP +#define SHARE_VM_UTILITIES_TICKS_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +class Ticks; + +class Tickspan VALUE_OBJ_CLASS_SPEC { + friend class Ticks; + friend Tickspan operator-(const Ticks& end, const Ticks& start); + + private: + jlong _span_ticks; + + Tickspan(const Ticks& end, const Ticks& start); + + public: + Tickspan() : _span_ticks(0) {} + + Tickspan& operator+=(const Tickspan& rhs) { + _span_ticks += rhs._span_ticks; + return *this; + } + + jlong value() const { + return _span_ticks; + } + +}; + +class Ticks VALUE_OBJ_CLASS_SPEC { + private: + jlong _stamp_ticks; + + public: + Ticks() : _stamp_ticks(0) { + assert((_stamp_ticks = invalid_time_stamp) == invalid_time_stamp, + "initial unstamped time value assignment"); + } + + Ticks& operator+=(const Tickspan& span) { + _stamp_ticks += span.value(); + return *this; + } + + Ticks& operator-=(const Tickspan& span) { + _stamp_ticks -= span.value(); + return *this; + } + + void stamp(); + + jlong value() const { + return _stamp_ticks; + } + + static const Ticks now(); + +#ifdef ASSERT + static const jlong invalid_time_stamp; +#endif + +#ifndef PRODUCT + // only for internal use by GC VM tests + friend class TimePartitionPhasesIteratorTest; + friend class GCTimerTest; + + private: + // implicit type conversion + Ticks(int ticks) : _stamp_ticks(ticks) {} + +#endif // !PRODUCT + +}; + +class TicksToTimeHelper : public AllStatic { + public: + enum Unit { + SECONDS = 1, + MILLISECONDS = 1000 + }; + static double seconds(const Tickspan& span); + static jlong milliseconds(const Tickspan& span); +}; + +#endif // SHARE_VM_UTILITIES_TICKS_HPP diff -r f76593e3fedb -r 163b418ec095 src/share/vm/utilities/ticks.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/ticks.inline.hpp Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TICKS_INLINE_HPP +#define SHARE_VM_UTILITIES_TICKS_INLINE_HPP + +#include "utilities/ticks.hpp" + +inline Tickspan operator+(Tickspan lhs, const Tickspan& rhs) { + lhs += rhs; + return lhs; +} + +inline bool operator==(const Tickspan& lhs, const Tickspan& rhs) { + return lhs.value() == rhs.value(); +} + +inline bool operator!=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator==(lhs,rhs); +} + +inline bool operator<(const Tickspan& lhs, const Tickspan& rhs) { + return lhs.value() < rhs.value(); +} + +inline bool operator>(const Tickspan& lhs, const Tickspan& rhs) { + return operator<(rhs,lhs); +} + +inline bool operator<=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator>(lhs,rhs); +} + +inline bool operator>=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator<(lhs,rhs); +} + +inline Ticks operator+(Ticks lhs, const Tickspan& span) { + lhs += span; + return lhs; +} + +inline Ticks operator-(Ticks lhs, const Tickspan& span) { + lhs -= span; + return lhs; +} + +inline Tickspan operator-(const Ticks& end, const Ticks& start) { + return Tickspan(end, start); +} + +inline bool operator==(const Ticks& lhs, const Ticks& rhs) { + return lhs.value() == rhs.value(); +} + +inline bool operator!=(const Ticks& lhs, const Ticks& rhs) { + return !operator==(lhs,rhs); +} + +inline bool operator<(const Ticks& lhs, const Ticks& rhs) { + return lhs.value() < rhs.value(); +} + +inline bool operator>(const Ticks& lhs, const Ticks& rhs) { + return operator<(rhs,lhs); +} + +inline bool operator<=(const Ticks& lhs, const Ticks& rhs) { + return !operator>(lhs,rhs); +} + +inline bool operator>=(const Ticks& lhs, const Ticks& rhs) { + return !operator<(lhs,rhs); +} + +#endif // SHARE_VM_UTILITIES_TICKS_INLINE_HPP diff -r f76593e3fedb -r 163b418ec095 test/TEST.groups --- a/test/TEST.groups Wed Dec 18 03:16:17 2013 -0800 +++ b/test/TEST.groups Wed Dec 18 06:06:52 2013 -0800 @@ -70,7 +70,6 @@ runtime/7107135/Test7107135.sh \ runtime/7158988/FieldMonitor.java \ runtime/7194254/Test7194254.java \ - runtime/8026365/InvokeSpecialAnonTest.java \ runtime/jsig/Test8017498.sh \ runtime/Metaspace/FragmentMetaspace.java \ runtime/NMT/BaselineWithParameter.java \ diff -r f76593e3fedb -r 163b418ec095 test/compiler/7141637/SpreadNullArg.java --- a/test/compiler/7141637/SpreadNullArg.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/7141637/SpreadNullArg.java Wed Dec 18 06:06:52 2013 -0800 @@ -46,13 +46,17 @@ mh_spread_target = MethodHandles.lookup().findStatic(SpreadNullArg.class, "target_spread_arg", mt_ref_arg); result = (int) mh_spreadInvoker.invokeExact(mh_spread_target, (Object[]) null); - } catch(NullPointerException e) { - // Expected exception - do nothing! - } catch(Throwable e) { + throw new Error("Expected IllegalArgumentException was not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("Expected exception : " + e); + } catch (Throwable e) { throw new Error(e); } - if (result != 42) throw new Error("Expected NullPointerException was not thrown"); + if (result != 42) { + throw new Error("result [" + result + + "] != 42 : Expected IllegalArgumentException was not thrown?"); + } } public static int target_spread_arg(Integer i1) { diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactICondTest.java --- a/test/compiler/intrinsics/mathexact/AddExactICondTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactICondTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @compile AddExactICondTest.java - * @run main AddExactICondTest + * @run main AddExactICondTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactIConstantTest.java --- a/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactIConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test constant addExact * @compile AddExactIConstantTest.java Verify.java - * @run main AddExactIConstantTest + * @run main AddExactIConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactILoadTest.java --- a/test/compiler/intrinsics/mathexact/AddExactILoadTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactILoadTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @compile AddExactILoadTest.java Verify.java - * @run main AddExactILoadTest + * @run main AddExactILoadTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java --- a/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactILoopDependentTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @compile AddExactILoopDependentTest.java Verify.java - * @run main AddExactILoopDependentTest + * @run main AddExactILoopDependentTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java --- a/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactINonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8024924 * @summary Test non constant addExact * @compile AddExactINonConstantTest.java Verify.java - * @run main AddExactINonConstantTest + * @run main AddExactINonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java --- a/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactIRepeatTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8025657 * @summary Test repeating addExact * @compile AddExactIRepeatTest.java Verify.java - * @run main AddExactIRepeatTest + * @run main AddExactIRepeatTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactLConstantTest.java --- a/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactLConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant addExact * @compile AddExactLConstantTest.java Verify.java - * @run main AddExactLConstantTest + * @run main AddExactLConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java --- a/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/AddExactLNonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant addExact * @compile AddExactLNonConstantTest.java Verify.java - * @run main AddExactLNonConstantTest + * @run main AddExactLNonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/CompareTest.java --- a/test/compiler/intrinsics/mathexact/CompareTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/CompareTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026722 * @summary Verify that the compare after addExact is a signed compare * @compile CompareTest.java - * @run main CompareTest + * @run main CompareTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/DecExactITest.java --- a/test/compiler/intrinsics/mathexact/DecExactITest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/DecExactITest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test decrementExact * @compile DecExactITest.java Verify.java - * @run main DecExactITest + * @run main DecExactITest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/DecExactLTest.java --- a/test/compiler/intrinsics/mathexact/DecExactLTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/DecExactLTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -25,8 +25,8 @@ * @test * @bug 8026844 * @summary Test decrementExact - * @compile DecExactITest.java Verify.java - * @run main DecExactITest + * @compile DecExactLTest.java Verify.java + * @run main DecExactLTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/GVNTest.java --- a/test/compiler/intrinsics/mathexact/GVNTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/GVNTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8028207 * @summary Verify that GVN doesn't mess up the two addExacts * @compile GVNTest.java - * @run main GVNTest + * @run main GVNTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/IncExactITest.java --- a/test/compiler/intrinsics/mathexact/IncExactITest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/IncExactITest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test incrementExact * @compile IncExactITest.java Verify.java - * @run main IncExactITest + * @run main IncExactITest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/IncExactLTest.java --- a/test/compiler/intrinsics/mathexact/IncExactLTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/IncExactLTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test incrementExact * @compile IncExactLTest.java Verify.java - * @run main IncExactLTest + * @run main IncExactLTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactICondTest.java --- a/test/compiler/intrinsics/mathexact/MulExactICondTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactICondTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test multiplyExact as condition * @compile MulExactICondTest.java - * @run main MulExactICondTest + * @run main MulExactICondTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactIConstantTest.java --- a/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactIConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant multiplyExact * @compile MulExactIConstantTest.java Verify.java - * @run main MulExactIConstantTest + * @run main MulExactIConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactILoadTest.java --- a/test/compiler/intrinsics/mathexact/MulExactILoadTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactILoadTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test multiplyExact * @compile MulExactILoadTest.java Verify.java - * @run main MulExactILoadTest + * @run main MulExactILoadTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java --- a/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactILoopDependentTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test loop dependent multiplyExact * @compile MulExactILoopDependentTest.java Verify.java - * @run main MulExactILoopDependentTest + * @run main MulExactILoopDependentTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ public class MulExactILoopDependentTest { diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java --- a/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactINonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant multiplyExact * @compile MulExactINonConstantTest.java Verify.java - * @run main MulExactINonConstantTest + * @run main MulExactINonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java --- a/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactIRepeatTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test repeating multiplyExact * @compile MulExactIRepeatTest.java Verify.java - * @run main MulExactIRepeatTest + * @run main MulExactIRepeatTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactLConstantTest.java --- a/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactLConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant mulExact * @compile MulExactLConstantTest.java Verify.java - * @run main MulExactLConstantTest + * @run main MulExactLConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java --- a/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/MulExactLNonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant mulExact * @compile MulExactLNonConstantTest.java Verify.java - * @run main MulExactLNonConstantTest + * @run main MulExactLNonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactIConstantTest.java --- a/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactIConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @compile NegExactIConstantTest.java Verify.java - * @run main NegExactIConstantTest + * @run main NegExactIConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactILoadTest.java --- a/test/compiler/intrinsics/mathexact/NegExactILoadTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactILoadTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test negExact * @compile NegExactILoadTest.java Verify.java - * @run main NegExactILoadTest + * @run main NegExactILoadTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java --- a/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactILoopDependentTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test negExact loop dependent * @compile NegExactILoopDependentTest.java Verify.java - * @run main NegExactILoopDependentTest + * @run main NegExactILoopDependentTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ public class NegExactILoopDependentTest { diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java --- a/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactINonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant negExact * @compile NegExactINonConstantTest.java Verify.java - * @run main NegExactINonConstantTest + * @run main NegExactINonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactLConstantTest.java --- a/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactLConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @compile NegExactLConstantTest.java Verify.java - * @run main NegExactLConstantTest + * @run main NegExactLConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java --- a/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NegExactLNonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant negExact * @compile NegExactLNonConstantTest.java Verify.java - * @run main NegExactLNonConstantTest + * @run main NegExactLNonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/NestedMathExactTest.java --- a/test/compiler/intrinsics/mathexact/NestedMathExactTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/NestedMathExactTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8027444 * @summary Test nested loops * @compile NestedMathExactTest.java - * @run main NestedMathExactTest + * @run main NestedMathExactTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SplitThruPhiTest.java --- a/test/compiler/intrinsics/mathexact/SplitThruPhiTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SplitThruPhiTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8028198 * @summary Verify that split through phi does the right thing * @compile SplitThruPhiTest.java - * @run main SplitThruPhiTest + * @run main SplitThruPhiTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactICondTest.java --- a/test/compiler/intrinsics/mathexact/SubExactICondTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactICondTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test subtractExact as condition * @compile SubExactICondTest.java Verify.java - * @run main SubExactICondTest + * @run main SubExactICondTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactIConstantTest.java --- a/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactIConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test constant subtractExact * @compile SubExactIConstantTest.java Verify.java - * @run main SubExactIConstantTest + * @run main SubExactIConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactILoadTest.java --- a/test/compiler/intrinsics/mathexact/SubExactILoadTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactILoadTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @compile SubExactILoadTest.java Verify.java - * @run main SubExactILoadTest + * @run main SubExactILoadTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java --- a/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactILoopDependentTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @compile SubExactILoopDependentTest.java Verify.java - * @run main SubExactILoopDependentTest + * @run main SubExactILoopDependentTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java --- a/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactINonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test non constant subtractExact * @compile SubExactINonConstantTest.java Verify.java - * @run main SubExactINonConstantTest + * @run main SubExactINonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java --- a/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactIRepeatTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -26,7 +26,7 @@ * @bug 8026844 * @summary Test repeating subtractExact * @compile SubExactIRepeatTest.java Verify.java - * @run main SubExactIRepeatTest + * @run main SubExactIRepeatTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactLConstantTest.java --- a/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactLConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -27,7 +27,7 @@ * @bug 8027353 * @summary Test constant subtractExact * @compile SubExactLConstantTest.java Verify.java - * @run main SubExactLConstantTest + * @run main SubExactLConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java --- a/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/intrinsics/mathexact/SubExactLNonConstantTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -27,7 +27,7 @@ * @bug 8027353 * @summary Test non constant subtractExact * @compile SubExactLNonConstantTest.java Verify.java - * @run main SubExactLNonConstantTest + * @run main SubExactLNonConstantTest -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseMathExactIntrinsics * */ diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/ConcurrentClassLoadingTest.java --- a/test/compiler/jsr292/ConcurrentClassLoadingTest.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/jsr292/ConcurrentClassLoadingTest.java Wed Dec 18 06:06:52 2013 -0800 @@ -172,7 +172,6 @@ "java.lang.invoke.LambdaConversionException", "java.lang.invoke.LambdaForm", "java.lang.invoke.LambdaMetafactory", - "java.lang.invoke.MagicLambdaImpl", "java.lang.invoke.MemberName", "java.lang.invoke.MethodHandle", "java.lang.invoke.MethodHandleImpl", diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java --- a/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java Wed Dec 18 06:06:52 2013 -0800 @@ -1,3 +1,12 @@ +import java.io.BufferedOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + /* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,12 +32,63 @@ */ /** - * A minimal classloader for loading bytecodes that could not result from - * properly compiled Java. + * A ByteClassLoader is used to define classes from collections of bytes, as + * well as loading classes in the usual way. It includes options to write the + * classes to files in a jar, or to read the classes from jars in a later or + * debugging run. + * + * If Boolean property byteclassloader.verbose is true, be chatty about jar + * file operations. * - * @author dr2chase */ -public class ByteClassLoader extends ClassLoader { +public class ByteClassLoader extends URLClassLoader { + + final static boolean verbose + = Boolean.getBoolean("byteclassloader.verbose"); + + final boolean read; + final JarOutputStream jos; + final String jar_name; + + /** + * Make a new ByteClassLoader. + * + * @param jar_name Basename of jar file to be read/written by this classloader. + * @param read If true, read classes from jar file instead of from parameter. + * @param write If true, write classes to jar files for offline study/use. + * + * @throws FileNotFoundException + * @throws IOException + */ + public ByteClassLoader(String jar_name, boolean read, boolean write) + throws FileNotFoundException, IOException { + super(read + ? new URL[]{new URL("file:" + jar_name + ".jar")} + : new URL[0]); + this.read = read; + this.jar_name = jar_name; + this.jos = write + ? new JarOutputStream( + new BufferedOutputStream( + new FileOutputStream(jar_name + ".jar"))) : null; + if (read && write) { + throw new Error("At most one of read and write may be true."); + } + } + + private static void writeJarredFile(JarOutputStream jos, String file, String suffix, byte[] bytes) { + String fileName = file.replace(".", "/") + "." + suffix; + JarEntry ze = new JarEntry(fileName); + try { + ze.setSize(bytes.length); + jos.putNextEntry(ze); + jos.write(bytes); + jos.closeEntry(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * (pre)load class name using classData for the definition. * @@ -36,9 +96,36 @@ * @param classData * @return */ - public Class loadBytes(String name, byte[] classData) { - Class clazz = defineClass(name, classData, 0, classData.length); - resolveClass(clazz); - return clazz; + public Class loadBytes(String name, byte[] classData) throws ClassNotFoundException { + if (jos != null) { + if (verbose) { + System.out.println("ByteClassLoader: writing " + name); + } + writeJarredFile(jos, name, "class", classData); + } + + Class clazz = null; + if (read) { + if (verbose) { + System.out.println("ByteClassLoader: reading " + name + " from " + jar_name); + } + clazz = loadClass(name); + } else { + clazz = defineClass(name, classData, 0, classData.length); + resolveClass(clazz); + } + return clazz; + } + + public void close() { + if (jos != null) { + try { + if (verbose) { + System.out.println("ByteClassLoader: closing " + jar_name); + } + jos.close(); + } catch (IOException ex) { + } + } } } diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/C.java --- a/test/compiler/jsr292/methodHandleExceptions/C.java Wed Dec 18 03:16:17 2013 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -/** - * Test class -- implements I, which provides default for m, but this class - * declares it abstract which (should) hide the interface default, and throw - * an abstract method error if it is called (calling it requires bytecode hacking - * or inconsistent compilation). - */ -public abstract class C implements I { - public abstract int m(); -} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/I.java --- a/test/compiler/jsr292/methodHandleExceptions/I.java Wed Dec 18 03:16:17 2013 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -public interface I { - default public int m() { return 1; } -} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java --- a/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Wed Dec 18 06:06:52 2013 -0800 @@ -21,50 +21,127 @@ * questions. * */ - import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Handle; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.Opcodes; +import p.Dok; /** - * @test - * @bug 8025260 - * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path + * @test @bug 8025260 8016839 + * @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException + * + * @compile -XDignore.symbol.file TestAMEnotNPE.java ByteClassLoader.java p/C.java p/Dok.java p/E.java p/F.java p/I.java p/Tdirect.java p/Treflect.java * - * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java * @run main/othervm TestAMEnotNPE + * @run main/othervm -Xint TestAMEnotNPE + * @run main/othervm -Xcomp TestAMEnotNPE */ - public class TestAMEnotNPE implements Opcodes { + static boolean writeJarFiles = false; + static boolean readJarFiles = false; + /** - * The bytes for D, a NOT abstract class extending abstract class C - * without supplying an implementation for abstract method m. - * There is a default method in the interface I, but it should lose to - * the abstract class. + * Optional command line parameter (any case-insensitive prefix of) + * "writejarfiles" or "readjarfiles". + * + * "Writejarfiles" creates a jar file for each different set of tested classes. + * "Readjarfiles" causes the classloader to use the copies of the classes + * found in the corresponding jar files. + * + * Jarfilenames look something like pD_ext_pF (p.D extends p.F) + * and qD_m_pp_imp_pI (q.D with package-private m implements p.I) + * + */ + public static void main(String args[]) throws Throwable { + ArrayList lt = new ArrayList(); + + if (args.length > 0) { + String a0 = args[0].toLowerCase(); + if (a0.length() > 0) { + writeJarFiles = ("writejarfiles").startsWith(a0); + readJarFiles = ("readjarfiles").startsWith(a0); + } + if (!(writeJarFiles || readJarFiles)) { + throw new Error("Command line parameter (if any) should be prefix of writeJarFiles or readJarFiles"); + } + } + + try { + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL"); + tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"), + "p.D extends p.F (p.F implements p.I, FINAL public m), private m", + IllegalAccessError.class, "pD_ext_pF"); + // We'll take either a VerifyError (pre 2013-11-30) + // or an IllegalAccessError (post 2013-11-22) + } catch (VerifyError ve) { + System.out.println("Saw expected VerifyError " + ve); + } + System.out.println(); - class D extends C { - D() { super(); } - // does not define m - } + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E"); + tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"), + "p.D extends p.E (p.E implements p.I, public m), private m", + IllegalAccessError.class, "pD_ext_pE"); + + System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m"); + tryAndCheckThrown(lt, bytesForD(), + "D extends abstract C, no m", + AbstractMethodError.class, "pD_ext_pC"); + + System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m"); + tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0), + "q.D implements p.I, protected m", IllegalAccessError.class, + "qD_m_pp_imp_pI"); + + // Note jar file name is used in the plural-arg case. + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m"); + tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), + "p.D implements p.I, private m", + IllegalAccessError.class, "pD_m_pri_imp_pI"); + // Plural-arg test. + System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m"); + tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), + "p.D implements p.I, private m", IllegalAccessError.class); + + if (lt.size() > 0) { + System.out.flush(); + Thread.sleep(250); // This de-interleaves output and error in Netbeans, sigh. + for (Throwable th : lt) + System.err.println(th); + throw new Error("Test failed, there were " + lt.size() + " failures listed above"); + } else { + System.out.println("ALL PASS, HOORAY!"); + } + } + + /** + * The bytes for D, a NOT abstract class extending abstract class C without + * supplying an implementation for abstract method m. There is a default + * method in the interface I, but it should lose to the abstract class. + * * @return * @throws Exception */ public static byte[] bytesForD() throws Exception { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); MethodVisitor mv; - cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null); + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/D", null, "p/C", null); { mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "C", "", "()V"); + mv.visitMethodInsn(INVOKESPECIAL, "p/C", "", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -74,70 +151,346 @@ return cw.toByteArray(); } + /** + * The bytes for D, implements I, does not extend C, declares m()I with + * access method_acc. + * + * @param d_name Name of class defined + * @param method_acc Accessibility of that class's method m. + * @return + * @throws Exception + */ + public static byte[] bytesForDsomeAccess(String d_name, int method_acc) throws Exception { + return bytesForSomeDsubSomethingSomeAccess(d_name, "java/lang/Object", method_acc); + } + + /** + * The bytes for D implements I, extends some class, declares m()I as + * private. + * + * Invokeinterface of I.m applied to this D should throw IllegalAccessError + * + * @param sub_what The name of the class that D will extend. + * @return + * @throws Exception + */ + public static byte[] bytesForDprivateSubWhat(String sub_what) throws Exception { + return bytesForSomeDsubSomethingSomeAccess("p/D", sub_what, ACC_PRIVATE); + } /** - * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D + * Returns the bytes for a class with name d_name (presumably "D" in some + * package), extending some class with name sub_what, implementing p.I, + * and defining two methods m() and m(11args) with access method_acc. + * + * @param d_name Name of class that is defined + * @param sub_what Name of class that it extends + * @param method_acc Accessibility of method(s) m in defined class. + * @return + * @throws Exception + */ + public static byte[] bytesForSomeDsubSomethingSomeAccess + (String d_name, String sub_what, int method_acc) + throws Exception { + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); + MethodVisitor mv; + String[] interfaces = {"p/I"}; - class T { - T() { super(); } // boring constructor - int test() { - MethodHandle mh = `I.m():int`; - D d = new D(); - return mh.invokeExact(d); // Should explode here, AbstractMethodError - } + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, d_name, null, sub_what, interfaces); + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, sub_what, "", "()V"); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + // int m() {return 3;} + { + mv = cw.visitMethod(method_acc, "m", "()I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Integer(3)); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); } + // int m(11args) {return 3;} + { + mv = cw.visitMethod(method_acc, "m", "(BCSIJ" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + ")I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Integer(3)); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } + /** + * The bytecodes for a class p/T defining a methods test() and test(11args) + * that contain an invokeExact of a particular methodHandle, I.m. + * + * Test will be passed values that may imperfectly implement I, + * and thus may in turn throw exceptions. + * * @return * @throws Exception */ public static byte[] bytesForT() throws Exception { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); MethodVisitor mv; - cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null); + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/T", null, "java/lang/Object", null); { mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); mv.visitInsn(RETURN); - mv.visitMaxs(0,0); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + // static int test(I) + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;)I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "()I")); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", + "invokeExact", "(Lp/I;)I"); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); mv.visitEnd(); } + // static int test(I,11args) { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I", null, null); mv.visitCode(); - mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I")); - mv.visitTypeInsn(NEW, "D"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "D", "", "()V"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I"); + mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "(BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I")); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(LLOAD, 5); + mv.visitVarInsn(ALOAD, 7); + mv.visitVarInsn(ALOAD, 8); + mv.visitVarInsn(ALOAD, 9); + mv.visitVarInsn(ALOAD, 10); + mv.visitVarInsn(ALOAD, 11); + mv.visitVarInsn(ALOAD, 12); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", + "invokeExact", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I"); mv.visitInsn(IRETURN); - mv.visitMaxs(0,0); + mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } - public static void main(String args[] ) throws Throwable { - ByteClassLoader bcl = new ByteClassLoader(); - Class d = bcl.loadBytes("D", bytesForD()); - Class t = bcl.loadBytes("T", bytesForT()); + private static void tryAndCheckThrown( + List lt, byte[] dBytes, String what, Class expected, String jar_name) + throws Throwable { + tryAndCheckThrown(lt, "p.D", dBytes, what, expected, jar_name); + } + + private static void tryAndCheckThrown(List lt, String d_name, byte[] dBytes, String what, Class expected, String jar_name) + throws Throwable { + + System.out.println("Methodhandle invokeExact I.m() for instance of " + what); + ByteClassLoader bcl1 = new ByteClassLoader(jar_name, readJarFiles, writeJarFiles); try { - Object result = t.getMethod("test").invoke(null); - System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception"); - throw new Error("Missing expected exception"); + Class d1 = bcl1.loadBytes(d_name, dBytes); + Class t1 = bcl1.loadBytes("p.T", bytesForT()); + invokeTest(t1, d1, expected, lt); + } finally { + // Not necessary for others -- all class files are written in this call. + // (unless the VM crashes first). + bcl1.close(); + } + + System.out.println("Reflection invoke I.m() for instance of " + what); + ByteClassLoader bcl3 = new ByteClassLoader(jar_name, readJarFiles, false); + Class d3 = bcl3.loadBytes(d_name, dBytes); + Class t3 = bcl3.loadClass("p.Treflect"); + invokeTest(t3, d3, expected, lt); + + System.out.println("Bytecode invokeInterface I.m() for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader(jar_name, readJarFiles, false); + Class d2 = bcl2.loadBytes(d_name, dBytes); + Class t2 = bcl2.loadClass("p.Tdirect"); + badGoodBadGood(t2, d2, expected, lt); + } + + private static void invokeTest(Class t, Class d, Class expected, List lt) + throws Throwable { + try { + Method m = t.getMethod("test", p.I.class); + Object o = d.newInstance(); + Object result = m.invoke(null, o); + if (expected != null) { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, but nothing was thrown"); + lt.add(new Error("Exception " + expected.getName() + " was not thrown")); + } else { + System.out.println("PASS, saw expected return."); + } } catch (InvocationTargetException e) { Throwable th = e.getCause(); - if (th instanceof AbstractMethodError) { - th.printStackTrace(System.out); - System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException)."); + th.printStackTrace(System.out); + if (expected != null) { + if (expected.isInstance(th)) { + System.out.println("PASS, saw expected exception (" + expected.getName() + ")."); + } else { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, saw " + th); + lt.add(th); + } } else { - System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th); - throw th; + System.out.println("FAIL, expected no exception, saw " + th); + lt.add(th); } } + System.out.println(); + } + + /* Many-arg versions of above */ + private static void tryAndCheckThrownMany(List lt, byte[] dBytes, String what, Class expected) + throws Throwable { + + System.out.println("Methodhandle invokeExact I.m(11params) for instance of " + what); + ByteClassLoader bcl1 = new ByteClassLoader("p.D", readJarFiles, false); + try { + Class d1 = bcl1.loadBytes("p.D", dBytes); + Class t1 = bcl1.loadBytes("p.T", bytesForT()); + invokeTestMany(t1, d1, expected, lt); + } finally { + bcl1.close(); // Not necessary for others -- all class files are written in this call. + } + + { + System.out.println("Bytecode invokeInterface I.m(11params) for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false); + Class d2 = bcl2.loadBytes("p.D", dBytes); + Class t2 = bcl2.loadClass("p.Tdirect"); + badGoodBadGoodMany(t2, d2, expected, lt); + + } + { + System.out.println("Reflection invokeInterface I.m(11params) for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false); + Class d2 = bcl2.loadBytes("p.D", dBytes); + Class t2 = bcl2.loadClass("p.Treflect"); + invokeTestMany(t2, d2, expected, lt); + } + } + + private static void invokeTestMany(Class t, Class d, Class expected, List lt) + throws Throwable { + try { + Method m = t.getMethod("test", p.I.class, + Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, + Object.class, Object.class, Object.class, + Object.class, Object.class, Object.class); + Object o = d.newInstance(); + Byte b = 1; + Character c = 2; + Short s = 3; + Integer i = 4; + Long j = 5L; + Object o1 = b; + Object o2 = c; + Object o3 = s; + Object o4 = i; + Object o5 = j; + Object o6 = "6"; + + Object result = m.invoke(null, o, b, c, s, i, j, + o1, o2, o3, o4, o5, o6); + if (expected != null) { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, but nothing was thrown"); + lt.add(new Error("Exception " + expected.getName() + + " was not thrown")); + } else { + System.out.println("PASS, saw expected return."); + } + } catch (InvocationTargetException e) { + Throwable th = e.getCause(); + th.printStackTrace(System.out); + if (expected != null) { + if (expected.isInstance(th)) { + System.out.println("PASS, saw expected exception (" + + expected.getName() + ")."); + } else { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, saw " + th); + lt.add(th); + } + } else { + System.out.println("FAIL, expected no exception, saw " + th); + lt.add(th); + } + } + System.out.println(); + } + + /** + * This tests a peculiar idiom for tickling the bug on older VMs that lack + * methodhandles. The bug (if not fixed) acts in the following way: + * + * When a broken receiver is passed to the first execution of an invokeinterface + * bytecode, the illegal access is detected before the effects of resolution are + * cached for later use, and so repeated calls with a broken receiver will always + * throw the correct error. + * + * If, however, a good receiver is passed to the invokeinterface, the effects of + * resolution will be successfully cached. A subsequent execution with a broken + * receiver will reuse the cached information, skip the detailed resolution work, + * and instead encounter a null pointer. By convention, that is the encoding for a + * missing abstract method, and an AbstractMethodError is thrown -- not the expected + * IllegalAccessError. + * + * @param t2 Test invocation class + * @param d2 Test receiver class + * @param expected expected exception type + * @param lt list of unexpected throwables seen + */ + private static void badGoodBadGood(Class t2, Class d2, Class expected, List lt) + throws Throwable { + System.out.println(" Error input 1st time"); + invokeTest(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTest(t2, Dok.class, null, lt); + System.out.println(" Error input 2nd time"); + invokeTest(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTest(t2, Dok.class, null, lt); + } + + private static void badGoodBadGoodMany(Class t2, Class d2, Class expected, List lt) + throws Throwable { + System.out.println(" Error input 1st time"); + invokeTestMany(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTestMany(t2, Dok.class, null, lt); + System.out.println(" Error input 2nd time"); + invokeTestMany(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTestMany(t2, Dok.class, null, lt); } } diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/C.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * declares it abstract which (should) hide the interface default, and throw + * an abstract method error if called. + * + */ +public abstract class C implements p.I { + public abstract int m(); +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/Dok.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Dok.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p; + +/** + * Test class -- implements I, extends E, both define m, so all should be well. + */ +public class Dok extends p.E { + +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/E.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/E.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * redeclares it so that all its non-overriding descendants should call its + * method instead (with no error, assuming no descendant monkey business, which + * of course is NOT usually the case in this test). + * + */ +public abstract class E implements p.I { + public int m() { + return 2; + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/F.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/F.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * redeclares it so that all its non-overriding descendants should call its + * method instead (with no error, assuming no descendant monkey business, which + * of course is NOT usually the case in this test). + * + * Note that m is final -- one form of monkey business is attempting to redefine + * m. + * + */ +public abstract class F implements p.I { + final public int m() { + return 2; + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/I.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/I.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package p; + +/** + * Test interface I, provides default implementations for m() and m(11args). + */ + +public interface I { + default public int m() { return 1; } + default public int m(byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + return 2; + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/Tdirect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Tdirect.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package p; + +/** + * Invokes I.m directly using invokeInterface bytecodes. + */ +public class Tdirect { + public static int test(p.I i) { + int accum = 0; + for (int j = 0; j < 100000; j++) { + accum += i.m(); + } + return accum; + } + + public static int test(p.I ii, byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + int accum = 0; + for (int j = 0; j < 100000; j++) { + accum += ii.m(b,c,s,i,l,o1,o2,o3,o4,o5,o6); + } + return accum; + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/jsr292/methodHandleExceptions/p/Treflect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Treflect.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package p; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Invokes I.m using reflection. + */ +public class Treflect { + + public static int test(p.I ii) throws Throwable { + int accum = 0; + Method m = p.I.class.getMethod("m"); + try { + for (int j = 0; j < 100000; j++) { + Object o = m.invoke(ii); + accum += ((Integer) o).intValue(); + } + } catch (InvocationTargetException ite) { + throw ite.getCause(); + } + return accum; + } + + public static int test(p.I ii, byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) + throws Throwable { + Method m = p.I.class.getMethod("m", Byte.TYPE, Character.TYPE, + Short.TYPE, Integer.TYPE, Long.TYPE, + Object.class, Object.class, Object.class, + Object.class, Object.class, Object.class); + int accum = 0; + try { + for (int j = 0; j < 100000; j++) { + Object o = m.invoke(ii, b, c, s, i, l, o1, o2, o3, o4, o5, o6); + accum += ((Integer) o).intValue(); + } + } catch (InvocationTargetException ite) { + throw ite.getCause(); + } + return accum; + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/reflection/ArrayNewInstanceOfVoid.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/reflection/ArrayNewInstanceOfVoid.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8029366 + * @summary ShouldNotReachHere error when creating an array with component type of void + */ + +public class ArrayNewInstanceOfVoid { + public static void main(String[] args) { + for (int i = 0; i < 100_000; i++) { + test(); + } + } + + private static void test() { + try { + java.lang.reflect.Array.newInstance(void.class, 2); + } catch (IllegalArgumentException e) { + // expected + } + } +} diff -r f76593e3fedb -r 163b418ec095 test/compiler/regalloc/C1ObjectSpillInLogicOp.java --- a/test/compiler/regalloc/C1ObjectSpillInLogicOp.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/compiler/regalloc/C1ObjectSpillInLogicOp.java Wed Dec 18 06:06:52 2013 -0800 @@ -34,8 +34,9 @@ */ import java.util.concurrent.atomic.*; -class C1ObjectSpillInLogicOp { - static public void main(String[] args) { + +public class C1ObjectSpillInLogicOp { + public static void main(String[] args) { AtomicReferenceArray x = new AtomicReferenceArray(128); Integer y = new Integer(0); for (int i = 0; i < 50000; i++) { diff -r f76593e3fedb -r 163b418ec095 test/compiler/uncommontrap/TestStackBangRbp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/uncommontrap/TestStackBangRbp.java Wed Dec 18 06:06:52 2013 -0800 @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8028308 + * @summary rbp not restored when stack overflow is thrown from deopt/uncommon trap blobs + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangRbp + * + */ +public class TestStackBangRbp { + + static class UnloadedClass1 { + } + + static class UnloadedClass2 { + } + + static Object m1(boolean deopt) { + long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, + l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, + l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36, + l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48, + l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60, + l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72, + l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84, + l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96, + l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107, + l108, l109, l110, l111, l112, l113, l114, l115, l116, l117, + l118, l119, l120, l121, l122, l123, l124, l125, l126, l127, + l128, l129, l130, l131, l132, l133, l134, l135, l136, l137, + l138, l139, l140, l141, l142, l143, l144, l145, l146, l147, + l148, l149, l150, l151, l152, l153, l154, l155, l156, l157, + l158, l159, l160, l161, l162, l163, l164, l165, l166, l167, + l168, l169, l170, l171, l172, l173, l174, l175, l176, l177, + l178, l179, l180, l181, l182, l183, l184, l185, l186, l187, + l188, l189, l190, l191, l192, l193, l194, l195, l196, l197, + l198, l199, l200, l201, l202, l203, l204, l205, l206, l207, + l208, l209, l210, l211, l212, l213, l214, l215, l216, l217, + l218, l219, l220, l221, l222, l223, l224, l225, l226, l227, + l228, l229, l230, l231, l232, l233, l234, l235, l236, l237, + l238, l239, l240, l241, l242, l243, l244, l245, l246, l247, + l248, l249, l250, l251, l252, l253, l254, l255, l256, l257, + l258, l259, l260, l261, l262, l263, l264, l265, l266, l267, + l268, l269, l270, l271, l272, l273, l274, l275, l276, l277, + l278, l279, l280, l281, l282, l283, l284, l285, l286, l287, + l288, l289, l290, l291, l292, l293, l294, l295, l296, l297, + l298, l299, l300, l301, l302, l303, l304, l305, l306, l307, + l308, l309, l310, l311, l312, l313, l314, l315, l316, l317, + l318, l319, l320, l321, l322, l323, l324, l325, l326, l327, + l328, l329, l330, l331, l332, l333, l334, l335, l336, l337, + l338, l339, l340, l341, l342, l343, l344, l345, l346, l347, + l348, l349, l350, l351, l352, l353, l354, l355, l356, l357, + l358, l359, l360, l361, l362, l363, l364, l365, l366, l367, + l368, l369, l370, l371, l372, l373, l374, l375, l376, l377, + l378, l379, l380, l381, l382, l383, l384, l385, l386, l387, + l388, l389, l390, l391, l392, l393, l394, l395, l396, l397, + l398, l399, l400, l401, l402, l403, l404, l405, l406, l407, + l408, l409, l410, l411, l412, l413, l414, l415, l416, l417, + l418, l419, l420, l421, l422, l423, l424, l425, l426, l427, + l428, l429, l430, l431, l432, l433, l434, l435, l436, l437, + l438, l439, l440, l441, l442, l443, l444, l445, l446, l447, + l448, l449, l450, l451, l452, l453, l454, l455, l456, l457, + l458, l459, l460, l461, l462, l463, l464, l465, l466, l467, + l468, l469, l470, l471, l472, l473, l474, l475, l476, l477, + l478, l479, l480, l481, l482, l483, l484, l485, l486, l487, + l488, l489, l490, l491, l492, l493, l494, l495, l496, l497, + l498, l499, l500, l501, l502, l503, l504, l505, l506, l507, + l508, l509, l510, l511; + + long ll0, ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, ll9, ll10, ll11, ll12, + ll13, ll14, ll15, ll16, ll17, ll18, ll19, ll20, ll21, ll22, ll23, ll24, + ll25, ll26, ll27, ll28, ll29, ll30, ll31, ll32, ll33, ll34, ll35, ll36, + ll37, ll38, ll39, ll40, ll41, ll42, ll43, ll44, ll45, ll46, ll47, ll48, + ll49, ll50, ll51, ll52, ll53, ll54, ll55, ll56, ll57, ll58, ll59, ll60, + ll61, ll62, ll63, ll64, ll65, ll66, ll67, ll68, ll69, ll70, ll71, ll72, + ll73, ll74, ll75, ll76, ll77, ll78, ll79, ll80, ll81, ll82, ll83, ll84, + ll85, ll86, ll87, ll88, ll89, ll90, ll91, ll92, ll93, ll94, ll95, ll96, + ll97, ll98, ll99, ll100, ll101, ll102, ll103, ll104, ll105, ll106, ll107, + ll108, ll109, ll110, ll111, ll112, ll113, ll114, ll115, ll116, ll117, + ll118, ll119, ll120, ll121, ll122, ll123, ll124, ll125, ll126, ll127, + ll128, ll129, ll130, ll131, ll132, ll133, ll134, ll135, ll136, ll137, + ll138, ll139, ll140, ll141, ll142, ll143, ll144, ll145, ll146, ll147, + ll148, ll149, ll150, ll151, ll152, ll153, ll154, ll155, ll156, ll157, + ll158, ll159, ll160, ll161, ll162, ll163, ll164, ll165, ll166, ll167, + ll168, ll169, ll170, ll171, ll172, ll173, ll174, ll175, ll176, ll177, + ll178, ll179, ll180, ll181, ll182, ll183, ll184, ll185, ll186, ll187, + ll188, ll189, ll190, ll191, ll192, ll193, ll194, ll195, ll196, ll197, + ll198, ll199, ll200, ll201, ll202, ll203, ll204, ll205, ll206, ll207, + ll208, ll209, ll210, ll211, ll212, ll213, ll214, ll215, ll216, ll217, + ll218, ll219, ll220, ll221, ll222, ll223, ll224, ll225, ll226, ll227, + ll228, ll229, ll230, ll231, ll232, ll233, ll234, ll235, ll236, ll237, + ll238, ll239, ll240, ll241, ll242, ll243, ll244, ll245, ll246, ll247, + ll248, ll249, ll250, ll251, ll252, ll253, ll254, ll255, ll256, ll257, + ll258, ll259, ll260, ll261, ll262, ll263, ll264, ll265, ll266, ll267, + ll268, ll269, ll270, ll271, ll272, ll273, ll274, ll275, ll276, ll277, + ll278, ll279, ll280, ll281, ll282, ll283, ll284, ll285, ll286, ll287, + ll288, ll289, ll290, ll291, ll292, ll293, ll294, ll295, ll296, ll297, + ll298, ll299, ll300, ll301, ll302, ll303, ll304, ll305, ll306, ll307, + ll308, ll309, ll310, ll311, ll312, ll313, ll314, ll315, ll316, ll317, + ll318, ll319, ll320, ll321, ll322, ll323, ll324, ll325, ll326, ll327, + ll328, ll329, ll330, ll331, ll332, ll333, ll334, ll335, ll336, ll337, + ll338, ll339, ll340, ll341, ll342, ll343, ll344, ll345, ll346, ll347, + ll348, ll349, ll350, ll351, ll352, ll353, ll354, ll355, ll356, ll357, + ll358, ll359, ll360, ll361, ll362, ll363, ll364, ll365, ll366, ll367, + ll368, ll369, ll370, ll371, ll372, ll373, ll374, ll375, ll376, ll377, + ll378, ll379, ll380, ll381, ll382, ll383, ll384, ll385, ll386, ll387, + ll388, ll389, ll390, ll391, ll392, ll393, ll394, ll395, ll396, ll397, + ll398, ll399, ll400, ll401, ll402, ll403, ll404, ll405, ll406, ll407, + ll408, ll409, ll410, ll411, ll412, ll413, ll414, ll415, ll416, ll417, + ll418, ll419, ll420, ll421, ll422, ll423, ll424, ll425, ll426, ll427, + ll428, ll429, ll430, ll431, ll432, ll433, ll434, ll435, ll436, ll437, + ll438, ll439, ll440, ll441, ll442, ll443, ll444, ll445, ll446, ll447, + ll448, ll449, ll450, ll451, ll452, ll453, ll454, ll455, ll456, ll457, + ll458, ll459, ll460, ll461, ll462, ll463, ll464, ll465, ll466, ll467, + ll468, ll469, ll470, ll471, ll472, ll473, ll474, ll475, ll476, ll477, + ll478, ll479, ll480, ll481, ll482, ll483, ll484, ll485, ll486, ll487, + ll488, ll489, ll490, ll491, ll492, ll493, ll494, ll495, ll496, ll497, + ll498, ll499, ll500, ll501, ll502, ll503, ll504, ll505, ll506, ll507, + ll508, ll509, ll510, ll511; + + int i1 = TestStackBangRbp.i1; + int i2 = TestStackBangRbp.i2; + int i3 = TestStackBangRbp.i3; + int i4 = TestStackBangRbp.i4; + int i5 = TestStackBangRbp.i5; + int i6 = TestStackBangRbp.i6; + int i7 = TestStackBangRbp.i7; + int i8 = TestStackBangRbp.i8; + int i9 = TestStackBangRbp.i9; + int i10 = TestStackBangRbp.i10; + int i11 = TestStackBangRbp.i11; + int i12 = TestStackBangRbp.i12; + int i13 = TestStackBangRbp.i13; + int i14 = TestStackBangRbp.i14; + int i15 = TestStackBangRbp.i15; + int i16 = TestStackBangRbp.i16; + + TestStackBangRbp.i1 = i1; + TestStackBangRbp.i2 = i2; + TestStackBangRbp.i3 = i3; + TestStackBangRbp.i4 = i4; + TestStackBangRbp.i5 = i5; + TestStackBangRbp.i6 = i6; + TestStackBangRbp.i7 = i7; + TestStackBangRbp.i8 = i8; + TestStackBangRbp.i9 = i9; + TestStackBangRbp.i10 = i10; + TestStackBangRbp.i11 = i11; + TestStackBangRbp.i12 = i12; + TestStackBangRbp.i13 = i13; + TestStackBangRbp.i14 = i14; + TestStackBangRbp.i15 = i15; + TestStackBangRbp.i16 = i16; + + if (deopt) { + // deoptimize with integer in rbp + UnloadedClass1 res = new UnloadedClass1(); // forces deopt with c2 + return res; + } + return null; + } + + static boolean m2(boolean deopt) { + // call m2 recursively until stack overflow. Then call m3 that + // will call m1 and trigger and deopt in m1 while keeping a + // lot of objects live in registers at the call to m1 + + long l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, + l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, + l25, l26, l27, l28, l29, l30, l31, l32, l33, l34, l35, l36, + l37, l38, l39, l40, l41, l42, l43, l44, l45, l46, l47, l48, + l49, l50, l51, l52, l53, l54, l55, l56, l57, l58, l59, l60, + l61, l62, l63, l64, l65, l66, l67, l68, l69, l70, l71, l72, + l73, l74, l75, l76, l77, l78, l79, l80, l81, l82, l83, l84, + l85, l86, l87, l88, l89, l90, l91, l92, l93, l94, l95, l96, + l97, l98, l99, l100, l101, l102, l103, l104, l105, l106, l107, + l108, l109, l110, l111, l112, l113, l114, l115, l116, l117, + l118, l119, l120, l121, l122, l123, l124, l125, l126, l127, + l128, l129, l130, l131, l132, l133, l134, l135, l136, l137, + l138, l139, l140, l141, l142, l143, l144, l145, l146, l147, + l148, l149, l150, l151, l152, l153, l154, l155, l156, l157, + l158, l159, l160, l161, l162, l163, l164, l165, l166, l167, + l168, l169, l170, l171, l172, l173, l174, l175, l176, l177, + l178, l179, l180, l181, l182, l183, l184, l185, l186, l187, + l188, l189, l190, l191, l192, l193, l194, l195, l196, l197, + l198, l199, l200, l201, l202, l203, l204, l205, l206, l207, + l208, l209, l210, l211, l212, l213, l214, l215, l216, l217, + l218, l219, l220, l221, l222, l223, l224, l225, l226, l227, + l228, l229, l230, l231, l232, l233, l234, l235, l236, l237, + l238, l239, l240, l241, l242, l243, l244, l245, l246, l247, + l248, l249, l250, l251, l252, l253, l254, l255, l256, l257, + l258, l259, l260, l261, l262, l263, l264, l265, l266, l267, + l268, l269, l270, l271, l272, l273, l274, l275, l276, l277, + l278, l279, l280, l281, l282, l283, l284, l285, l286, l287, + l288, l289, l290, l291, l292, l293, l294, l295, l296, l297, + l298, l299, l300, l301, l302, l303, l304, l305, l306, l307, + l308, l309, l310, l311, l312, l313, l314, l315, l316, l317, + l318, l319, l320, l321, l322, l323, l324, l325, l326, l327, + l328, l329, l330, l331, l332, l333, l334, l335, l336, l337, + l338, l339, l340, l341, l342, l343, l344, l345, l346, l347, + l348, l349, l350, l351, l352, l353, l354, l355, l356, l357, + l358, l359, l360, l361, l362, l363, l364, l365, l366, l367, + l368, l369, l370, l371, l372, l373, l374, l375, l376, l377, + l378, l379, l380, l381, l382, l383, l384, l385, l386, l387, + l388, l389, l390, l391, l392, l393, l394, l395, l396, l397, + l398, l399, l400, l401, l402, l403, l404, l405, l406, l407, + l408, l409, l410, l411, l412, l413, l414, l415, l416, l417, + l418, l419, l420, l421, l422, l423, l424, l425, l426, l427, + l428, l429, l430, l431, l432, l433, l434, l435, l436, l437, + l438, l439, l440, l441, l442, l443, l444, l445, l446, l447, + l448, l449, l450, l451, l452, l453, l454, l455, l456, l457, + l458, l459, l460, l461, l462, l463, l464, l465, l466, l467, + l468, l469, l470, l471, l472, l473, l474, l475, l476, l477, + l478, l479, l480, l481, l482, l483, l484, l485, l486, l487, + l488, l489, l490, l491, l492, l493, l494, l495, l496, l497, + l498, l499, l500, l501, l502, l503, l504, l505, l506, l507, + l508, l509, l510, l511; + + boolean do_m3 = false; + try { + do_m3 = m2(deopt); + } catch (StackOverflowError e) { + return true; + } + if (do_m3) { + m3(deopt); + } + return false; + } + + static volatile Object o1 = new Object(); + + static volatile int i1 = 1; + static volatile int i2 = 2; + static volatile int i3 = 3; + static volatile int i4 = 4; + static volatile int i5 = 5; + static volatile int i6 = 6; + static volatile int i7 = 7; + static volatile int i8 = 8; + static volatile int i9 = 9; + static volatile int i10 = 10; + static volatile int i11 = 11; + static volatile int i12 = 12; + static volatile int i13 = 13; + static volatile int i14 = 14; + static volatile int i15 = 15; + static volatile int i16 = 16; + + static void m3(boolean deopt) { + Object o1 = TestStackBangRbp.o1; + TestStackBangRbp.o1 = o1; + + try { + m1(deopt); + } catch (StackOverflowError e) { + // deoptimize again. rbp holds an integer. It should have an object. + UnloadedClass2 res = new UnloadedClass2(); // forces deopt with c2 + } + TestStackBangRbp.o1 = o1; + } + + static public void main(String[] args) { + // get m1 & m3 compiled + for (int i = 0; i < 20000; i++) { + m1(false); + m3(false); + } + m2(true); + + System.out.println("TEST PASSED"); + } +} diff -r f76593e3fedb -r 163b418ec095 test/runtime/6626217/Test6626217.sh --- a/test/runtime/6626217/Test6626217.sh Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/6626217/Test6626217.sh Wed Dec 18 06:06:52 2013 -0800 @@ -21,7 +21,8 @@ # questions. # - + +# @ignore 8028733 # @test @(#)Test6626217.sh # @bug 6626217 # @summary Loader-constraint table allows arrays instead of only the base-classes diff -r f76593e3fedb -r 163b418ec095 test/runtime/6929067/Test6929067.sh --- a/test/runtime/6929067/Test6929067.sh Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/6929067/Test6929067.sh Wed Dec 18 06:06:52 2013 -0800 @@ -1,6 +1,7 @@ #!/bin/sh ## +## @ignore 8028740 ## @test Test6929067.sh ## @bug 6929067 ## @bug 8021296 diff -r f76593e3fedb -r 163b418ec095 test/runtime/8024804/RegisterNatives.java --- a/test/runtime/8024804/RegisterNatives.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/8024804/RegisterNatives.java Wed Dec 18 06:06:52 2013 -0800 @@ -24,7 +24,8 @@ /* * @test * @bug 8024804 - * @summary registerNatives() interface resolution should receive IAE + * @bug 8028741 + * @summary interface method resolution should skip finding j.l.Object's registerNatives() and succeed in selecting class B's registerNatives() * @run main RegisterNatives */ public class RegisterNatives { @@ -37,10 +38,10 @@ try { val.registerNatives(); } catch (IllegalAccessError e) { - System.out.println("TEST PASSES - according to current JVM spec, IAE expected\n"); - return; + System.out.println("TEST FAILS - JDK 8 JVMS, static and non-public methods of j.l.Object should be ignored during interface method resolution\n"); + e.printStackTrace(); + throw e; } - System.out.println("TEST FAILS - no IAE resulted\n"); - System.exit(1); + System.out.println("TEST PASSES - no IAE resulted\n"); } } diff -r f76593e3fedb -r 163b418ec095 test/runtime/CDSCompressedKPtrs/XShareAuto.java --- a/test/runtime/CDSCompressedKPtrs/XShareAuto.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/CDSCompressedKPtrs/XShareAuto.java Wed Dec 18 06:06:52 2013 -0800 @@ -22,6 +22,7 @@ */ /* + * @ignore 8026154 * @test * @bug 8005933 * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server. diff -r f76593e3fedb -r 163b418ec095 test/runtime/InitialThreadOverflow/testme.sh --- a/test/runtime/InitialThreadOverflow/testme.sh Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/InitialThreadOverflow/testme.sh Wed Dec 18 06:06:52 2013 -0800 @@ -21,6 +21,7 @@ # or visit www.oracle.com if you need additional information or have any # questions. +# @ignore 8029139 # @test testme.sh # @bug 8009062 # @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 diff -r f76593e3fedb -r 163b418ec095 test/runtime/LoadClass/LoadClassNegative.java --- a/test/runtime/LoadClass/LoadClassNegative.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/LoadClass/LoadClassNegative.java Wed Dec 18 06:06:52 2013 -0800 @@ -22,6 +22,7 @@ */ /* + * @ignore 8028095 * @test * @key regression * @bug 8020675 diff -r f76593e3fedb -r 163b418ec095 test/runtime/XCheckJniJsig/XCheckJSig.java --- a/test/runtime/XCheckJniJsig/XCheckJSig.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/XCheckJniJsig/XCheckJSig.java Wed Dec 18 06:06:52 2013 -0800 @@ -22,6 +22,7 @@ */ /* + * @ignore 8023735 * @test * @bug 7051189 8023393 * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so diff -r f76593e3fedb -r 163b418ec095 test/runtime/jsig/Test8017498.sh --- a/test/runtime/jsig/Test8017498.sh Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/jsig/Test8017498.sh Wed Dec 18 06:06:52 2013 -0800 @@ -24,6 +24,7 @@ # ## +## @ignore 8028806 ## @test Test8017498.sh ## @bug 8017498 ## @bug 8020791 diff -r f76593e3fedb -r 163b418ec095 test/runtime/memory/ReadFromNoaccessArea.java --- a/test/runtime/memory/ReadFromNoaccessArea.java Wed Dec 18 03:16:17 2013 -0800 +++ b/test/runtime/memory/ReadFromNoaccessArea.java Wed Dec 18 06:06:52 2013 -0800 @@ -22,6 +22,7 @@ */ /* + * @ignore 8028398 * @test * @summary Test that touching noaccess area in class ReservedHeapSpace results in SIGSEGV/ACCESS_VIOLATION * @library /testlibrary /testlibrary/whitebox