Mercurial > hg > truffle
changeset 19944:f73a6e260e0c
Merge
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Wed, 18 Mar 2015 10:07:47 -0700 |
parents | 6a0692faf9fd (diff) ed3e144ced29 (current diff) |
children | efa840053649 b3a2e8e564ad |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARCScratchRegister.java |
diffstat | 10 files changed, 260 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Wed Mar 18 16:39:06 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Wed Mar 18 10:07:47 2015 -0700 @@ -53,13 +53,9 @@ @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess; - public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length) { + public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length, @ConstantNodeParameter Kind kind) { super(TYPE, StampFactory.forKind(Kind.Boolean)); - // Ignore nullness in stamp equality test - assert array1.stamp().join(StampFactory.objectNonNull()).equals(array2.stamp().join(StampFactory.objectNonNull())); - ObjectStamp array1Stamp = (ObjectStamp) array1.stamp(); - ResolvedJavaType componentType = array1Stamp.type().getComponentType(); - this.kind = componentType.getKind(); + this.kind = kind; this.array1 = array1; this.array2 = array2; this.length = length; @@ -109,28 +105,39 @@ } @NodeIntrinsic - public static native boolean equals(boolean[] array1, boolean[] array2, int length); + public static native boolean equals(Object array1, Object array2, int length, @ConstantNodeParameter Kind kind); - @NodeIntrinsic - public static native boolean equals(byte[] array1, byte[] array2, int length); + public static boolean equals(boolean[] array1, boolean[] array2, int length) { + return equals(array1, array2, length, Kind.Boolean); + } - @NodeIntrinsic - public static native boolean equals(char[] array1, char[] array2, int length); + public static boolean equals(byte[] array1, byte[] array2, int length) { + return equals(array1, array2, length, Kind.Byte); + } - @NodeIntrinsic - public static native boolean equals(short[] array1, short[] array2, int length); + public static boolean equals(char[] array1, char[] array2, int length) { + return equals(array1, array2, length, Kind.Char); + } - @NodeIntrinsic - public static native boolean equals(int[] array1, int[] array2, int length); + public static boolean equals(short[] array1, short[] array2, int length) { + return equals(array1, array2, length, Kind.Short); + } - @NodeIntrinsic - public static native boolean equals(long[] array1, long[] array2, int length); + public static boolean equals(int[] array1, int[] array2, int length) { + return equals(array1, array2, length, Kind.Int); + } - @NodeIntrinsic - public static native boolean equals(float[] array1, float[] array2, int length); + public static boolean equals(long[] array1, long[] array2, int length) { + return equals(array1, array2, length, Kind.Long); + } - @NodeIntrinsic - public static native boolean equals(double[] array1, double[] array2, int length); + public static boolean equals(float[] array1, float[] array2, int length) { + return equals(array1, array2, length, Kind.Float); + } + + public static boolean equals(double[] array1, double[] array2, int length) { + return equals(array1, array2, length, Kind.Double); + } @Override public void generate(NodeLIRBuilderTool gen) {
--- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java Wed Mar 18 10:07:47 2015 -0700 @@ -45,6 +45,7 @@ System.out.println(" -e: sort events by elapsed time"); System.out.println(" -n: sort events by name and start"); System.out.println(" -L: print eliminated locks"); + System.out.println(" -Q: print compile queue activity"); System.exit(exitcode); } @@ -54,6 +55,7 @@ boolean printInlining = false; boolean cleanup = false; boolean printEliminatedLocks = false; + boolean printCompileQueue = false; int index = 0; while (args.length > index) { @@ -80,6 +82,9 @@ } else if (args[index].equals("-L")) { printEliminatedLocks = true; index++; + } else if (args[index].equals("-Q")) { + printCompileQueue = true; + index++; } else { break; } @@ -92,32 +97,17 @@ while (index < args.length) { ArrayList<LogEvent> events = LogParser.parse(args[index], cleanup); - if (printEliminatedLocks) { - Collections.sort(events, defaultSort); - for (LogEvent e : events) { - if (e instanceof Compilation) { - Compilation c = (Compilation) e; - List<JVMState> eliminated = c.getEliminatedLocks(); - if (!eliminated.isEmpty()) { - c.print(System.out); - System.out.println(" Eliminated locks"); - for (JVMState jvms : eliminated) { - System.err.print(" "); - while (jvms != null) { - System.out.printf(" %s.%s@%d", jvms.method.getHolder().replace('/', '.'), jvms.method.getName(), jvms.bci); - jvms = jvms.outer; - } - System.out.println(); - } - } - } - } + if (printCompileQueue) { + printCompileQueue(events, System.out); + } else if (printEliminatedLocks) { + printEliminatedLocks(events, System.out, defaultSort); } else if (statistics) { printStatistics(events, System.out); } else { Collections.sort(events, defaultSort); for (LogEvent c : events) { if (c instanceof NMethod) continue; + if (c instanceof TaskEvent) continue; System.out.printf("%f ", c.getStart()); if (printInlining && c instanceof Compilation) { @@ -131,7 +121,81 @@ index++; } } + + public static void printCompileQueue(ArrayList<LogEvent> events, PrintStream out) { + int[] levels = new int[5]; + HashMap<String, TaskEvent> tasks = new HashMap<String, TaskEvent>(); + + out.printf("%7s ", "Stamp"); + for (int i = 1; i <= 4; i++) { + out.printf(" Level%d", i); + } + out.printf(" %10s", "Kind"); + out.println(); + for (LogEvent e : events) { + if (e instanceof TaskEvent) { + boolean demoted = false; + TaskEvent t = (TaskEvent) e; + TaskEvent start = tasks.get(t.getId()); + switch (t.getKind()) { + case Enqueue: + assert start == null; + levels[t.getLevel()] = levels[t.getLevel()] + 1; + tasks.put(t.getId(), t); + break; + + case Finish: + case Dequeue: + if (start != null && start.getLevel() != t.getLevel()) { + // Sometimes tasks are moved to a lower + // compilation level when the queue fills. + demoted = true; + levels[start.getLevel()] = levels[start.getLevel()] - 1; + } else { + levels[t.getLevel()] = levels[t.getLevel()] - 1; + } + break; + default: + throw new InternalError(); + } + out.printf("%7.3f ", t.getStart()); + for (int i = 1; i <= 4; i++) { + out.printf(" %6d", levels[i]); + } + out.printf(" %10s", t.getKind()); + if (t.getComment() != null) { + out.printf(" %s", t.getComment()); + } + if (demoted) { + out.printf(" %d->%d", start.getLevel(), t.getLevel()); + } + out.println(); + } + } + } + public static void printEliminatedLocks(ArrayList<LogEvent> events, PrintStream out, Comparator<LogEvent> defaultSort) { + Collections.sort(events, defaultSort); + for (LogEvent e : events) { + if (e instanceof Compilation) { + Compilation c = (Compilation) e; + List<JVMState> eliminated = c.getEliminatedLocks(); + if (!eliminated.isEmpty()) { + c.print(out); + out.println(" Eliminated locks"); + for (JVMState jvms : eliminated) { + System.err.print(" "); + while (jvms != null) { + out.printf(" %s.%s@%d", jvms.method.getHolder().replace('/', '.'), jvms.method.getName(), jvms.bci); + jvms = jvms.outer; + } + out.println(); + } + } + } + } + } + public static void printStatistics(ArrayList<LogEvent> events, PrintStream out) { long cacheSize = 0; long maxCacheSize = 0;
--- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Wed Mar 18 10:07:47 2015 -0700 @@ -204,7 +204,7 @@ } } else { if (c == null) { - throw new InternalError("can't find compilation " + ble.getId() + " for " + ble); + // throw new InternalError("can't find compilation " + ble.getId() + " for " + ble); } } } @@ -363,6 +363,17 @@ scopes.peek().last().setReason(search(atts, "reason")); } else if (qname.equals("failure")) { failureReason = search(atts, "reason"); + } else if (qname.equals("task_queued")) { + String id = makeId(atts); + int level = Integer.parseInt(search(atts, "level")); + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Enqueue); + events.add(t); + } else if (qname.equals("task_dequeued")) { + String id = makeId(atts); + int level = Integer.parseInt(search(atts, "level")); + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Dequeue); + t.setComment(search(atts, "comment")); + events.add(t); } else if (qname.equals("task_done")) { compile.setEnd(Double.parseDouble(search(atts, "stamp"))); if (Integer.parseInt(search(atts, "success")) == 0) { @@ -425,6 +436,12 @@ parseLong(atts.getValue("size"))); nmethods.put(id, nm); events.add(nm); + + int level = Integer.parseInt(search(atts, "level")); + if (level > 0) { + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Finish); + events.add(t); + } } else if (qname.equals("parse")) { Method m = method(search(atts, "method")); if (scopes.size() == 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/TaskEvent.java Wed Mar 18 10:07:47 2015 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +public class TaskEvent extends BasicLogEvent { + private int level; + private String comment; + private Kind kind; + + enum Kind { + Enqueue, + Dequeue, + Finish + } + + public TaskEvent(double start, String id, int level, Kind kind) { + super(start, id); + this.level = level; + this.kind = kind; + } + + void setComment(String comment) { + this.comment = comment; + } + + String getComment() { + return comment; + } + + int getLevel() { + return level; + } + + Kind getKind() { + return kind; + } + + public void print(PrintStream stream) { + stream.printf("%s id='%s' level='%s' %s%n", start, id, level, kind); + } +}
--- a/src/share/vm/compiler/compileBroker.cpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Mar 18 10:07:47 2015 -0700 @@ -558,6 +558,24 @@ // ------------------------------------------------------------------ +// CompileTask::log_task_dequeued +void CompileTask::log_task_dequeued(const char* comment) { + if (LogCompilation && xtty != NULL) { + Thread* thread = Thread::current(); + ttyLocker ttyl; + ResourceMark rm(thread); + + xtty->begin_elem("task_dequeued"); + log_task(xtty); + if (comment != NULL) { + xtty->print(" comment='%s'", comment); + } + xtty->end_elem(); + } +} + + +// ------------------------------------------------------------------ // CompileTask::log_task_start void CompileTask::log_task_start(CompileLog* log) { log->begin_head("task"); @@ -1202,10 +1220,12 @@ blocking = false; } - // Don't allow blocking compiles if inside a class initializer + // Don't allow blocking compiles if inside a class initializer or while performing class loading vframeStream vfst((JavaThread*) thread); for (; !vfst.at_end(); vfst.next()) { - if (vfst.method()->is_static_initializer()) { + if (vfst.method()->is_static_initializer() || + (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) && + vfst.method()->name() == vmSymbols::loadClass_name())) { blocking = false; break; }
--- a/src/share/vm/compiler/compileBroker.hpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/compiler/compileBroker.hpp Wed Mar 18 10:07:47 2015 -0700 @@ -129,6 +129,7 @@ void log_task(xmlStream* log); void log_task_queued(); + void log_task_dequeued(const char* comment); void log_task_start(CompileLog* log); void log_task_done(CompileLog* log); };
--- a/src/share/vm/graal/graalCompiler.cpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Wed Mar 18 10:07:47 2015 -0700 @@ -65,6 +65,9 @@ void GraalCompiler::bootstrap() { JavaThread* THREAD = JavaThread::current(); _bootstrapping = true; + // Allow bootstrap to perform Graal compilations of itself + bool c1only = GraalCompileWithC1Only; + GraalCompileWithC1Only = false; ResourceMark rm; HandleMark hm; if (PrintBootstrap) { @@ -105,6 +108,7 @@ if (PrintBootstrap) { tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methodsCompiled); } + GraalCompileWithC1Only = c1only; _bootstrapping = false; }
--- a/src/share/vm/graal/graalGlobals.hpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/graal/graalGlobals.hpp Wed Mar 18 10:07:47 2015 -0700 @@ -82,6 +82,12 @@ product(bool, GraalHProfEnabled, false, \ "Is Heap Profiler enabled") \ \ + product(bool, GraalCompileWithC1Only, true, \ + "Only compile Graal classes with C1") \ + \ + product(bool, GraalCompileAppFirst, false, \ + "Prioritize application compilations over Graal compilations") \ + \ develop(bool, GraalUseFastLocking, true, \ "Use fast inlined locking code") \ \
--- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Mar 18 10:07:47 2015 -0700 @@ -157,6 +157,9 @@ // Called with the queue locked and with at least one element CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { +#ifdef COMPILERGRAAL + CompileTask *max_non_graal_task = NULL; +#endif CompileTask *max_task = NULL; Method* max_method = NULL; jlong t = os::javaTimeMillis(); @@ -175,6 +178,7 @@ if (PrintTieredEvents) { print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); } + task->log_task_dequeued("stale"); CompileTaskWrapper ctw(task); // Frees the task compile_queue->remove(task); method->clear_queued_for_compilation(); @@ -188,9 +192,30 @@ max_method = method; } } +#ifdef COMPILERGRAAL + if (GraalCompileAppFirst && (task->comp_level() == CompLevel_full_optimization || !method->has_compiled_code()) && + SystemDictionary::graal_loader() != NULL && + method->method_holder()->class_loader() != SystemDictionary::graal_loader()) { + if (max_non_graal_task == NULL) { + max_non_graal_task = task; + } else { + // Select a method with a higher rate + if (compare_methods(method, max_non_graal_task->method())) { + max_non_graal_task = task; + } + } + } +#endif task = next_task; } +#ifdef COMPILERGRAAL + if (max_non_graal_task != NULL) { + max_task = max_non_graal_task; + max_method = max_task->method(); + } +#endif + if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile && is_method_profiled(max_method)) { max_task->set_comp_level(CompLevel_limited_profile);
--- a/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Wed Mar 18 16:39:06 2015 +0100 +++ b/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Wed Mar 18 10:07:47 2015 -0700 @@ -55,6 +55,13 @@ // Determine if a given method is such a case. bool SimpleThresholdPolicy::is_trivial(Method* method) { if (method->is_accessor()) return true; +#ifdef COMPILERGRAAL + if (TieredCompilation && GraalCompileWithC1Only && + SystemDictionary::graal_loader() != NULL && + method->method_holder()->class_loader() == SystemDictionary::graal_loader()) { + return true; + } +#endif if (method->code() != NULL) { MethodData* mdo = method->method_data(); if (mdo != NULL && mdo->num_loops() == 0 &&