# HG changeset patch # User Michael Van De Vanter # Date 1430190070 25200 # Node ID bbc6a4347faf06d51ee037e1f9e246d256ad4dfe # Parent fc6fd02ecf957010db99bb02cb50460b314860db# Parent b95deaa6ebf6100bb5a95ab25b2fdc6b9ef5f420 Merge with b95deaa6ebf6100bb5a95ab25b2fdc6b9ef5f420 diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderConfiguration.java Mon Apr 27 20:01:10 2015 -0700 @@ -34,6 +34,7 @@ private final InvocationPlugins invocationPlugins; private LoadFieldPlugin loadFieldPlugin; private LoadIndexedPlugin loadIndexedPlugin; + private TypeCheckPlugin typeCheckPlugin; private ParameterPlugin parameterPlugin; private InlineInvokePlugin inlineInvokePlugin; private GenericInvocationPlugin genericInvocationPlugin; @@ -49,6 +50,7 @@ this.parameterPlugin = copyFrom.parameterPlugin; this.loadFieldPlugin = copyFrom.loadFieldPlugin; this.loadIndexedPlugin = copyFrom.loadIndexedPlugin; + this.typeCheckPlugin = copyFrom.typeCheckPlugin; this.inlineInvokePlugin = copyFrom.inlineInvokePlugin; this.loopExplosionPlugin = copyFrom.loopExplosionPlugin; this.genericInvocationPlugin = copyFrom.genericInvocationPlugin; @@ -92,6 +94,14 @@ this.loadIndexedPlugin = plugin; } + public TypeCheckPlugin getTypeCheckPlugin() { + return typeCheckPlugin; + } + + public void setTypeCheckPlugin(TypeCheckPlugin typeCheckPlugin) { + this.typeCheckPlugin = typeCheckPlugin; + } + public ParameterPlugin getParameterPlugin() { return parameterPlugin; } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/TypeCheckPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/TypeCheckPlugin.java Mon Apr 27 20:01:10 2015 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graphbuilderconf; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +public interface TypeCheckPlugin extends GraphBuilderPlugin { + /** + * Intercept the parsing of a CHECKCAST bytecode. If the method returns true, it must push + * {@link GraphBuilderContext#push push} an object value as the result of the cast. + * + * @param b The context. + * @param object The object to be type checked. + * @param type The type that the object is checked against. + * @param profile The profiling information for the type check, or null if no profiling + * information is available. + * @return True if the plugin handled the cast, false if the bytecode parser should handle the + * cast. + */ + default boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) { + return false; + } + + /** + * Intercept the parsing of a INSTANCEOF bytecode. If the method returns true, it must push + * {@link GraphBuilderContext#push push} an integer value with the result of the instanceof. + * + * @param b The context. + * @param object The object to be type checked. + * @param type The type that the object is checked against. + * @param profile The profiling information for the type check, or null if no profiling + * information is available. + * @return True if the plugin handled the instanceof, false if the bytecode parser should handle + * the instanceof. + */ + default boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) { + return false; + } +} diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java Mon Apr 27 20:01:10 2015 -0700 @@ -111,6 +111,11 @@ public void write(int b) throws IOException { write(new byte[]{(byte) b}, 0, 1); } + + @Override + public void flush() throws IOException { + compilerToVM.flushDebugOutput(); + } }; ps = new PrintStream(ttyOut); } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Apr 27 20:01:10 2015 -0700 @@ -387,4 +387,6 @@ boolean shouldDebugNonSafepoints(); void writeDebugOutput(byte[] bytes, int offset, int length); + + void flushDebugOutput(); } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Apr 27 20:01:10 2015 -0700 @@ -206,4 +206,6 @@ public native boolean shouldDebugNonSafepoints(); public native void writeDebugOutput(byte[] bytes, int offset, int length); + + public native void flushDebugOutput(); } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Apr 27 20:01:10 2015 -0700 @@ -74,6 +74,7 @@ plugins.setParameterPlugin(new HotSpotParameterPlugin(wordTypes)); plugins.setLoadFieldPlugin(new HotSpotLoadFieldPlugin(metaAccess, constantReflection)); plugins.setLoadIndexedPlugin(new HotSpotLoadIndexedPlugin(wordTypes)); + plugins.setTypeCheckPlugin(wordOperationPlugin); plugins.setInlineInvokePlugin(new DefaultInlineInvokePlugin(replacements)); plugins.setGenericInvocationPlugin(new DefaultGenericInvocationPlugin(metaAccess, nodeIntrinsification, wordOperationPlugin)); diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Mon Apr 27 20:01:10 2015 -0700 @@ -604,9 +604,13 @@ JavaType type = lookupType(cpi, CHECKCAST); ValueNode object = frameState.apop(); if (type instanceof ResolvedJavaType) { - JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type); - ValueNode checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false)); - frameState.apush(checkCastNode); + ResolvedJavaType resolvedType = (ResolvedJavaType) type; + JavaTypeProfile profile = getProfileForTypeCheck(resolvedType); + TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin(); + if (typeCheckPlugin == null || !typeCheckPlugin.checkCast((GraphBuilderContext) this, object, resolvedType, profile)) { + ValueNode checkCastNode = append(createCheckCast(resolvedType, object, profile, false)); + frameState.apush(checkCastNode); + } } else { handleUnresolvedCheckCast(type, object); } @@ -622,8 +626,12 @@ ValueNode object = frameState.apop(); if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; - ValueNode instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); - frameState.ipush(append(genConditional(genUnique(instanceOfNode)))); + JavaTypeProfile profile = getProfileForTypeCheck(resolvedType); + TypeCheckPlugin typeCheckPlugin = this.graphBuilderConfig.getPlugins().getTypeCheckPlugin(); + if (typeCheckPlugin == null || !typeCheckPlugin.instanceOf((GraphBuilderContext) this, object, resolvedType, profile)) { + ValueNode instanceOfNode = createInstanceOf(resolvedType, object, profile); + frameState.ipush(append(genConditional(genUnique(instanceOfNode)))); + } } else { handleUnresolvedInstanceOf(type, object); } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Mon Apr 27 20:01:10 2015 -0700 @@ -427,7 +427,7 @@ } public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) { - BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()), invoke.asNode().graph().method(), invoke.bci()); + BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()).getCaller(), invoke.asNode().graph().method(), invoke.bci()); infopointNode.addCaller(pos); return pos; } diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Mon Apr 27 20:01:10 2015 -0700 @@ -110,6 +110,20 @@ } } + @Test + public void testCast() { + test("cast", 1234L); + } + + @Snippet + public static long cast(long input) { + WordBase base = Word.signed(input); + Unsigned unsigned = (Unsigned) base; + Pointer pointer = (Pointer) unsigned; + Word word = (Word) pointer; + return word.rawValue(); + } + @Snippet public static long unsignedLong(long word) { return Word.unsigned(word).rawValue(); diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Mon Apr 27 20:01:10 2015 -0700 @@ -43,9 +43,10 @@ import com.oracle.graal.word.nodes.*; /** - * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}. + * A {@link GenericInvocationPlugin} for calls to {@linkplain Operation word operations}, and a + * {@link TypeCheckPlugin} to handle casts between word types. */ -public class WordOperationPlugin implements GenericInvocationPlugin { +public class WordOperationPlugin implements GenericInvocationPlugin, TypeCheckPlugin { protected final WordTypes wordTypes; protected final Kind wordKind; protected final SnippetReflectionProvider snippetReflection; @@ -71,6 +72,32 @@ return true; } + @Override + public boolean checkCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) { + if (!wordTypes.isWord(type)) { + if (object.getKind() != Kind.Object) { + throw b.bailout("Cannot cast a word value to a non-word type: " + type.toJavaName(true)); + } + return false; + } + + if (object.getKind() != wordTypes.getWordKind()) { + throw b.bailout("Cannot cast a non-word value to a word type: " + type.toJavaName(true)); + } + b.push(Kind.Object, object); + return true; + } + + @Override + public boolean instanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) { + if (wordTypes.isWord(type)) { + throw b.bailout("Cannot use instanceof for word a type: " + type.toJavaName(true)); + } else if (object.getKind() != Kind.Object) { + throw b.bailout("Cannot use instanceof on a word value: " + type.toJavaName(true)); + } + return false; + } + protected void processWordOperation(GraphBuilderContext b, ValueNode[] args, ResolvedJavaMethod wordMethod) throws GraalInternalError { Operation operation = wordMethod.getAnnotation(Word.Operation.class); Kind returnKind = wordMethod.getSignature().getReturnKind(); diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Apr 27 20:01:10 2015 -0700 @@ -89,8 +89,11 @@ ReadCacheEntry identifier = new ReadCacheEntry(object, read.location()); ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null && read.stamp().isCompatible(cachedValue.stamp())) { + // Anchor guard if it is not fixed and different from cachedValue's guard if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) { - effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read); + if (!(cachedValue instanceof GuardedNode) || ((GuardedNode) cachedValue).getGuard() != read.getGuard()) { + effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read); + } } effects.replaceAtUsages(read, cachedValue); addScalarAlias(read, cachedValue); diff -r fc6fd02ecf95 -r bbc6a4347faf graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java Sun Apr 26 20:50:30 2015 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java Mon Apr 27 20:01:10 2015 -0700 @@ -41,10 +41,16 @@ super(src); } - @Specialization - protected long div(long left, long right) { - /* No overflow is possible on a division. */ - return left / right; + @Specialization(rewriteOn = ArithmeticException.class) + protected long div(long left, long right) throws ArithmeticException { + long result = left / right; + /* + * The division overflows if left is Long.MIN_VALUE and right is -1. + */ + if ((left & right & result) < 0) { + throw new ArithmeticException("long overflow"); + } + return result; } @Specialization diff -r fc6fd02ecf95 -r bbc6a4347faf mx/mx_graal.py --- a/mx/mx_graal.py Sun Apr 26 20:50:30 2015 -0700 +++ b/mx/mx_graal.py Mon Apr 27 20:01:10 2015 -0700 @@ -601,6 +601,8 @@ def _classifyGraalServices(classNames, graalJars): classification = {} + if not classNames: + return classification for className in classNames: classification[className] = None javap = mx.java().javap @@ -680,14 +682,17 @@ assert serviceName and member == 'META-INF/services/' + serviceName with zf.open(member) as serviceFile: serviceImpls = servicesMap.setdefault(serviceName, []) - serviceImpls.extend(serviceFile.readlines()) + for line in serviceFile.readlines(): + line = line.strip() + if line: + serviceImpls.append(line) graalServices = _filterGraalService(servicesMap.keys(), graalJars) for serviceName in graalServices: serviceImpls = servicesMap[serviceName] fd, tmp = tempfile.mkstemp(prefix=serviceName) f = os.fdopen(fd, 'w+') for serviceImpl in serviceImpls: - f.write(serviceImpl.rstrip() + os.linesep) + f.write(serviceImpl + os.linesep) target = join(destination, serviceName) f.close() shutil.move(tmp, target) diff -r fc6fd02ecf95 -r bbc6a4347faf src/cpu/sparc/vm/graalGlobals_sparc.hpp --- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp Sun Apr 26 20:50:30 2015 -0700 +++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp Mon Apr 27 20:01:10 2015 -0700 @@ -60,4 +60,6 @@ define_pd_global(intx, MethodProfileWidth, 0); #endif // COMPILERGRAAL +define_pd_global(intx, MaxVectorSize, 8); + #endif // CPU_SPARC_VM_GRAALGLOBALS_SPARC_HPP diff -r fc6fd02ecf95 -r bbc6a4347faf src/cpu/x86/vm/graalGlobals_x86.hpp --- a/src/cpu/x86/vm/graalGlobals_x86.hpp Sun Apr 26 20:50:30 2015 -0700 +++ b/src/cpu/x86/vm/graalGlobals_x86.hpp Mon Apr 27 20:01:10 2015 -0700 @@ -60,4 +60,6 @@ define_pd_global(intx, MethodProfileWidth, 0); #endif // COMPILERGRAAL +define_pd_global(intx, MaxVectorSize, 32); + #endif // CPU_X86_VM_GRAALGLOBALS_X86_HPP diff -r fc6fd02ecf95 -r bbc6a4347faf src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Sun Apr 26 20:50:30 2015 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Apr 27 20:01:10 2015 -0700 @@ -1019,6 +1019,10 @@ } C2V_END +C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject)) + tty->flush(); +C2V_END + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1099,6 +1103,7 @@ {CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)}, {CC"shouldDebugNonSafepoints", CC"()Z", FN_PTR(shouldDebugNonSafepoints)}, {CC"writeDebugOutput", CC"([BII)V", FN_PTR(writeDebugOutput)}, + {CC"flushDebugOutput", CC"()V", FN_PTR(flushDebugOutput)}, }; int CompilerToVM_methods_count() { diff -r fc6fd02ecf95 -r bbc6a4347faf src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Sun Apr 26 20:50:30 2015 -0700 +++ b/src/share/vm/graal/graalGlobals.hpp Mon Apr 27 20:01:10 2015 -0700 @@ -67,7 +67,7 @@ GRAAL_ONLY(product(bool, CodeInstallSafepointChecks, true, \ "Perform explicit safepoint checks while installing code")) \ \ - NOT_COMPILER2(product(intx, MaxVectorSize, 32, \ + NOT_COMPILER2(product_pd(intx, MaxVectorSize, \ "Max vector size in bytes, " \ "actual size could be less depending on elements type")) \ \ diff -r fc6fd02ecf95 -r bbc6a4347faf src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Sun Apr 26 20:50:30 2015 -0700 +++ b/src/share/vm/graal/graalRuntime.cpp Mon Apr 27 20:01:10 2015 -0700 @@ -1099,19 +1099,43 @@ GrowableArray* implNames = new GrowableArray(); char* line = buffer; while (line - buffer < num_read) { - char* nl = strchr(line, '\n'); - if (nl != NULL) { - *nl = '\0'; + // find line end (\r, \n or \r\n) + char* nextline = NULL; + char* cr = strchr(line, '\r'); + char* lf = strchr(line, '\n'); + if (cr != NULL && lf != NULL) { + char* min = MIN2(cr, lf); + *min = '\0'; + if (lf == cr + 1) { + nextline = lf + 1; + } else { + nextline = min + 1; + } + } else if (cr != NULL) { + *cr = '\0'; + nextline = cr + 1; + } else if (lf != NULL) { + *lf = '\0'; + nextline = lf + 1; } - // Turn all '.'s into '/'s - for (size_t index = 0; line[index] != '\0'; index++) { - if (line[index] == '.') { - line[index] = '/'; + // trim left + while (*line == ' ' || *line == '\t') line++; + char* end = line + strlen(line); + // trim right + while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--; + *end = '\0'; + // skip comments and empty lines + if (*line != '#' && strlen(line) > 0) { + // Turn all '.'s into '/'s + for (size_t index = 0; line[index] != '\0'; index++) { + if (line[index] == '.') { + line[index] = '/'; + } } + implNames->append(line); } - implNames->append(line); - if (nl != NULL) { - line = nl + 1; + if (nextline != NULL) { + line = nextline; } else { // File without newline at the end break;