8184768: Update Graal

Reviewed-by: kvn
This commit is contained in:
Igor Veresov 2017-07-17 16:31:51 -07:00
parent 040ada2f40
commit 76b7f30159
64 changed files with 1765 additions and 1406 deletions

View File

@ -100,16 +100,15 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
final long threadId = Thread.currentThread().getId();
final boolean printCompilation = GraalCompilerOptions.PrintCompilation.getValue(graalOptions) && !TTY.isSuppressed();
final boolean printAfterCompilation = GraalCompilerOptions.PrintAfterCompilation.getValue(graalOptions) && !TTY.isSuppressed();
if (printCompilation) {
TTY.println(getMethodDescription() + "...");
}
final long start;
final long allocatedBytesBefore;
if (printAfterCompilation || printCompilation) {
if (printCompilation) {
start = System.currentTimeMillis();
allocatedBytesBefore = printAfterCompilation || printCompilation ? threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
allocatedBytesBefore = printCompilation ? threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
} else {
start = 0L;
allocatedBytesBefore = 0L;
@ -123,7 +122,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
}
final long endTime = System.currentTimeMillis();
if (printAfterCompilation || printCompilation) {
if (printCompilation) {
final long stop = System.currentTimeMillis();
final int targetCodeSize = compResult != null ? compResult.getTargetCodeSize() : -1;
final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId);

View File

@ -91,4 +91,31 @@ public class DeoptimizeDirectiveTest extends GraalCompilerTest {
boolean valid = testDeoptimizeCheckValid(method);
Assert.assertTrue("code should still be valid", valid);
}
public static int zeroBranchProbabilitySnippet(boolean flag) {
if (GraalDirectives.injectBranchProbability(0, flag)) {
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
return 1;
} else {
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
return 2;
}
}
@Test
public void testZeroBranchProbability() {
ResolvedJavaMethod method = getResolvedJavaMethod("zeroBranchProbabilitySnippet");
Result expected = executeExpected(method, null, true);
InstalledCode code = getCode(method);
Result actual;
try {
actual = new Result(code.executeVarargs(true), null);
} catch (Exception e) {
actual = new Result(null, e);
}
assertEquals(expected, actual);
assertFalse("code should be invalidated", code.isValid());
}
}

View File

@ -85,6 +85,11 @@ public class AArch64MoveFactory implements MoveFactory {
}
}
@Override
public LIRInstruction createStackLoad(AllocatableValue result, Constant input) {
return createLoad(result, input);
}
@Override
public boolean canInlineConstant(Constant con) {
if (con instanceof JavaConstant) {

View File

@ -23,16 +23,18 @@
package org.graalvm.compiler.core.amd64;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64StackMove;
import org.graalvm.compiler.lir.amd64.AMD64Move.LeaDataOp;
import org.graalvm.compiler.lir.amd64.AMD64Move.LeaOp;
@ -69,6 +71,17 @@ public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
return false;
}
@Override
public boolean allowConstantToStackMove(Constant constant) {
if (constant instanceof DataPointerConstant) {
return false;
}
if (constant instanceof JavaConstant && !AMD64Move.canMoveConst2Stack(((JavaConstant) constant))) {
return false;
}
return true;
}
@Override
public AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
if (src instanceof AMD64AddressValue) {
@ -97,4 +110,13 @@ public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
throw GraalError.shouldNotReachHere(String.format("unsupported constant: %s", src));
}
}
@Override
public LIRInstruction createStackLoad(AllocatableValue result, Constant input) {
if (input instanceof JavaConstant) {
return new MoveFromConstOp(result, (JavaConstant) input);
} else {
throw GraalError.shouldNotReachHere(String.format("unsupported constant for stack load: %s", input));
}
}
}

View File

@ -36,8 +36,8 @@ public class RetryableBailoutException extends BailoutException {
super(false, reason);
}
public RetryableBailoutException(Throwable cause, String format) {
super(cause, format);
public RetryableBailoutException(Throwable cause, String format, Object... args) {
super(cause, format, args);
}
}

View File

@ -90,6 +90,14 @@ public class SPARCMoveFactory implements MoveFactory {
}
}
@Override
public LIRInstruction createStackLoad(AllocatableValue result, Constant input) {
if (input instanceof DataPointerConstant) {
throw GraalError.shouldNotReachHere("unsupported constant for stack load: " + input);
}
return createLoad(result, input);
}
@Override
public boolean canInlineConstant(Constant con) {
if (con instanceof JavaConstant) {

View File

@ -183,6 +183,13 @@ public class CheckGraalInvariants extends GraalCompilerTest {
String name = zipEntry.getName();
if (name.endsWith(".class")) {
String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
if (isInNativeImage(className)) {
/*
* Native Image is an external tool and does not need to follow the
* Graal invariants.
*/
continue;
}
classNames.add(className);
}
}
@ -293,6 +300,10 @@ public class CheckGraalInvariants extends GraalCompilerTest {
}
}
private static boolean isInNativeImage(String className) {
return className.startsWith("org.graalvm.nativeimage");
}
private static List<Class<?>> initializeClasses(InvariantsTool tool, List<String> classNames) {
List<Class<?>> classes = new ArrayList<>(classNames.size());
for (String className : classNames) {

View File

@ -22,7 +22,7 @@
*/
package org.graalvm.compiler.core.test;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintCompilation;
import static jdk.vm.ci.runtime.JVMCICompiler.INVOCATION_ENTRY_BCI;
import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
@ -51,15 +51,16 @@ import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.CompilationPrinter;
import org.graalvm.compiler.core.GraalCompiler;
import org.graalvm.compiler.core.GraalCompiler.Request;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpHandler;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.graph.Node;
@ -941,16 +942,9 @@ public abstract class GraalCompilerTest extends GraalTest {
StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner, id, options) : graph;
DebugContext debug = graphToCompile.getDebug();
try (AllocSpy spy = AllocSpy.open(installedCodeOwner); DebugContext.Scope ds = debug.scope("Compiling", new DebugDumpScope(id.toString(CompilationIdentifier.Verbosity.ID), true))) {
final boolean printCompilation = PrintCompilation.getValue(options) && !TTY.isSuppressed();
if (printCompilation) {
TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s ...", id, installedCodeOwner.getDeclaringClass().getName(), installedCodeOwner.getName(),
installedCodeOwner.getSignature()));
}
long start = System.currentTimeMillis();
CompilationPrinter printer = CompilationPrinter.begin(options, id, installedCodeOwner, INVOCATION_ENTRY_BCI);
CompilationResult compResult = compile(installedCodeOwner, graphToCompile, new CompilationResult(), id, options);
if (printCompilation) {
TTY.println(String.format("@%-6s Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
}
printer.finish(compResult);
try (DebugContext.Scope s = debug.scope("CodeInstall", getCodeCache(), installedCodeOwner, compResult);
DebugContext.Activation a = debug.activate()) {

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.DebugContext.Scope;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Assert;
import org.junit.Test;
public class GraphResetDebugTest extends GraalCompilerTest {
public static void testSnippet() {
}
@SuppressWarnings("try")
@Test
public void test1() {
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
// Configure with an option that enables scopes
map.put(DebugOptions.DumpOnError, true);
DebugContext debug = getDebugContext(new OptionValues(map));
StructuredGraph graph = parseEager("testSnippet", AllowAssumptions.YES, debug);
boolean resetSucceeded = false;
try (Scope scope = debug.scope("some scope")) {
graph.resetDebug(DebugContext.DISABLED);
resetSucceeded = true;
} catch (AssertionError expected) {
}
Assert.assertFalse(resetSucceeded);
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintCompilation;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.debug.Management;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.runtime.JVMCICompiler;
/**
* Utility for printing an informational line to {@link TTY} upon completion of compiling a method.
*/
public final class CompilationPrinter {
private final CompilationIdentifier id;
private final JavaMethod method;
private final int entryBCI;
private final long start;
private final long allocatedBytesBefore;
/**
* Gets an object that will report statistics for a compilation if
* {@link GraalCompilerOptions#PrintCompilation} is enabled and {@link TTY} is not suppressed.
* This method should be called just before a compilation starts as it captures pre-compilation
* data for the purpose of {@linkplain #finish(CompilationResult) printing} the post-compilation
* statistics.
*
* @param options used to get the value of {@link GraalCompilerOptions#PrintCompilation}
* @param id the identifier for the compilation
* @param method the method for which code is being compiled
* @param entryBCI the BCI at which compilation starts
*/
public static CompilationPrinter begin(OptionValues options, CompilationIdentifier id, JavaMethod method, int entryBCI) {
if (PrintCompilation.getValue(options) && !TTY.isSuppressed()) {
return new CompilationPrinter(id, method, entryBCI);
}
return DISABLED;
}
private static final CompilationPrinter DISABLED = new CompilationPrinter();
private CompilationPrinter() {
this.method = null;
this.id = null;
this.entryBCI = -1;
this.start = -1;
this.allocatedBytesBefore = -1;
}
private CompilationPrinter(CompilationIdentifier id, JavaMethod method, int entryBCI) {
this.method = method;
this.id = id;
this.entryBCI = entryBCI;
final long threadId = Thread.currentThread().getId();
start = System.nanoTime();
allocatedBytesBefore = getAllocatedBytes(threadId);
}
private String getMethodDescription() {
return String.format("%-30s %-70s %-45s %-50s %s", id.toString(CompilationIdentifier.Verbosity.ID),
method.getDeclaringClass().getName(), method.getName(),
method.getSignature().toMethodDescriptor(),
entryBCI == JVMCICompiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ");
}
/**
* Notifies this object that the compilation finished and the informational line should be
* printed to {@link TTY}.
*/
public void finish(CompilationResult result) {
if (id != null) {
final long threadId = Thread.currentThread().getId();
final long stop = System.nanoTime();
final long duration = (stop - start) / 1000000;
final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1;
final int bytecodeSize = result != null ? result.getBytecodeSize() : 0;
final long allocatedBytesAfter = getAllocatedBytes(threadId);
final long allocatedKBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB %5dkB", duration, bytecodeSize, targetCodeSize, allocatedKBytes));
}
}
static com.sun.management.ThreadMXBean threadMXBean;
static long getAllocatedBytes(long threadId) {
if (threadMXBean == null) {
threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
}
return threadMXBean.getThreadAllocatedBytes(threadId);
}
}

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
import static org.graalvm.compiler.debug.DebugOptions.Dump;
import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.PathUtilities;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.options.EnumOptionKey;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.BailoutException;
/**
* Wrapper for a compilation that centralizes what action to take based on
* {@link GraalCompilerOptions#CompilationBailoutAction} and
* {@link GraalCompilerOptions#CompilationFailureAction} when an uncaught exception occurs during
* compilation.
*/
public abstract class CompilationWrapper<T> {
/**
* Actions to take upon an exception being raised during compilation performed via
* {@link CompilationWrapper}. The actions are with respect to what the user sees on the
* console. The compilation requester determines what ultimate action is taken in
* {@link CompilationWrapper#handleException(Throwable)}.
*/
public enum ExceptionAction {
/**
* Print nothing to the console.
*/
Silent,
/**
* Print a stack trace to the console.
*/
Print,
/**
* An exception causes the compilation to be retried with extra diagnostics enabled.
*/
Diagnose,
/**
* Same as {@link #Diagnose} except that the VM process is exited after retrying.
*/
ExitVM;
static ValueHelp HELP = new ValueHelp();
static class ValueHelp implements EnumOptionKey.ValueHelp<ExceptionAction> {
@Override
public String getHelp(Object value) {
ExceptionAction action = (ExceptionAction) value;
switch (action) {
case Silent:
return action + ": Print nothing to the console.";
case Print:
return action + ": Print a stack trace to the console.";
case Diagnose:
return action + ": Retry the compilation with extra diagnostics.";
case ExitVM:
return action + ": Same as " + Diagnose + " except that the VM process exits after retrying.";
}
return null;
}
}
}
private final DiagnosticsOutputDirectory outputDirectory;
/**
* @param outputDirectory object used to access a directory for dumping if the compilation is
* re-executed
*/
public CompilationWrapper(DiagnosticsOutputDirectory outputDirectory) {
this.outputDirectory = outputDirectory;
}
/**
* Handles an uncaught exception.
*
* @param t an exception thrown during {@link #run(DebugContext)}
* @return a value representing the result of a failed compilation (may be {@code null})
*/
protected abstract T handleException(Throwable t);
/**
* Gets the action to take based on the value of {@code actionKey} in {@code options}.
*
* Subclasses can override this to choose a different action based on factors such as whether
* {@code actionKey} has been explicitly set in {@code options} for example.
*/
protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey) {
if (actionKey == CompilationFailureAction) {
if (ExitVMOnException.getValue(options)) {
assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
assert ExitVMOnException.getDefaultValue() != true;
if (CompilationFailureAction.hasBeenSet(options) && CompilationFailureAction.getValue(options) != ExceptionAction.ExitVM) {
TTY.printf("WARNING: Ignoring %s=%s since %s=true has been explicitly specified.%n",
CompilationFailureAction.getName(), CompilationFailureAction.getValue(options),
ExitVMOnException.getName());
}
return ExceptionAction.ExitVM;
}
}
return actionKey.getValue(options);
}
/**
* Perform the compilation wrapped by this object.
*
* @param debug the debug context to use for the compilation
*/
protected abstract T performCompilation(DebugContext debug);
/**
* Gets a value that represents the input to the compilation.
*/
@Override
public abstract String toString();
/**
* Creates the {@link DebugContext} to use when retrying a compilation.
*
* @param options the options for configuring the debug context
*/
protected abstract DebugContext createRetryDebugContext(OptionValues options);
@SuppressWarnings("try")
public final T run(DebugContext initialDebug) {
try {
return performCompilation(initialDebug);
} catch (Throwable cause) {
OptionValues initialOptions = initialDebug.getOptions();
String causeType = "failure";
EnumOptionKey<ExceptionAction> actionKey;
if (cause instanceof BailoutException) {
actionKey = CompilationBailoutAction;
causeType = "bailout";
} else {
actionKey = CompilationFailureAction;
causeType = "failure";
}
ExceptionAction action = lookupAction(initialOptions, actionKey);
if (action == ExceptionAction.Silent) {
return handleException(cause);
}
if (action == ExceptionAction.Print) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
cause.printStackTrace(ps);
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Silent,
actionKey.getName(), ExceptionAction.Silent);
ps.printf("To capture more information for diagnosing or reporting a compilation %s, " +
"set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Diagnose,
ExceptionAction.ExitVM,
actionKey.getName(), ExceptionAction.Diagnose);
}
synchronized (CompilationFailureAction) {
// Synchronize to prevent compilation exception
// messages from interleaving.
TTY.println(baos.toString());
}
return handleException(cause);
}
// action is Diagnose or ExitVM
if (Dump.hasBeenSet(initialOptions)) {
// If dumping is explicitly enabled, Graal is being debugged
// so don't interfere with what the user is expecting to see.
return handleException(cause);
}
String dir = this.outputDirectory.getPath();
if (dir == null) {
return null;
}
String dumpName = PathUtilities.sanitizeFileName(toString());
File dumpPath = new File(dir, dumpName);
dumpPath.mkdirs();
if (!dumpPath.exists()) {
TTY.println("Warning: could not create diagnostics directory " + dumpPath);
return handleException(cause);
}
String message;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos)) {
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
cause.printStackTrace(ps);
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Silent,
actionKey.getName(), ExceptionAction.Silent);
ps.printf("To print a message for a compilation %s without retrying the compilation, " +
"set %s to %s (e.g., -Dgraal.%s=%s).%n",
causeType,
actionKey.getName(), ExceptionAction.Print,
actionKey.getName(), ExceptionAction.Print);
ps.println("Retrying compilation of " + this);
message = baos.toString();
}
synchronized (CompilationFailureAction) {
// Synchronize here to serialize retry compilations. This
// mitigates retry compilation storms.
TTY.println(message);
File retryLogFile = new File(dumpPath, "retry.log");
try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
ps.print(message);
} catch (IOException ioe) {
TTY.printf("Error writing to %s: %s%n", retryLogFile, ioe);
}
OptionValues retryOptions = new OptionValues(initialOptions,
Dump, ":" + VERBOSE_LEVEL,
MethodFilter, null,
DumpPath, dumpPath.getPath());
try (DebugContext retryDebug = createRetryDebugContext(retryOptions)) {
return performCompilation(retryDebug);
} catch (Throwable ignore) {
// Failures during retry are silent
return handleException(cause);
} finally {
if (action == ExitVM) {
synchronized (ExceptionAction.class) {
TTY.println("Exiting VM after retry compilation of " + this);
System.exit(-1);
}
}
}
}
}
}
}

View File

@ -22,6 +22,8 @@
*/
package org.graalvm.compiler.core;
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
import org.graalvm.compiler.options.EnumOptionKey;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
@ -32,22 +34,16 @@ import org.graalvm.compiler.options.OptionType;
public class GraalCompilerOptions {
// @formatter:off
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<String> PrintFilter = new OptionKey<>(null);
@Option(help = "", type = OptionType.Debug)
@Option(help = "Print an informational line to the console for each completed compilation.", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintCompilation = new OptionKey<>(false);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintAfterCompilation = new OptionKey<>(false);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintBailout = new OptionKey<>(false);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> ExitVMOnBailout = new OptionKey<>(false);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> PrintStackTraceOnException = new OptionKey<>(false);
@Option(help = "Pattern (see MethodFilter for format) for method that will trigger an exception when compiled. " +
"This option exists to test handling compilation crashes gracefully.", type = OptionType.Debug)
public static final OptionKey<String> CrashAt = new OptionKey<>(null);
@Option(help = "Specifies the action to take when compilation fails with a non-bailout exception.", type = OptionType.User)
public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose, ExceptionAction.HELP);
@Option(help = "Specifies the action to take when compilation fails with a bailout exception.", type = OptionType.User)
public static final EnumOptionKey<ExceptionAction> CompilationBailoutAction = new EnumOptionKey<>(ExceptionAction.Silent, ExceptionAction.HELP);
@Option(help = "Alias for CompilationFailureAction=ExitVM.", type = OptionType.Debug)
public static final OptionKey<Boolean> ExitVMOnException = new OptionKey<>(false);
// @formatter:on
}

View File

@ -712,6 +712,20 @@ public final class DebugContext implements AutoCloseable {
}
}
/**
* Determines if scopes are enabled and this context is in a non-top-level scope.
*/
public boolean inNestedScope() {
if (immutable.scopesEnabled) {
if (currentScope == null) {
// In an active DisabledScope
return true;
}
return !currentScope.isTopLevel();
}
return immutable.scopesEnabled && currentScope == null;
}
class DisabledScope implements DebugContext.Scope {
final boolean savedMetricsEnabled;
final ScopeImpl savedScope;

View File

@ -180,7 +180,7 @@ public class DebugOptions {
/**
* Gets the directory in which {@link DebugDumpHandler}s can generate output. This will be the
* directory specified by {@link #DumpPath} if it has been set otherwise it will be derived from
* the default value of {@link #DumpPath} and {@link UniquePathUtilities#getGlobalTimeStamp()}.
* the default value of {@link #DumpPath} and {@link PathUtilities#getGlobalTimeStamp()}.
*
* This method will ensure the returned directory exists, printing a message to {@link TTY} if
* it creates it.
@ -193,13 +193,14 @@ public class DebugOptions {
if (DumpPath.hasBeenSet(options)) {
dumpDir = Paths.get(DumpPath.getValue(options));
} else {
dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(UniquePathUtilities.getGlobalTimeStamp()));
dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(PathUtilities.getGlobalTimeStamp()));
}
dumpDir = dumpDir.toAbsolutePath();
if (!Files.exists(dumpDir)) {
synchronized (DebugConfigImpl.class) {
if (!Files.exists(dumpDir)) {
Files.createDirectories(dumpDir);
TTY.println("Dumping debug output in %s", dumpDir.toAbsolutePath().toString());
TTY.println("Dumping debug output in %s", dumpDir.toString());
}
}
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.debug;
/**
* A mechanism for re-executing a task upon failure.
*/
public abstract class DebugRetryableTask<T> {
/**
* Calls {@link #run} on this task and if it results in an exception, calls
* {@link #getRetryContext} and if that returns a non-null value,
* {@link #run(DebugContext, Throwable)} is called with it.
*
* @param initialDebug the debug context to be used for the initial execution
*/
@SuppressWarnings("try")
public final T runWithRetry(DebugContext initialDebug) {
try {
return run(initialDebug, null);
} catch (Throwable t) {
DebugContext retryDebug = getRetryContext(initialDebug, t);
if (retryDebug != null) {
return run(retryDebug, t);
} else {
throw t;
}
}
}
/**
* Runs this body of this task.
*
* @param debug the debug context to use for the execution
* @param failure {@code null} if this is the first execution otherwise the cause of the first
* execution to fail
*/
protected abstract T run(DebugContext debug, Throwable failure);
/**
* Notifies this object that the initial execution failed with exception {@code t} and requests
* a debug context to be used for re-execution.
*
* @param initialDebug the debug context used for the initial execution
* @param t an exception that terminated the first execution of this task
* @return the debug context to be used for re-executing this task or {@code null} if {@code t}
* should immediately be re-thrown without re-executing this task
*/
protected DebugContext getRetryContext(DebugContext initialDebug, Throwable t) {
return null;
}
}

View File

@ -0,0 +1,191 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.debug;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.graalvm.compiler.options.OptionValues;
/**
* Manages a directory into which diagnostics such crash reports and dumps should be written. The
* directory is archived and deleted when {@link #close()} is called.
*/
public class DiagnosticsOutputDirectory {
/**
* Use an illegal file name to denote that {@link #close()} has been called.
*/
private static final String CLOSED = "\u0000";
public DiagnosticsOutputDirectory(OptionValues options) {
this.options = options;
}
private final OptionValues options;
private String path;
/**
* Gets the path to the output directory managed by this object, creating if it doesn't exist
* and has not been deleted.
*
* @returns the directory or {@code null} if the could not be created or has been deleted
*/
public String getPath() {
return getPath(true);
}
/**
* Gets a unique identifier for this execution such as a process ID.
*/
protected String getExecutionID() {
String runtimeName = ManagementFactory.getRuntimeMXBean().getName();
try {
int index = runtimeName.indexOf('@');
if (index != -1) {
long pid = Long.parseLong(runtimeName.substring(0, index));
return Long.toString(pid);
}
} catch (NumberFormatException e) {
}
return runtimeName;
}
private synchronized String getPath(boolean createIfNull) {
if (path == null && createIfNull) {
path = createPath();
File dir = new File(path).getAbsoluteFile();
if (!dir.exists()) {
dir.mkdirs();
if (!dir.exists()) {
TTY.println("Warning: could not create Graal diagnostic directory " + dir);
return null;
}
}
}
return CLOSED.equals(path) ? null : path;
}
/**
* Gets the path of the directory to be created.
*
* Subclasses can override this to determine how the path name is created.
*
* @return the path to be created
*/
protected String createPath() {
Path baseDir;
try {
baseDir = DebugOptions.getDumpDirectory(options);
} catch (IOException e) {
// Default to current directory if there was a problem creating the
// directory specified by the DumpPath option.
baseDir = Paths.get(".");
}
return baseDir.resolve("graal_diagnostics_" + getExecutionID()).toAbsolutePath().toString();
}
/**
* Archives and deletes this directory if it exists.
*/
public void close() {
archiveAndDelete();
}
/**
* Archives and deletes the {@linkplain #getPath() output directory} if it exists.
*/
private synchronized void archiveAndDelete() {
String outDir = getPath(false);
if (outDir != null) {
// Notify other threads calling getPath() that the directory is deleted.
// This attempts to mitigate other threads writing to the directory
// while it is being archived and deleted.
path = CLOSED;
Path dir = Paths.get(outDir);
if (dir.toFile().exists()) {
File zip = new File(outDir + ".zip").getAbsoluteFile();
List<Path> toDelete = new ArrayList<>();
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
zos.setLevel(Deflater.BEST_COMPRESSION);
Files.walkFileTree(dir, Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (attrs.isRegularFile()) {
ZipEntry ze = new ZipEntry(file.toString());
zos.putNextEntry(ze);
zos.write(Files.readAllBytes(file));
zos.closeEntry();
}
toDelete.add(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
toDelete.add(d);
return FileVisitResult.CONTINUE;
}
});
// Keep this in sync with the catch_files in common.hocon
TTY.println("Graal diagnostic output saved in %s", zip);
} catch (IOException e) {
TTY.printf("IO error archiving %s:%n%s. The directory will not be deleted and must be " +
"manually removed once the VM exits.%n", dir, e);
toDelete.clear();
}
if (!toDelete.isEmpty()) {
IOException lastDeletionError = null;
for (Path p : toDelete) {
try {
Files.delete(p);
} catch (IOException e) {
lastDeletionError = e;
}
}
if (lastDeletionError != null) {
TTY.printf("IO error deleting %s:%n%s. This is most likely due to a compilation on " +
"another thread holding a handle to a file within this directory. " +
"Please delete the directory manually once the VM exits.%n", dir, lastDeletionError);
}
}
}
}
}
}

View File

@ -23,6 +23,7 @@
package org.graalvm.compiler.debug;
import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
@ -32,7 +33,10 @@ import java.util.concurrent.atomic.AtomicLong;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
public class UniquePathUtilities {
/**
* Miscellaneous methods for modifying and generating file system paths.
*/
public class PathUtilities {
private static final AtomicLong globalTimeStamp = new AtomicLong();
/**
@ -70,6 +74,13 @@ public class UniquePathUtilities {
return id.generateID(extension);
}
/**
* Prepends a period (i.e., {@code '.'}) to an non-null, non-empty string representation a file
* extension if the string does not already start with a period.
*
* @return {@code ext} unmodified if it is null, empty or already starts with a period other
* {@code "." + ext}
*/
public static String formatExtension(String ext) {
if (ext == null || ext.length() == 0) {
return "";
@ -77,6 +88,10 @@ public class UniquePathUtilities {
return "." + ext;
}
/**
* Gets a time stamp for the current process. This method will always return the same value for
* the current VM execution.
*/
public static long getGlobalTimeStamp() {
if (globalTimeStamp.get() == 0) {
globalTimeStamp.compareAndSet(0, System.currentTimeMillis());
@ -91,8 +106,8 @@ public class UniquePathUtilities {
*
* @return the output file path or null if the flag is null
*/
public static Path getPath(OptionValues options, OptionKey<String> option, String extension) throws IOException {
return getPath(options, option, extension, true);
public static Path getPath(OptionValues options, OptionKey<String> baseNameOption, String extension) throws IOException {
return getPath(options, baseNameOption, extension, true);
}
/**
@ -120,4 +135,31 @@ public class UniquePathUtilities {
Path dumpDir = DebugOptions.getDumpDirectory(options);
return dumpDir.resolve(name).normalize();
}
/**
* Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
* without causing an {@link InvalidPathException}.
*
* @return {@code name} with all characters invalid for the current file system replaced by
* {@code '_'}
*/
public static String sanitizeFileName(String name) {
try {
Paths.get(name);
return name;
} catch (InvalidPathException e) {
// fall through
}
StringBuilder buf = new StringBuilder(name.length());
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
try {
Paths.get(String.valueOf(c));
} catch (InvalidPathException e) {
buf.append('_');
}
buf.append(c);
}
return buf.toString();
}
}

View File

@ -165,6 +165,10 @@ public final class ScopeImpl implements DebugContext.Scope {
owner.lastClosedScope = this;
}
boolean isTopLevel() {
return parent == null;
}
public boolean isDumpEnabled(int dumpLevel) {
assert dumpLevel >= 0;
return currentDumpLevel >= dumpLevel;

View File

@ -150,7 +150,7 @@ public class Graph {
/**
* The {@link DebugContext} used while compiling this graph.
*/
private final DebugContext debug;
private DebugContext debug;
private class NodeSourcePositionScope implements DebugCloseable {
private final NodeSourcePosition previous;
@ -373,6 +373,21 @@ public class Graph {
return debug;
}
/**
* Resets the {@link DebugContext} for this graph to a new value. This is useful when a graph is
* "handed over" from its creating thread to another thread.
*
* This must only be done when the current thread is no longer using the graph. This is in
* general impossible to test due to races and since metrics can be updated at any time. As
* such, this method only performs a weak sanity check that at least the current debug context
* does not have a nested scope open (the top level scope will always be open if scopes are
* enabled).
*/
public void resetDebug(DebugContext newDebug) {
assert newDebug == debug || !debug.inNestedScope() : String.format("Cannot reset the debug context for %s while it has the nested scope \"%s\" open", this, debug.getCurrentScopeName());
this.debug = newDebug;
}
@Override
public String toString() {
return name == null ? super.toString() : "Graph " + name;

View File

@ -23,6 +23,7 @@
package org.graalvm.compiler.hotspot.amd64;
import org.graalvm.compiler.core.amd64.AMD64MoveFactory;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
@ -57,7 +58,7 @@ public class AMD64HotSpotMoveFactory extends AMD64MoveFactory {
if (value instanceof HotSpotConstant) {
return ((HotSpotConstant) value).isCompressed();
}
return true;
return super.allowConstantToStackMove(value);
}
@Override
@ -72,4 +73,19 @@ public class AMD64HotSpotMoveFactory extends AMD64MoveFactory {
return super.createLoad(dst, src);
}
}
@Override
public LIRInstruction createStackLoad(AllocatableValue dst, Constant src) {
if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(src)) {
return super.createStackLoad(dst, JavaConstant.INT_0);
} else if (src instanceof HotSpotObjectConstant) {
assert ((HotSpotConstant) src).isCompressed();
return new AMD64HotSpotMove.HotSpotLoadObjectConstantOp(dst, (HotSpotObjectConstant) src);
} else if (src instanceof HotSpotMetaspaceConstant) {
assert ((HotSpotConstant) src).isCompressed();
return new AMD64HotSpotMove.HotSpotLoadMetaspaceConstantOp(dst, (HotSpotMetaspaceConstant) src);
} else {
return super.createStackLoad(dst, src);
}
}
}

View File

@ -43,14 +43,31 @@ import org.junit.Test;
/**
* Tests support for dumping graphs and other info useful for debugging a compiler crash.
*/
public class RetryableCompilationTest extends GraalCompilerTest {
public class CompilationWrapperTest extends GraalCompilerTest {
/**
* Tests compilation requested by the VM.
*/
@Test
public void testVMCompilation() throws IOException, InterruptedException {
testHelper(Arrays.asList("-XX:+BootstrapJVMCI", "-XX:+UseJVMCICompiler", "-Dgraal.CrashAt=Object.*,String.*", "-version"));
public void testVMCompilation1() throws IOException, InterruptedException {
testHelper(Arrays.asList("-XX:+BootstrapJVMCI",
"-XX:+UseJVMCICompiler",
"-Dgraal.CompilationFailureAction=ExitVM",
"-Dgraal.CrashAt=Object.*,String.*",
"-version"));
}
/**
* Tests that {@code -Dgraal.ExitVMOnException=true} works as an alias for
* {@code -Dgraal.CompilationFailureAction=ExitVM}.
*/
@Test
public void testVMCompilation2() throws IOException, InterruptedException {
testHelper(Arrays.asList("-XX:+BootstrapJVMCI",
"-XX:+UseJVMCICompiler",
"-Dgraal.ExitVMOnException=true",
"-Dgraal.CrashAt=Object.*,String.*",
"-version"));
}
/**
@ -58,17 +75,24 @@ public class RetryableCompilationTest extends GraalCompilerTest {
*/
@Test
public void testTruffleCompilation() throws IOException, InterruptedException {
testHelper(Arrays.asList("-Dgraal.CrashAt=root test1"), "org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite", "test");
testHelper(Arrays.asList(
"-Dgraal.CompilationFailureAction=ExitVM",
"-Dgraal.CrashAt=root test1"),
"org.graalvm.compiler.truffle.test.SLTruffleGraalTestSuite",
"test");
}
private static void testHelper(List<String> extraVmArgs, String... mainClassAndArgs) throws IOException, InterruptedException {
final File dumpPath = new File(CompilationWrapperTest.class.getSimpleName() + "_" + System.currentTimeMillis()).getAbsoluteFile();
List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
vmArgs.removeIf(a -> a.startsWith("-Dgraal."));
vmArgs.add("-Dgraal.DumpPath=" + dumpPath);
// Force output to a file even if there's a running IGV instance available.
vmArgs.add("-Dgraal.PrintGraphFile=true");
vmArgs.addAll(extraVmArgs);
Subprocess proc = SubprocessUtil.java(vmArgs, mainClassAndArgs);
System.out.println(proc);
String forcedCrashString = "Forced crash after compiling";
String diagnosticOutputFilePrefix = "Graal diagnostic output saved in ";
@ -86,6 +110,7 @@ public class RetryableCompilationTest extends GraalCompilerTest {
}
}
}
if (!seenForcedCrashString) {
Assert.fail(String.format("Did not find '%s' in output of command:%n%s", forcedCrashString, proc));
}
@ -93,8 +118,11 @@ public class RetryableCompilationTest extends GraalCompilerTest {
Assert.fail(String.format("Did not find '%s' in output of command:%n%s", diagnosticOutputFilePrefix, proc));
}
String[] dumpPathEntries = dumpPath.list();
File zip = new File(diagnosticOutputZip).getAbsoluteFile();
Assert.assertTrue(zip.toString(), zip.exists());
Assert.assertArrayEquals(dumpPathEntries, new String[]{zip.getName()});
try {
int bgv = 0;
int cfg = 0;
@ -118,6 +146,7 @@ public class RetryableCompilationTest extends GraalCompilerTest {
}
} finally {
zip.delete();
dumpPath.delete();
}
}
}

View File

@ -23,9 +23,9 @@
package org.graalvm.compiler.hotspot.test;
import static java.util.Collections.singletonList;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintBailout;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintStackTraceOnException;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Print;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries;
import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes;
import static org.graalvm.compiler.hotspot.test.CompileTheWorld.Options.DESCRIPTORS;
@ -209,12 +209,9 @@ public final class CompileTheWorld {
EconomicMap<OptionKey<?>, Object> compilationOptionsCopy = EconomicMap.create(initialOptions.getMap());
compilationOptionsCopy.putAll(compilationOptions);
// We don't want the VM to exit when a method fails to compile...
ExitVMOnException.putIfAbsent(compilationOptionsCopy, false);
// ...but we want to see exceptions.
PrintBailout.putIfAbsent(compilationOptionsCopy, true);
PrintStackTraceOnException.putIfAbsent(compilationOptionsCopy, true);
// We want to see stack traces when a method fails to compile
CompilationBailoutAction.putIfAbsent(compilationOptionsCopy, Print);
CompilationFailureAction.putIfAbsent(compilationOptionsCopy, Print);
// By default only report statistics for the CTW threads themselves
DebugOptions.MetricsThreadFilter.putIfAbsent(compilationOptionsCopy, "^CompileTheWorld");

View File

@ -22,7 +22,10 @@
*/
package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
import org.graalvm.compiler.options.OptionKey;
@ -40,13 +43,15 @@ public class CompileTheWorldTest extends GraalCompilerTest {
@Test
public void testJDK() throws Throwable {
boolean originalSetting = ExitVMOnException.getValue(getInitialOptions());
ExceptionAction originalBailoutAction = CompilationBailoutAction.getValue(getInitialOptions());
ExceptionAction originalFailureAction = CompilationFailureAction.getValue(getInitialOptions());
// Compile a couple classes in rt.jar
HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime();
System.setProperty("CompileTheWorld.LimitModules", "java.base");
OptionValues initialOptions = getInitialOptions();
EconomicMap<OptionKey<?>, Object> compilationOptions = CompileTheWorld.parseOptions("Inline=false");
new CompileTheWorld(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), CompileTheWorld.SUN_BOOT_CLASS_PATH, 1, 5, null, null, false, initialOptions, compilationOptions).compile();
assert ExitVMOnException.getValue(initialOptions) == originalSetting;
assert CompilationBailoutAction.getValue(initialOptions) == originalBailoutAction;
assert CompilationFailureAction.getValue(initialOptions) == originalFailureAction;
}
}

View File

@ -22,13 +22,8 @@
*/
package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnBailout;
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintAfterCompilation;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintBailout;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintCompilation;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintFilter;
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintStackTraceOnException;
import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
@ -36,16 +31,17 @@ import java.util.List;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.CompilationPrinter;
import org.graalvm.compiler.core.CompilationWrapper;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.Management;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.debug.TimeSource;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.options.EnumOptionKey;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
@ -65,8 +61,6 @@ import jdk.vm.ci.services.JVMCIServiceLocator;
public class CompilationTask {
private static final CounterKey BAILOUTS = DebugContext.counter("Bailouts");
private static final EventProvider eventProvider;
static {
@ -96,81 +90,95 @@ public class CompilationTask {
private final boolean useProfilingInfo;
private final OptionValues options;
final class RetryableCompilation extends HotSpotRetryableCompilation<HotSpotCompilationRequestResult> {
final class HotSpotCompilationWrapper extends CompilationWrapper<HotSpotCompilationRequestResult> {
private final EventProvider.CompilationEvent compilationEvent;
CompilationResult result;
RetryableCompilation(EventProvider.CompilationEvent compilationEvent) {
super(compiler.getGraalRuntime());
HotSpotCompilationWrapper(EventProvider.CompilationEvent compilationEvent) {
super(compiler.getGraalRuntime().getOutputDirectory());
this.compilationEvent = compilationEvent;
}
@Override
protected DebugContext createRetryDebugContext(OptionValues retryOptions) {
SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
return DebugContext.create(retryOptions, new GraalDebugHandlersFactory(snippetReflection));
}
@Override
public String toString() {
return getMethod().format("%H.%n");
return getMethod().format("%H.%n(%p)");
}
@Override
protected HotSpotCompilationRequestResult handleException(Throwable t) {
if (t instanceof BailoutException) {
BailoutException bailout = (BailoutException) t;
/*
* Handling of permanent bailouts: Permanent bailouts that can happen for example
* due to unsupported unstructured control flow in the bytecodes of a method must
* not be retried. Hotspot compile broker will ensure that no recompilation at the
* given tier will happen if retry is false.
*/
return HotSpotCompilationRequestResult.failure(bailout.getMessage(), !bailout.isPermanent());
}
// Log a failure event.
EventProvider.CompilerFailureEvent event = eventProvider.newCompilerFailureEvent();
if (event.shouldWrite()) {
event.setCompileId(getId());
event.setMessage(t.getMessage());
event.commit();
}
/*
* Treat random exceptions from the compiler as indicating a problem compiling this
* method. Report the result of toString instead of getMessage to ensure that the
* exception type is included in the output in case there's no detail mesage.
*/
return HotSpotCompilationRequestResult.failure(t.toString(), false);
}
@Override
protected ExceptionAction lookupAction(OptionValues values, EnumOptionKey<ExceptionAction> actionKey) {
/*
* Automatically exit VM on non-bailout during bootstrap or when asserts are enabled but
* respect CompilationFailureAction if it has been explicitly set.
*/
if (actionKey == CompilationFailureAction && !actionKey.hasBeenSet(values)) {
if (Assertions.ENABLED || compiler.getGraalRuntime().isBootstrapping()) {
return ExitVM;
}
}
return super.lookupAction(values, actionKey);
}
@SuppressWarnings("try")
@Override
protected HotSpotCompilationRequestResult run(DebugContext debug, Throwable retryCause) {
protected HotSpotCompilationRequestResult performCompilation(DebugContext debug) {
HotSpotResolvedJavaMethod method = getMethod();
int entryBCI = getEntryBCI();
final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
CompilationStatistics stats = CompilationStatistics.create(options, method, isOSR);
final boolean printCompilation = PrintCompilation.getValue(options) && !TTY.isSuppressed();
final boolean printAfterCompilation = PrintAfterCompilation.getValue(options) && !TTY.isSuppressed();
if (printCompilation) {
TTY.println(getMethodDescription() + "...");
}
TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(options), method);
final long start;
final long allocatedBytesBefore;
if (printAfterCompilation || printCompilation) {
final long threadId = Thread.currentThread().getId();
start = TimeSource.getTimeNS();
allocatedBytesBefore = printAfterCompilation || printCompilation ? Lazy.threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
} else {
start = 0L;
allocatedBytesBefore = 0L;
}
final CompilationPrinter printer = CompilationPrinter.begin(options, compilationId, method, entryBCI);
try (DebugContext.Scope s = debug.scope("Compiling", new DebugDumpScope(getIdString(), true))) {
// Begin the compilation event.
compilationEvent.begin();
result = compiler.compile(method, entryBCI, useProfilingInfo, compilationId, options, debug);
} catch (Throwable e) {
if (retryCause != null) {
log("Exception during retry", e);
}
throw debug.handle(e);
} finally {
// End the compilation event.
compilationEvent.end();
filter.remove();
if (printAfterCompilation || printCompilation) {
final long threadId = Thread.currentThread().getId();
final long stop = TimeSource.getTimeNS();
final long duration = (stop - start) / 1000000;
final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1;
final int bytecodeSize = result != null ? result.getBytecodeSize() : 0;
final long allocatedBytesAfter = Lazy.threadMXBean.getThreadAllocatedBytes(threadId);
final long allocatedKBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
if (printAfterCompilation) {
TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB %5dkB", duration, bytecodeSize, targetCodeSize, allocatedKBytes));
} else if (printCompilation) {
TTY.println(String.format("%-6d JVMCI %-70s %-45s %-50s | %4dms %5dB %5dB %5dkB", getId(), "", "", "", duration, bytecodeSize, targetCodeSize, allocatedKBytes));
}
}
}
if (result != null) {
try (DebugCloseable b = CodeInstallationTime.start(debug)) {
installMethod(debug, result);
}
// Installation is included in compilation time and memory usage reported by printer
printer.finish(result);
}
stats.finish(method, installedCode);
if (result != null) {
@ -180,14 +188,6 @@ public class CompilationTask {
}
}
static class Lazy {
/**
* A {@link com.sun.management.ThreadMXBean} to be able to query some information about the
* current compiler thread, e.g. total allocated bytes.
*/
static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
}
public CompilationTask(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault,
OptionValues options) {
this.jvmciRuntime = jvmciRuntime;
@ -226,7 +226,7 @@ public class CompilationTask {
}
/**
* Returns the HostSpot id of this compilation.
* Returns the HotSpot id of this compilation.
*
* @return HotSpot compile id
*/
@ -307,46 +307,9 @@ public class CompilationTask {
}
}
RetryableCompilation compilation = new RetryableCompilation(compilationEvent);
HotSpotCompilationWrapper compilation = new HotSpotCompilationWrapper(compilationEvent);
try (DebugCloseable a = CompilationTime.start(debug)) {
return compilation.runWithRetry(debug);
} catch (BailoutException bailout) {
BAILOUTS.increment(debug);
if (ExitVMOnBailout.getValue(options)) {
TTY.out.println(method.format("Bailout in %H.%n(%p)"));
bailout.printStackTrace(TTY.out);
System.exit(-1);
} else if (PrintBailout.getValue(options)) {
TTY.out.println(method.format("Bailout in %H.%n(%p)"));
bailout.printStackTrace(TTY.out);
}
/*
* Handling of permanent bailouts: Permanent bailouts that can happen for example due to
* unsupported unstructured control flow in the bytecodes of a method must not be
* retried. Hotspot compile broker will ensure that no recompilation at the given tier
* will happen if retry is false.
*/
final boolean permanentBailout = bailout.isPermanent();
if (permanentBailout && PrintBailout.getValue(options)) {
TTY.println("Permanent bailout %s compiling method %s %s.", bailout.getMessage(), HotSpotGraalCompiler.str(method), (isOSR ? "OSR" : ""));
}
return HotSpotCompilationRequestResult.failure(bailout.getMessage(), !permanentBailout);
} catch (Throwable t) {
// Log a failure event.
EventProvider.CompilerFailureEvent event = eventProvider.newCompilerFailureEvent();
if (event.shouldWrite()) {
event.setCompileId(getId());
event.setMessage(t.getMessage());
event.commit();
}
handleException(t);
/*
* Treat random exceptions from the compiler as indicating a problem compiling this
* method. Report the result of toString instead of getMessage to ensure that the
* exception type is included in the output in case there's no detail mesage.
*/
return HotSpotCompilationRequestResult.failure(t.toString(), false);
return compilation.run(debug);
} finally {
try {
int compiledBytecodes = 0;
@ -374,46 +337,11 @@ public class CompilationTask {
compilationEvent.commit();
}
} catch (Throwable t) {
handleException(t);
return compilation.handleException(t);
}
}
}
protected void handleException(Throwable t) {
/*
* Automatically enable ExitVMOnException during bootstrap or when asserts are enabled but
* respect ExitVMOnException if it's been explicitly set.
*/
boolean exitVMOnException = ExitVMOnException.getValue(options);
if (!ExitVMOnException.hasBeenSet(options)) {
assert (exitVMOnException = true) == true;
if (!exitVMOnException) {
HotSpotGraalRuntimeProvider runtime = compiler.getGraalRuntime();
if (runtime.isBootstrapping()) {
exitVMOnException = true;
}
}
}
if (PrintStackTraceOnException.getValue(options) || exitVMOnException) {
try {
t.printStackTrace(TTY.out);
} catch (Throwable throwable) {
// Don't let an exception here change the other control flow
}
}
if (exitVMOnException) {
System.exit(-1);
}
}
private String getMethodDescription() {
HotSpotResolvedJavaMethod method = getMethod();
return String.format("%-6d JVMCI %-70s %-45s %-50s %s", getId(), method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(),
getEntryBCI() == JVMCICompiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + getEntryBCI() + ") ");
}
@SuppressWarnings("try")
private void installMethod(DebugContext debug, final CompilationResult compResult) {
final CodeCacheProvider codeCache = jvmciRuntime.getHostJVMCIBackend().getCodeCache();

View File

@ -29,32 +29,18 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining;
import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.runtime.GraalRuntime;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Description;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.GlobalMetrics;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
@ -108,6 +94,7 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
private final GraalHotSpotVMConfig config;
private final OptionValues options;
private final DiagnosticsOutputDirectory outputDirectory;
private final HotSpotGraalMBean mBean;
/**
@ -126,6 +113,7 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
options = initialOptions;
}
outputDirectory = new DiagnosticsOutputDirectory(options);
snippetCounterGroups = GraalOptions.SnippetCounters.getValue(options) ? new ArrayList<>() : null;
CompilerConfiguration compilerConfiguration = compilerConfigurationFactory.createCompilerConfiguration();
@ -177,17 +165,6 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
runtimeStartTime = System.nanoTime();
bootstrapJVMCI = config.getFlag("BootstrapJVMCI", Boolean.class);
assert checkPathIsInvalid(DELETED_OUTPUT_DIRECTORY);
}
private static boolean checkPathIsInvalid(String path) {
try {
Paths.get(path);
return false;
} catch (InvalidPathException e) {
return true;
}
}
private HotSpotBackend registerBackend(HotSpotBackend backend) {
@ -293,7 +270,7 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
}
BenchmarkCounters.shutdown(runtime(), options, runtimeStartTime);
archiveAndDeleteOutputDirectory();
outputDirectory.close();
}
void clearMetrics() {
@ -317,98 +294,8 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
return shutdown;
}
/**
* Gets a unique identifier for this execution such as a process ID.
*/
private static String getExecutionID() {
String runtimeName = ManagementFactory.getRuntimeMXBean().getName();
try {
int index = runtimeName.indexOf('@');
if (index != -1) {
long pid = Long.parseLong(runtimeName.substring(0, index));
return Long.toString(pid);
}
} catch (NumberFormatException e) {
}
return runtimeName;
}
private String outputDirectory;
/**
* Use an illegal file name to denote that the output directory has been deleted.
*/
private static final String DELETED_OUTPUT_DIRECTORY = "\u0000";
@Override
public String getOutputDirectory() {
return getOutputDirectory(true);
}
private synchronized String getOutputDirectory(boolean createIfNull) {
if (outputDirectory == null && createIfNull) {
outputDirectory = "graal_output_" + getExecutionID();
File dir = new File(outputDirectory).getAbsoluteFile();
if (!dir.exists()) {
dir.mkdirs();
if (!dir.exists()) {
TTY.println("Warning: could not create Graal diagnostic directory " + dir);
return null;
}
}
}
return DELETED_OUTPUT_DIRECTORY.equals(outputDirectory) ? null : outputDirectory;
}
/**
* Archives and deletes the {@linkplain #getOutputDirectory() output directory} if it exists.
*/
private void archiveAndDeleteOutputDirectory() {
String outDir = getOutputDirectory(false);
if (outDir != null) {
Path dir = Paths.get(outDir);
if (dir.toFile().exists()) {
try {
// Give compiler threads a chance to finishing dumping
Thread.sleep(1000);
} catch (InterruptedException e1) {
}
File zip = new File(outDir + ".zip").getAbsoluteFile();
List<Path> toDelete = new ArrayList<>();
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
zos.setLevel(Deflater.BEST_COMPRESSION);
Files.walkFileTree(dir, Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (attrs.isRegularFile()) {
ZipEntry ze = new ZipEntry(file.toString());
zos.putNextEntry(ze);
zos.write(Files.readAllBytes(file));
zos.closeEntry();
}
toDelete.add(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
toDelete.add(d);
return FileVisitResult.CONTINUE;
}
});
TTY.println("Graal diagnostic output saved in %s", zip);
} catch (IOException e) {
TTY.printf("IO error archiving %s:%n%s%n", dir, e);
}
for (Path p : toDelete) {
try {
Files.delete(p);
} catch (IOException e) {
TTY.printf("IO error deleting %s:%n%s%n", p, e);
}
}
}
outputDirectory = DELETED_OUTPUT_DIRECTORY;
}
public DiagnosticsOutputDirectory getOutputDirectory() {
return outputDirectory;
}
}

View File

@ -25,6 +25,7 @@ package org.graalvm.compiler.hotspot;
import org.graalvm.compiler.api.runtime.GraalRuntime;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.options.OptionValues;
@ -91,12 +92,7 @@ public interface HotSpotGraalRuntimeProvider extends GraalRuntime, RuntimeProvid
boolean isShutdown();
/**
* Gets a directory into which diagnostics such crash reports and dumps should be written. This
* method will create the directory if it doesn't exist so it should only be called if
* diagnostics are about to be generated.
*
* @return the directory into which diagnostics can be written or {@code null} if the directory
* does not exist and could not be created or has already been deleted
* Gets a directory into which diagnostics such crash reports and dumps should be written.
*/
String getOutputDirectory();
DiagnosticsOutputDirectory getOutputDirectory();
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
import static org.graalvm.compiler.debug.DebugOptions.Dump;
import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugRetryableTask;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
import jdk.vm.ci.code.BailoutException;
/**
* Utility for retrying a compilation that throws an exception where the retry enables extra logging
* for subsequently diagnosing the failure.
*/
public abstract class HotSpotRetryableCompilation<T> extends DebugRetryableTask<T> {
protected final HotSpotGraalRuntimeProvider runtime;
public HotSpotRetryableCompilation(HotSpotGraalRuntimeProvider runtime) {
this.runtime = runtime;
}
/**
* Gets a value that represents the compilation unit being compiled.
*/
@Override
public abstract String toString();
@Override
protected DebugContext getRetryContext(DebugContext initialDebug, Throwable t) {
if (t instanceof BailoutException) {
return null;
}
OptionValues initialOptions = initialDebug.getOptions();
if (Dump.hasBeenSet(initialOptions)) {
// If dumping is explicitly enabled, Graal is being debugged
// so don't interfere with what the user is expecting to see.
return null;
}
String outputDirectory = runtime.getOutputDirectory();
if (outputDirectory == null) {
return null;
}
String dumpName = GraalDebugHandlersFactory.sanitizedFileName(toString());
File dumpPath = new File(outputDirectory, dumpName);
dumpPath.mkdirs();
if (!dumpPath.exists()) {
TTY.println("Warning: could not create dump directory " + dumpPath);
return null;
}
TTY.println("Retrying compilation of " + this + " due to " + t);
retryLogPath = new File(dumpPath, "retry.log").getPath();
log("Exception causing retry", t);
OptionValues retryOptions = new OptionValues(initialOptions,
Dump, ":" + VERBOSE_LEVEL,
MethodFilter, null,
DumpPath, dumpPath.getPath());
SnippetReflectionProvider snippetReflection = runtime.getHostProviders().getSnippetReflection();
return DebugContext.create(retryOptions, new GraalDebugHandlersFactory(snippetReflection));
}
private String retryLogPath;
/**
* Prints a message to a retry log file.
*
* @param message the message to print
* @param t if non-{@code null}, the stack trace for this exception is written to the retry log
* after {@code message}
*/
protected void log(String message, Throwable t) {
if (retryLogPath != null) {
try (PrintStream retryLog = new PrintStream(new FileOutputStream(retryLogPath), true)) {
StringBuilder buf = new StringBuilder(Thread.currentThread() + ": " + message);
if (t != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
t.printStackTrace(new PrintStream(baos));
buf.append(System.lineSeparator()).append(baos.toString());
}
retryLog.println(buf);
} catch (FileNotFoundException e) {
TTY.println("Warning: could not open retry log file " + retryLogPath + " [" + e + "]");
}
}
}
}

View File

@ -90,7 +90,7 @@ import org.graalvm.compiler.replacements.nodes.DirectStoreNode;
import org.graalvm.compiler.word.Word;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Pointer;
import org.graalvm.word.Unsigned;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;
import jdk.vm.ci.code.Register;
@ -250,11 +250,11 @@ public class WriteBarrierSnippets implements Snippets {
// The result of the xor reveals whether the installed pointer crosses heap regions.
// In case it does the write barrier has to be issued.
final int logOfHeapRegionGrainBytes = GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes();
Unsigned xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes);
UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes);
// Calculate the address of the card to be enqueued to the
// thread local card queue.
Unsigned cardBase = oop.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG));
UnsignedWord cardBase = oop.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG));
final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress();
int displacement = 0;
if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) {

View File

@ -56,7 +56,7 @@ import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
import org.graalvm.compiler.word.ObjectAccess;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Unsigned;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;
import jdk.vm.ci.code.TargetDescription;
@ -237,15 +237,15 @@ public class UnsafeArrayCopySnippets implements Snippets {
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
Unsigned vectorSize = WordFactory.unsigned(VECTOR_SIZE);
Unsigned srcOffset = WordFactory.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
Unsigned destOffset = WordFactory.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
Unsigned destStart = destOffset;
Unsigned destEnd = destOffset.add(WordFactory.unsigned(length).shiftLeft(log2ElementSize));
UnsignedWord vectorSize = WordFactory.unsigned(VECTOR_SIZE);
UnsignedWord srcOffset = WordFactory.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize);
UnsignedWord destOffset = WordFactory.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize);
UnsignedWord destStart = destOffset;
UnsignedWord destEnd = destOffset.add(WordFactory.unsigned(length).shiftLeft(log2ElementSize));
Unsigned destVectorEnd = null;
Unsigned nonVectorBytes = null;
Unsigned sizeInBytes = WordFactory.unsigned(length).shiftLeft(log2ElementSize);
UnsignedWord destVectorEnd = null;
UnsignedWord nonVectorBytes = null;
UnsignedWord sizeInBytes = WordFactory.unsigned(length).shiftLeft(log2ElementSize);
if (supportsUnalignedMemoryAccess) {
nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize);
destVectorEnd = destEnd;
@ -261,7 +261,7 @@ public class UnsafeArrayCopySnippets implements Snippets {
destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize));
}
Unsigned destNonVectorEnd = destStart.add(nonVectorBytes);
UnsignedWord destNonVectorEnd = destStart.add(nonVectorBytes);
while (destOffset.belowThan(destNonVectorEnd)) {
ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, any()), any());
destOffset = destOffset.add(1);

View File

@ -31,8 +31,8 @@ import org.graalvm.compiler.word.Word.Opcode;
import org.graalvm.compiler.word.Word.Operation;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Pointer;
import org.graalvm.word.Signed;
import org.graalvm.word.Unsigned;
import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordBase;
/**
@ -50,8 +50,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -65,8 +65,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -80,8 +80,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -95,8 +95,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -110,8 +110,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -125,8 +125,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -140,8 +140,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -155,8 +155,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -170,8 +170,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -284,8 +284,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -299,8 +299,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -314,8 +314,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -329,8 +329,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -344,8 +344,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -359,8 +359,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -374,8 +374,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -389,8 +389,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -404,8 +404,8 @@ public abstract class MetaspacePointer {
* Initializes the memory at address {@code (this + offset)}. Both the base address and offset
* are in bytes. The memory must be uninitialized or zero prior to this operation.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -419,8 +419,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -533,8 +533,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -547,8 +547,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -561,8 +561,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -575,8 +575,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -589,8 +589,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -603,8 +603,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -617,8 +617,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -631,8 +631,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -645,8 +645,8 @@ public abstract class MetaspacePointer {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -660,8 +660,8 @@ public abstract class MetaspacePointer {
* the VM uses compressed oops, and it can be parameterized to allow read barriers (G1 referent
* field).
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -777,8 +777,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -791,8 +791,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -805,8 +805,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -819,8 +819,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -833,8 +833,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -847,8 +847,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -861,8 +861,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -875,8 +875,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -889,8 +889,8 @@ public abstract class MetaspacePointer {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access

View File

@ -365,6 +365,7 @@ import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
import org.graalvm.compiler.nodes.calc.XorNode;
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.extended.AnchoringNode;
import org.graalvm.compiler.nodes.extended.BranchProbabilityNode;
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode;
import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
@ -2959,7 +2960,7 @@ public class BytecodeParser implements GraphBuilderContext {
}
// Need to get probability based on current bci.
double probability = branchProbability();
double probability = branchProbability(condition);
if (negate) {
BciBlock tmpBlock = trueBlock;
@ -4026,12 +4027,36 @@ public class BytecodeParser implements GraphBuilderContext {
return probability == 0 && optimisticOpts.removeNeverExecutedCode(getOptions());
}
protected double branchProbability() {
private double rawBranchProbability(LogicNode conditionInput) {
if (conditionInput instanceof IntegerEqualsNode) {
// Propagate injected branch probability if any.
IntegerEqualsNode condition = (IntegerEqualsNode) conditionInput;
BranchProbabilityNode injectedProbability = null;
ValueNode other = null;
if (condition.getX() instanceof BranchProbabilityNode) {
injectedProbability = (BranchProbabilityNode) condition.getX();
other = condition.getY();
} else if (condition.getY() instanceof BranchProbabilityNode) {
injectedProbability = (BranchProbabilityNode) condition.getY();
other = condition.getX();
}
if (injectedProbability != null && injectedProbability.getProbability().isConstant() && other != null && other.isConstant()) {
double probabilityValue = injectedProbability.getProbability().asJavaConstant().asDouble();
return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
}
}
if (profilingInfo == null) {
return 0.5;
}
assert assertAtIfBytecode();
double probability = profilingInfo.getBranchTakenProbability(bci());
return profilingInfo.getBranchTakenProbability(bci());
}
protected double branchProbability(LogicNode conditionInput) {
double probability = rawBranchProbability(conditionInput);
if (probability < 0) {
assert probability == -1 : "invalid probability";
debug.log("missing probability in %s at bci %d", code, bci());

View File

@ -435,8 +435,9 @@ public class AArch64Move {
try (ScratchRegister r2 = masm.getScratchRegister()) {
Register rscratch1 = r1.getRegister();
Register rscratch2 = r2.getRegister();
// use the slot kind to define the operand size
PlatformKind kind = input.getPlatformKind();
final int size = kind.getSizeInBytes() <= 4 ? 32 : 64;
final int size = kind.getSizeInBytes() * Byte.SIZE;
// Always perform stack -> stack copies through integer registers
crb.blockComment("[stack -> stack copy]");
@ -466,8 +467,9 @@ public class AArch64Move {
private static void reg2stack(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) {
AArch64Address dest = loadStackSlotAddress(crb, masm, asStackSlot(result), Value.ILLEGAL);
Register src = asRegister(input);
AArch64Kind kind = (AArch64Kind) input.getPlatformKind();
int size = kind.getSizeInBytes() * Byte.SIZE;
// use the slot kind to define the operand size
AArch64Kind kind = (AArch64Kind) result.getPlatformKind();
final int size = kind.getSizeInBytes() * Byte.SIZE;
if (kind.isInteger()) {
masm.str(size, src, dest);
} else {
@ -477,6 +479,7 @@ public class AArch64Move {
private static void stack2reg(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) {
AArch64Kind kind = (AArch64Kind) input.getPlatformKind();
// use the slot kind to define the operand size
final int size = kind.getSizeInBytes() * Byte.SIZE;
if (kind.isInteger()) {
AArch64Address src = loadStackSlotAddress(crb, masm, asStackSlot(input), result);

View File

@ -669,6 +669,28 @@ public class AMD64Move {
}
}
public static boolean canMoveConst2Stack(JavaConstant input) {
switch (input.getJavaKind().getStackKind()) {
case Int:
break;
case Long:
break;
case Float:
break;
case Double:
break;
case Object:
if (input.isNull()) {
return true;
} else {
return false;
}
default:
return false;
}
return true;
}
public static void const2stack(CompilationResultBuilder crb, AMD64MacroAssembler masm, Value result, JavaConstant input) {
AMD64Address dest = (AMD64Address) crb.asAddress(result);
final long imm;

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.lir.jtt;
import org.junit.Before;
import org.junit.Test;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.VirtualStackSlot;
import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
public class StackStoreLoadTest extends LIRTest {
private static PlatformKind byteKind;
private static PlatformKind shortKind;
@Before
public void setUp() {
byteKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Byte);
shortKind = getBackend().getTarget().arch.getPlatformKind(JavaKind.Short);
}
private static class StackStoreLoadSpec extends LIRTestSpecification {
@Override
public void generate(LIRGeneratorTool gen, Value a) {
FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
ValueKind<?> valueKind = getValueKind(a);
// create slots
VirtualStackSlot s1 = frameMapBuilder.allocateSpillSlot(valueKind);
VirtualStackSlot s2 = frameMapBuilder.allocateSpillSlot(valueKind);
VirtualStackSlot s3 = frameMapBuilder.allocateSpillSlot(valueKind);
// start emit
gen.emitMove(s1, a);
gen.emitMove(s2, a);
gen.emitMove(s3, a);
gen.append(gen.getSpillMoveFactory().createStackMove(s1, s3));
Variable result = gen.emitMove(s2);
Value slot1 = gen.emitMove(s1);
Value slot3 = gen.emitMove(s3);
// end emit
// set output and result
setResult(result);
setOutput("slot1", slot1);
setOutput("slot3", slot3);
}
protected ValueKind<?> getValueKind(Value value) {
return value.getValueKind();
}
}
/*
* short
*/
private static final LIRTestSpecification shortStackCopy = new StackStoreLoadSpec() {
@Override
protected ValueKind<?> getValueKind(Value value) {
return LIRKind.value(shortKind);
}
};
@SuppressWarnings("unused")
@LIRIntrinsic
public static short copyShort(LIRTestSpecification spec, short a) {
return a;
}
public short[] testShort(short a, short[] out) {
out[0] = copyShort(shortStackCopy, a);
out[1] = getOutput(shortStackCopy, "slot1", a);
out[2] = getOutput(shortStackCopy, "slot3", a);
return out;
}
@Test
public void runShort() throws Throwable {
runTest("testShort", Short.MIN_VALUE, supply(() -> new short[3]));
runTest("testShort", (short) -1, supply(() -> new short[3]));
runTest("testShort", (short) 0, supply(() -> new short[3]));
runTest("testShort", (short) 1, supply(() -> new short[3]));
runTest("testShort", Short.MAX_VALUE, supply(() -> new short[3]));
}
/*
* byte
*/
private static final LIRTestSpecification byteStackCopy = new StackStoreLoadSpec() {
@Override
protected ValueKind<?> getValueKind(Value value) {
return LIRKind.value(byteKind);
}
};
@SuppressWarnings("unused")
@LIRIntrinsic
public static byte copyByte(LIRTestSpecification spec, byte a) {
return a;
}
public byte[] testByte(byte a, byte[] out) {
out[0] = copyByte(byteStackCopy, a);
out[1] = getOutput(byteStackCopy, "slot1", a);
out[2] = getOutput(byteStackCopy, "slot3", a);
return out;
}
@Test
public void runByte() throws Throwable {
runTest("testByte", Byte.MIN_VALUE, supply(() -> new byte[3]));
runTest("testByte", (byte) -1, supply(() -> new byte[3]));
runTest("testByte", (byte) 0, supply(() -> new byte[3]));
runTest("testByte", (byte) 1, supply(() -> new byte[3]));
runTest("testByte", Byte.MAX_VALUE, supply(() -> new byte[3]));
}
}

View File

@ -37,8 +37,9 @@ import org.graalvm.compiler.lir.LIRInsertionBuffer;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRValueUtil;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.util.Equivalence;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.Equivalence;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.Value;
@ -296,7 +297,12 @@ public class MoveResolver {
assert insertIdx != -1 : "must setup insert position first";
AllocatableValue toOpr = toInterval.operand;
LIRInstruction move = getAllocator().getSpillMoveFactory().createLoad(toOpr, fromOpr);
LIRInstruction move;
if (LIRValueUtil.isStackSlotValue(toInterval.location())) {
move = getAllocator().getSpillMoveFactory().createStackLoad(toOpr, fromOpr);
} else {
move = getAllocator().getSpillMoveFactory().createLoad(toOpr, fromOpr);
}
insertionBuffer.append(insertIdx, move);
DebugContext debug = allocator.getDebug();
@ -482,7 +488,8 @@ public class MoveResolver {
}
assert !fromInterval.operand.equals(toInterval.operand) : "from and to interval equal: " + fromInterval;
assert LIRKind.verifyMoveKinds(toInterval.kind(), fromInterval.kind(), allocator.getRegisterAllocationConfig()) : String.format("Kind mismatch: %s vs. %s, from=%s, to=%s", fromInterval.kind(),
assert LIRKind.verifyMoveKinds(toInterval.kind(), fromInterval.kind(), allocator.getRegisterAllocationConfig()) : String.format("Kind mismatch: %s vs. %s, from=%s, to=%s",
fromInterval.kind(),
toInterval.kind(), fromInterval, toInterval);
mappingFrom.add(fromInterval);
mappingFromOpr.add(null);

View File

@ -482,7 +482,7 @@ public class CompilationResultBuilder {
afterOp.accept(op);
}
} catch (GraalError e) {
throw e.addContext("lir instruction", block + "@" + op.id() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
throw e.addContext("lir instruction", block + "@" + op.id() + " " + op.getClass().getName() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
}
}
}

View File

@ -80,6 +80,8 @@ public interface LIRGeneratorTool extends DiagnosticLIRGeneratorTool, ValueKindF
LIRInstruction createStackMove(AllocatableValue result, AllocatableValue input);
LIRInstruction createLoad(AllocatableValue result, Constant input);
LIRInstruction createStackLoad(AllocatableValue result, Constant input);
}
abstract class BlockScope implements AutoCloseable {

View File

@ -80,6 +80,13 @@ public final class VerifyingMoveFactory implements MoveFactory {
return inst;
}
@Override
public LIRInstruction createStackLoad(AllocatableValue result, Constant input) {
LIRInstruction inst = inner.createStackLoad(result, input);
assert LoadConstantOp.isLoadConstantOp(inst) && checkResult(inst, result, null);
return inst;
}
/** Closure for {@link VerifyingMoveFactory#checkResult}. */
@SuppressWarnings("unused")
private static class CheckClosure {

View File

@ -22,7 +22,9 @@
*/
package org.graalvm.compiler.loop;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import org.graalvm.compiler.debug.GraalError;
@ -55,6 +57,8 @@ import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.util.EconomicMap;
import jdk.vm.ci.meta.TriState;
public abstract class LoopFragment {
private final LoopEx loop;
@ -221,6 +225,7 @@ public abstract class LoopFragment {
}
final NodeBitMap nonLoopNodes = graph.createNodeBitMap();
Deque<WorkListEntry> worklist = new ArrayDeque<>();
for (AbstractBeginNode b : blocks) {
if (b.isDeleted()) {
continue;
@ -229,56 +234,98 @@ public abstract class LoopFragment {
for (Node n : b.getBlockNodes()) {
if (n instanceof CommitAllocationNode) {
for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) {
markFloating(obj, nodes, nonLoopNodes);
markFloating(worklist, obj, nodes, nonLoopNodes);
}
}
if (n instanceof MonitorEnterNode) {
markFloating(((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes);
markFloating(worklist, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes);
}
for (Node usage : n.usages()) {
markFloating(usage, nodes, nonLoopNodes);
markFloating(worklist, usage, nodes, nonLoopNodes);
}
}
}
}
private static boolean markFloating(Node n, NodeBitMap loopNodes, NodeBitMap nonLoopNodes) {
static class WorkListEntry {
final Iterator<Node> usages;
final Node n;
boolean isLoopNode;
WorkListEntry(Node n, NodeBitMap loopNodes) {
this.n = n;
this.usages = n.usages().iterator();
this.isLoopNode = loopNodes.isMarked(n);
}
}
static TriState isLoopNode(Node n, NodeBitMap loopNodes, NodeBitMap nonLoopNodes) {
if (loopNodes.isMarked(n)) {
return true;
return TriState.TRUE;
}
if (nonLoopNodes.isMarked(n)) {
return false;
return TriState.FALSE;
}
if (n instanceof FixedNode) {
return false;
return TriState.FALSE;
}
boolean mark = false;
if (n instanceof PhiNode) {
PhiNode phi = (PhiNode) n;
mark = loopNodes.isMarked(phi.merge());
if (mark) {
/*
* This Phi is a loop node but the inputs might not be so they must be processed by
* the caller.
*/
loopNodes.mark(n);
} else {
nonLoopNodes.mark(n);
return false;
return TriState.FALSE;
}
}
for (Node usage : n.usages()) {
if (markFloating(usage, loopNodes, nonLoopNodes)) {
mark = true;
return TriState.UNKNOWN;
}
private static void markFloating(Deque<WorkListEntry> workList, Node start, NodeBitMap loopNodes, NodeBitMap nonLoopNodes) {
if (isLoopNode(start, loopNodes, nonLoopNodes).isKnown()) {
return;
}
workList.push(new WorkListEntry(start, loopNodes));
while (!workList.isEmpty()) {
WorkListEntry currentEntry = workList.peek();
if (currentEntry.usages.hasNext()) {
Node current = currentEntry.usages.next();
TriState result = isLoopNode(current, loopNodes, nonLoopNodes);
if (result.isKnown()) {
if (result.toBoolean()) {
currentEntry.isLoopNode = true;
}
} else {
workList.push(new WorkListEntry(current, loopNodes));
}
} else {
workList.pop();
boolean isLoopNode = currentEntry.isLoopNode;
Node current = currentEntry.n;
if (!isLoopNode && current instanceof GuardNode) {
/*
* (gd) this is only OK if we are not going to make loop transforms based on
* this
*/
assert !((GuardNode) current).graph().hasValueProxies();
isLoopNode = true;
}
if (isLoopNode) {
loopNodes.mark(current);
for (WorkListEntry e : workList) {
e.isLoopNode = true;
}
} else {
nonLoopNodes.mark(current);
}
}
}
if (!mark && n instanceof GuardNode) {
// (gd) this is only OK if we are not going to make loop transforms based on this
assert !((GuardNode) n).graph().hasValueProxies();
mark = true;
}
if (mark) {
loopNodes.mark(n);
return true;
}
nonLoopNodes.mark(n);
return false;
}
public static NodeIterable<AbstractBeginNode> toHirBlocks(final Iterable<Block> blocks) {

View File

@ -28,10 +28,27 @@ import org.graalvm.util.EconomicMap;
public class EnumOptionKey<T extends Enum<T>> extends OptionKey<T> {
final Class<T> enumClass;
final ValueHelp<T> valueHelp;
/**
* Provides help text for enum values.
*/
public interface ValueHelp<T extends Enum<T>> {
/**
* Gets help text for the enum {@code value} that includes the name of the value. If
* {@code null} is returned, {@code value.toString()} is used.
*/
String getHelp(Object value);
}
public EnumOptionKey(T value) {
this(value, null);
}
@SuppressWarnings("unchecked")
public EnumOptionKey(T value) {
public EnumOptionKey(T value, ValueHelp<T> help) {
super(value);
this.valueHelp = help;
if (value == null) {
throw new IllegalArgumentException("Value must not be null");
}
@ -45,6 +62,10 @@ public class EnumOptionKey<T extends Enum<T>> extends OptionKey<T> {
return EnumSet.allOf(enumClass);
}
public ValueHelp<T> getValueHelp() {
return valueHelp;
}
Object valueOf(String name) {
try {
return Enum.valueOf(enumClass, name);

View File

@ -26,11 +26,13 @@ import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.graalvm.compiler.options.EnumOptionKey.ValueHelp;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import org.graalvm.util.UnmodifiableEconomicMap;
@ -223,11 +225,20 @@ public class OptionValues {
String help = desc.getHelp();
if (desc.getOptionKey() instanceof EnumOptionKey) {
EnumOptionKey<?> eoption = (EnumOptionKey<?>) desc.getOptionKey();
String evalues = eoption.getAllValues().toString();
EnumSet<?> evalues = eoption.getAllValues();
String evaluesString = evalues.toString();
ValueHelp<?> valueHelp = eoption.getValueHelp();
if (help.length() > 0 && !help.endsWith(".")) {
help += ".";
}
help += " Valid values are: " + evalues.substring(1, evalues.length() - 1);
if (valueHelp == null) {
help += " Valid values are: " + evaluesString.substring(1, evaluesString.length() - 1);
} else {
for (Object o : evalues) {
String vhelp = valueHelp.getHelp(o);
help += "%n" + (vhelp == null ? o : vhelp);
}
}
}
String name = namePrefix + e.getKey();
String assign = containsKey(desc.optionKey) ? ":=" : "=";

View File

@ -144,7 +144,7 @@ public class CFGPrinterObserver implements DebugDumpHandler {
OutputStream out = new BufferedOutputStream(new FileOutputStream(cfgFile));
cfgPrinter = new CFGPrinter(out);
} catch (IOException e) {
throw (GraalError) new GraalError("Could not open %s", cfgFile.getAbsolutePath()).initCause(e);
throw (GraalError) new GraalError("Could not open %s", cfgFile == null ? "[null]" : cfgFile.getAbsolutePath()).initCause(e);
}
}

View File

@ -28,6 +28,7 @@ import static org.graalvm.compiler.debug.DebugOptions.PrintGraphHost;
import static org.graalvm.compiler.debug.DebugOptions.PrintXmlGraphPort;
import static org.graalvm.compiler.debug.DebugOptions.ShowDumpFiles;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
@ -53,7 +54,7 @@ import org.graalvm.compiler.debug.DebugHandler;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.debug.UniquePathUtilities;
import org.graalvm.compiler.debug.PathUtilities;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodeinfo.Verbosity;
@ -117,7 +118,13 @@ public class GraalDebugHandlersFactory implements DebugHandlersFactory {
return new CanonicalStringGraphPrinter(snippetReflection);
}
public static String sanitizedFileName(String name) {
public static String sanitizedFileName(String n) {
/*
* First ensure that the name does not contain the directory separator (which would be
* considered a valid path).
*/
String name = n.replace(File.separatorChar, '_');
try {
Paths.get(name);
return name;
@ -194,7 +201,7 @@ public class GraalDebugHandlersFactory implements DebugHandlersFactory {
label = graph == null ? null : graph.name != null ? graph.name : graph.toString();
id = "UnknownCompilation-" + unknownCompilationId.incrementAndGet();
}
String ext = UniquePathUtilities.formatExtension(extension);
String ext = PathUtilities.formatExtension(extension);
Path result = createUnique(DebugOptions.getDumpDirectory(options), id, label, ext, createDirectory);
if (ShowDumpFiles.getValue(options)) {
TTY.println("Dumping debug output to %s", result.toAbsolutePath().toString());
@ -220,7 +227,7 @@ public class GraalDebugHandlersFactory implements DebugHandlersFactory {
// This means `id` is very long
String suffix = timestamp + ext;
int idLengthLimit = Math.min(MAX_FILE_NAME_LENGTH - suffix.length(), id.length());
fileName = id.substring(0, idLengthLimit) + suffix;
fileName = sanitizedFileName(id.substring(0, idLengthLimit) + suffix);
} else {
if (label == null) {
fileName = sanitizedFileName(id + timestamp + ext);

View File

@ -30,7 +30,7 @@ import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.word.Word;
import org.graalvm.word.Pointer;
import org.graalvm.word.Unsigned;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordBase;
import org.graalvm.word.WordFactory;
import org.junit.Test;
@ -118,7 +118,7 @@ public class WordTest extends SnippetsTest {
@Snippet
public static long cast(long input) {
WordBase base = WordFactory.signed(input);
Unsigned unsigned = (Unsigned) base;
UnsignedWord unsigned = (UnsignedWord) base;
Pointer pointer = (Pointer) unsigned;
Word word = (Word) pointer;
return word.rawValue();

View File

@ -151,6 +151,13 @@ public class ClassfileBytecodeProviderTest extends GraalCompilerTest {
String name = zipEntry.getName();
if (name.endsWith(".class") && !name.equals("module-info.class")) {
String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
if (isInNativeImage(className)) {
/*
* Native image requires non-graalsdk classes to be present in the
* classpath.
*/
continue;
}
try {
checkClass(metaAccess, getSnippetReflection(), className);
} catch (ClassNotFoundException e) {
@ -165,6 +172,10 @@ public class ClassfileBytecodeProviderTest extends GraalCompilerTest {
}
}
private static boolean isInNativeImage(String className) {
return className.startsWith("org.graalvm.nativeimage");
}
protected void checkClass(MetaAccessProvider metaAccess, SnippetReflectionProvider snippetReflection, String className) throws ClassNotFoundException {
Class<?> c = Class.forName(className, true, getClass().getClassLoader());
ClassfileBytecodeProvider cbp = new ClassfileBytecodeProvider(metaAccess, snippetReflection);

View File

@ -32,6 +32,7 @@ import java.util.List;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.StampPair;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node.ValueNumberable;
import org.graalvm.compiler.java.FrameStateBuilder;
@ -206,7 +207,7 @@ public class GraphKit implements GraphBuilderTool {
method = providers.getMetaAccess().lookupJavaMethod(m);
}
}
assert method != null : "did not find method in " + declaringClass + " named " + name;
GraalError.guarantee(method != null, "Could not find %s.%s (%s)", declaringClass, name, isStatic ? "static" : "non-static");
return method;
}

View File

@ -26,8 +26,8 @@ import org.graalvm.compiler.word.Word.Opcode;
import org.graalvm.compiler.word.Word.Operation;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Pointer;
import org.graalvm.word.Signed;
import org.graalvm.word.Unsigned;
import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordBase;
/**
@ -41,8 +41,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -56,8 +56,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -71,8 +71,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -86,8 +86,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -101,8 +101,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -116,8 +116,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -131,8 +131,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -146,8 +146,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -161,8 +161,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -275,8 +275,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -290,8 +290,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -305,8 +305,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -320,8 +320,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -335,8 +335,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -350,8 +350,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -365,8 +365,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -380,8 +380,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -395,8 +395,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -509,8 +509,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -523,8 +523,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -537,8 +537,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -551,8 +551,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -565,8 +565,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -579,8 +579,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -593,8 +593,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -607,8 +607,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -621,8 +621,8 @@ public final class BarrieredAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -725,8 +725,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -739,8 +739,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -753,8 +753,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -767,8 +767,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -781,8 +781,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -795,8 +795,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -809,8 +809,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -823,8 +823,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -837,8 +837,8 @@ public final class BarrieredAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access

View File

@ -26,8 +26,8 @@ import org.graalvm.compiler.word.Word.Opcode;
import org.graalvm.compiler.word.Word.Operation;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Pointer;
import org.graalvm.word.Signed;
import org.graalvm.word.Unsigned;
import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordBase;
/**
@ -41,8 +41,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -56,8 +56,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -71,8 +71,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -86,8 +86,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -101,8 +101,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -116,8 +116,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -131,8 +131,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -146,8 +146,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -161,8 +161,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -275,8 +275,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -290,8 +290,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -305,8 +305,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -320,8 +320,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -335,8 +335,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -350,8 +350,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -365,8 +365,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -380,8 +380,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -395,8 +395,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -509,8 +509,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -523,8 +523,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -537,8 +537,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -551,8 +551,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -565,8 +565,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -579,8 +579,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -593,8 +593,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -607,8 +607,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -621,8 +621,8 @@ public final class ObjectAccess {
/**
* Reads the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -725,8 +725,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -739,8 +739,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -753,8 +753,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -767,8 +767,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -781,8 +781,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -795,8 +795,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -809,8 +809,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -823,8 +823,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access
@ -837,8 +837,8 @@ public final class ObjectAccess {
/**
* Writes the memory at address {@code (object + offset)}. The offset is in bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param object the base object for the memory access

View File

@ -51,12 +51,21 @@ import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
import org.graalvm.word.ComparableWord;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.Pointer;
import org.graalvm.word.Signed;
import org.graalvm.word.Unsigned;
import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordBase;
import org.graalvm.word.WordFactory;
public abstract class Word extends WordFactory implements Signed, Unsigned, Pointer {
public abstract class Word extends WordFactory implements SignedWord, UnsignedWord, Pointer {
static {
assert WordFactory.boxFactory == null : "BoxFactory must be initialized only once.";
WordFactory.boxFactory = new BoxFactoryImpl();
}
public static void ensureInitialized() {
/* Calling this method ensures that the static initializer has been executed. */
}
/**
* Links a method to a canonical operation represented by an {@link Opcode} val.
@ -166,13 +175,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = AddNode.class)
public Word add(Signed val) {
public Word add(SignedWord val) {
return add((Word) val);
}
@Override
@Operation(node = AddNode.class)
public Word add(Unsigned val) {
public Word add(UnsignedWord val) {
return add((Word) val);
}
@ -189,13 +198,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = SubNode.class)
public Word subtract(Signed val) {
public Word subtract(SignedWord val) {
return subtract((Word) val);
}
@Override
@Operation(node = SubNode.class)
public Word subtract(Unsigned val) {
public Word subtract(UnsignedWord val) {
return subtract((Word) val);
}
@ -212,13 +221,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = MulNode.class)
public Word multiply(Signed val) {
public Word multiply(SignedWord val) {
return multiply((Word) val);
}
@Override
@Operation(node = MulNode.class)
public Word multiply(Unsigned val) {
public Word multiply(UnsignedWord val) {
return multiply((Word) val);
}
@ -235,7 +244,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = SignedDivNode.class)
public Word signedDivide(Signed val) {
public Word signedDivide(SignedWord val) {
return signedDivide((Word) val);
}
@ -252,7 +261,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = UnsignedDivNode.class)
public Word unsignedDivide(Unsigned val) {
public Word unsignedDivide(UnsignedWord val) {
return unsignedDivide((Word) val);
}
@ -269,7 +278,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = SignedRemNode.class)
public Word signedRemainder(Signed val) {
public Word signedRemainder(SignedWord val) {
return signedRemainder((Word) val);
}
@ -286,7 +295,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = UnsignedRemNode.class)
public Word unsignedRemainder(Unsigned val) {
public Word unsignedRemainder(UnsignedWord val) {
return unsignedRemainder((Word) val);
}
@ -303,7 +312,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = LeftShiftNode.class, rightOperandIsInt = true)
public Word shiftLeft(Unsigned val) {
public Word shiftLeft(UnsignedWord val) {
return shiftLeft((Word) val);
}
@ -320,7 +329,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = RightShiftNode.class, rightOperandIsInt = true)
public Word signedShiftRight(Unsigned val) {
public Word signedShiftRight(UnsignedWord val) {
return signedShiftRight((Word) val);
}
@ -337,7 +346,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true)
public Word unsignedShiftRight(Unsigned val) {
public Word unsignedShiftRight(UnsignedWord val) {
return unsignedShiftRight((Word) val);
}
@ -354,13 +363,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = AndNode.class)
public Word and(Signed val) {
public Word and(SignedWord val) {
return and((Word) val);
}
@Override
@Operation(node = AndNode.class)
public Word and(Unsigned val) {
public Word and(UnsignedWord val) {
return and((Word) val);
}
@ -377,13 +386,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = OrNode.class)
public Word or(Signed val) {
public Word or(SignedWord val) {
return or((Word) val);
}
@Override
@Operation(node = OrNode.class)
public Word or(Unsigned val) {
public Word or(UnsignedWord val) {
return or((Word) val);
}
@ -400,13 +409,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(node = XorNode.class)
public Word xor(Signed val) {
public Word xor(SignedWord val) {
return xor((Word) val);
}
@Override
@Operation(node = XorNode.class)
public Word xor(Unsigned val) {
public Word xor(UnsignedWord val) {
return xor((Word) val);
}
@ -447,13 +456,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ)
public boolean equal(Signed val) {
public boolean equal(SignedWord val) {
return equal((Word) val);
}
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ)
public boolean equal(Unsigned val) {
public boolean equal(UnsignedWord val) {
return equal((Word) val);
}
@ -476,13 +485,13 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.NE)
public boolean notEqual(Signed val) {
public boolean notEqual(SignedWord val) {
return notEqual((Word) val);
}
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.NE)
public boolean notEqual(Unsigned val) {
public boolean notEqual(UnsignedWord val) {
return notEqual((Word) val);
}
@ -499,7 +508,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.LT)
public boolean lessThan(Signed val) {
public boolean lessThan(SignedWord val) {
return lessThan((Word) val);
}
@ -516,7 +525,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.LE)
public boolean lessOrEqual(Signed val) {
public boolean lessOrEqual(SignedWord val) {
return lessOrEqual((Word) val);
}
@ -533,7 +542,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.GT)
public boolean greaterThan(Signed val) {
public boolean greaterThan(SignedWord val) {
return greaterThan((Word) val);
}
@ -550,7 +559,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.GE)
public boolean greaterOrEqual(Signed val) {
public boolean greaterOrEqual(SignedWord val) {
return greaterOrEqual((Word) val);
}
@ -567,7 +576,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.BT)
public boolean belowThan(Unsigned val) {
public boolean belowThan(UnsignedWord val) {
return belowThan((Word) val);
}
@ -584,7 +593,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.BE)
public boolean belowOrEqual(Unsigned val) {
public boolean belowOrEqual(UnsignedWord val) {
return belowOrEqual((Word) val);
}
@ -601,7 +610,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.AT)
public boolean aboveThan(Unsigned val) {
public boolean aboveThan(UnsignedWord val) {
return aboveThan((Word) val);
}
@ -618,7 +627,7 @@ public abstract class Word extends WordFactory implements Signed, Unsigned, Poin
@Override
@Operation(opcode = Opcode.COMPARISON, condition = Condition.AE)
public boolean aboveOrEqual(Unsigned val) {
public boolean aboveOrEqual(UnsignedWord val) {
return aboveOrEqual((Word) val);
}

View File

@ -76,6 +76,7 @@ public class WordTypes {
this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class);
this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class);
Word.ensureInitialized();
this.wordImplType.initialize();
}

View File

@ -25,7 +25,7 @@
package org.graalvm.options;
/**
* Classifies options in several categories depending on who this option is relevant for.
* Categorizes options according to user relevance.
*
* @since 1.0
*/

View File

@ -27,7 +27,7 @@ package org.graalvm.options;
import java.util.Objects;
/**
* Represents meta-data for a single option.
* Represents metadata for a single option.
*
* @since 1.0
*/
@ -48,7 +48,7 @@ public final class OptionDescriptor {
}
/**
* Returns the option name of the option represented by this descriptor.
* Returns the name of the option that this descriptor represents.
*
* @since 1.0
*/
@ -185,7 +185,7 @@ public final class OptionDescriptor {
}
/**
* Defines whether this option is deprecated. The default value for deprecated is
* Defines if this option is deprecated. The default value for deprecated is
* <code>false</code>. This can be used to evolve options between releases.
*
* @since 1.0

View File

@ -57,14 +57,14 @@ public interface OptionDescriptors extends Iterable<OptionDescriptor> {
/**
* Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option
* descriptor set doesn't contain a matching option name.
* descriptor set does not contain a matching option name.
*
* @since 1.0
*/
OptionDescriptor get(String optionName);
/**
* Create a union options descriptor out of multiple given descriptors. The operation
* Creates a union options descriptor out of multiple given descriptors. The operation
* descriptors are not checked for duplicate keys. The option descriptors are iterated in
* declaration order.
*
@ -89,7 +89,7 @@ public interface OptionDescriptors extends Iterable<OptionDescriptor> {
Iterator<OptionDescriptor> iterator();
/**
* Create an {@link OptionDescriptors} instance from a list. The option descriptors
* Creates an {@link OptionDescriptors} instance from a list. The option descriptors
* implementation is backed by a {@link LinkedHashMap} that preserves ordering.
*
* @since 1.0

View File

@ -27,7 +27,7 @@ package org.graalvm.options;
import java.util.Objects;
/**
* Represents the option key for a option specification.
* Represents the option key for an option specification.
*
* @since 1.0
*/
@ -48,12 +48,12 @@ public final class OptionKey<T> {
this.defaultValue = defaultValue;
this.type = OptionType.defaultType(defaultValue);
if (type == null) {
throw new IllegalArgumentException("No default type specified for type " + defaultValue.getClass().getName() + ". Specify the option type explicitely to resolve this.");
throw new IllegalArgumentException("No default type specified for type " + defaultValue.getClass().getName() + ". Specify the option type explicitly to resolve this.");
}
}
/**
* Contructs a new option key givena default value and option key. The default value and the
* Constructs a new option key given a default value and option key. The default value and the
* type must not be <code>null</code>.
*
* @since 1.0

View File

@ -31,7 +31,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
/**
* Represents a type of an option that allows to convert string values to a java value.
* Represents a type of an option that allows to convert string values to Java values.
*
* @since 1.0
*/
@ -43,13 +43,13 @@ public final class OptionType<T> {
private final T defaultValue;
/**
* Constructs a new option type with name, defaultValue and function that allows to convert a
* Constructs a new option type with name, defaultValue, and function that allows to convert a
* string to the option type.
*
* @param name the name of the type to identify it
* @param defaultValue the default value to use if no value is given
* @param stringConverter a function that converts a string value to the actual option value.
* Can throw {@link IllegalArgumentException} to indicate an invalid string.
* @param name the name of the type.
* @param defaultValue the default value to use if no value is given.
* @param stringConverter a function that converts a string value to the option value. Can throw
* {@link IllegalArgumentException} to indicate an invalid string.
* @param validator used for validating the option value. Throws
* {@link IllegalArgumentException} if the value is invalid.
*
@ -67,13 +67,13 @@ public final class OptionType<T> {
}
/**
* Constructs a new option type with name, defaultValue and function that allows to convert a
* Constructs a new option type with name, defaultValue, and function that allows to convert a
* string to the option type.
*
* @param name the name of the type to identify it
* @param defaultValue the default value to use if no value is given
* @param stringConverter a function that converts a string value to the actual option value.
* Can throw {@link IllegalArgumentException} to indicate an invalid string.
* @param name the name of the type.
* @param defaultValue the default value to use if no value is given.
* @param stringConverter a function that converts a string value to the option value. Can throw
* {@link IllegalArgumentException} to indicate an invalid string.
*
* @since 1.0
*/
@ -85,7 +85,7 @@ public final class OptionType<T> {
}
/**
* Returns the default value of this type, to be used if no value is available.
* Returns the default value of this type. Used if no value is available.
*
* @since 1.0
*/
@ -103,7 +103,7 @@ public final class OptionType<T> {
}
/**
* Converts a string value, validates it and converts it to an object of this type.
* Converts a string value, validates it, and converts it to an object of this type.
*
* @throws IllegalArgumentException if the value is invalid or cannot be converted.
* @since 1.0
@ -115,7 +115,8 @@ public final class OptionType<T> {
}
/**
* Validates an option value and throws an {@link IllegalArgumentException} if it is invalid.
* Validates an option value and throws an {@link IllegalArgumentException} if the value is
* invalid.
*
* @throws IllegalArgumentException if the value is invalid or cannot be converted.
* @since 1.0
@ -199,7 +200,7 @@ public final class OptionType<T> {
/**
* Returns the default option type for a given value. Returns <code>null</code> if no default
* option type is available for this java type.
* option type is available for this Java type.
*
* @since 1.0
*/

View File

@ -42,8 +42,8 @@ public interface OptionValues {
* Sets the value of {@code optionKey} to {@code value}.
*
* @throws IllegalArgumentException if the given value is not {@link OptionType#validate(Object)
* validated} by the {@link OptionKey#getType() option type} of the key. Please note
* that the operation does not fail if the option key is not described by any of the
* validated} by the {@link OptionKey#getType() option type} of the key. Note that
* the operation succeeds if the option key is not described by any of the
* associated {@link #getDescriptors() descriptors}.
*
* @since 1.0

View File

@ -1,73 +0,0 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.word;
/**
* A {@link Unsigned} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for description of the properties of
* atomic variables.
*/
public class AtomicUnsigned extends AtomicWord<Unsigned> {
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the previous value
*/
public final Unsigned getAndAdd(Unsigned delta) {
return WordFactory.unsigned(value.getAndAdd(delta.rawValue()));
}
/**
* Atomically adds the given value to the current value.
*
* @param delta the value to add
* @return the updated value
*/
public final Unsigned addAndGet(Unsigned delta) {
return WordFactory.unsigned(value.addAndGet(delta.rawValue()));
}
/**
* Atomically subtracts the given value from the current value.
*
* @param delta the value to add
* @return the previous value
*/
public final Unsigned getAndSubtract(Unsigned delta) {
return WordFactory.unsigned(value.getAndAdd(-delta.rawValue()));
}
/**
* Atomically subtracts the given value from the current value.
*
* @param delta the value to add
* @return the updated value
*/
public final Unsigned subtractAndGet(Unsigned delta) {
return WordFactory.unsigned(value.addAndGet(-delta.rawValue()));
}
}

View File

@ -1,93 +0,0 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.word;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
/**
* A {@link WordBase word} value that may be updated atomically. See the
* {@link java.util.concurrent.atomic} package specification for description of the properties of
* atomic variables.
*
* Similar to {@link AtomicReference}, but for {@link WordBase word} types. A dedicated
* implementation is necessary because Object and word types cannot be mixed.
*/
public class AtomicWord<T extends WordBase> {
/**
* For simplicity, we convert the word value to a long and delegate to existing atomic
* operations.
*/
protected final AtomicLong value;
/**
* Creates a new AtomicWord with initial value {@link WordFactory#zero}.
*/
public AtomicWord() {
value = new AtomicLong();
}
/**
* Gets the current value.
*
* @return the current value
*/
public final T get() {
return WordFactory.unsigned(value.get());
}
/**
* Sets to the given value.
*
* @param newValue the new value
*/
public final void set(T newValue) {
value.set(newValue.rawValue());
}
/**
* Atomically sets to the given value and returns the old value.
*
* @param newValue the new value
* @return the previous value
*/
public final T getAndSet(T newValue) {
return WordFactory.unsigned(value.getAndSet(newValue.rawValue()));
}
/**
* Atomically sets the value to the given updated value if the current value {@code ==} the
* expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that the actual value was not
* equal to the expected value.
*/
public final boolean compareAndSet(T expect, T update) {
return value.compareAndSet(expect.rawValue(), update.rawValue());
}
}

View File

@ -31,7 +31,7 @@ package org.graalvm.word;
* null checks, read- or write barriers. Even when the VM uses compressed pointers, then readObject
* and writeObject methods access uncompressed pointers.
*/
public interface Pointer extends Unsigned, PointerBase {
public interface Pointer extends UnsignedWord, PointerBase {
/**
* Unsafe conversion of this Pointer to a Java language object. No correctness checks or type
@ -55,8 +55,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -69,8 +69,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -83,8 +83,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -97,8 +97,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -111,8 +111,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -125,8 +125,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -139,8 +139,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -153,8 +153,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -167,8 +167,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -271,8 +271,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -285,8 +285,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -299,8 +299,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -313,8 +313,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -327,8 +327,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -341,8 +341,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -355,8 +355,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -369,8 +369,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -383,8 +383,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Initializes the memory at address {@code (this + offset)}. Both the base address and offset
* are in bytes. The memory must be uninitialized or zero prior to this operation.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -397,8 +397,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -511,8 +511,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -524,8 +524,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -537,8 +537,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -550,8 +550,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -563,8 +563,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -576,8 +576,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -589,8 +589,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -602,8 +602,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -615,8 +615,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Reads the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -709,8 +709,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -722,8 +722,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -735,8 +735,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -748,8 +748,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -761,8 +761,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -774,8 +774,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -787,8 +787,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -800,8 +800,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -813,8 +813,8 @@ public interface Pointer extends Unsigned, PointerBase {
* Writes the memory at address {@code (this + offset)}. Both the base address and offset are in
* bytes.
* <p>
* The offset is always treated as a {@link Signed} value. However, the static type is
* {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller
* The offset is always treated as a {@link SignedWord} value. However, the static type is
* {@link WordBase} to avoid the frequent casts of {@link UnsignedWord} values (where the caller
* knows that the highest-order bit of the unsigned value is never used).
*
* @param offset the signed offset for the memory access
@ -940,25 +940,25 @@ public interface Pointer extends Unsigned, PointerBase {
// It is therefore safe that they return a static type of Pointer instead of Unsigned.
@Override
Pointer add(Unsigned val);
Pointer add(UnsignedWord val);
@Override
Pointer add(int val);
@Override
Pointer subtract(Unsigned val);
Pointer subtract(UnsignedWord val);
@Override
Pointer subtract(int val);
@Override
Pointer and(Unsigned val);
Pointer and(UnsignedWord val);
@Override
Pointer and(int val);
@Override
Pointer or(Unsigned val);
Pointer or(UnsignedWord val);
@Override
Pointer or(int val);

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.word;
/**
* Utility methods on Pointers.
*/
public final class PointerUtils {
private PointerUtils() {
// This is a class of static methods, so no need for any instances.
}
/**
* The value of a null Pointer.
*
* @return A null Pointer value.
*/
public static <T extends PointerBase> T nullPointer() {
/* This method will be deleted soon. */
return WordFactory.nullPointer();
}
/**
* Predicate to check for the null Pointer value.
*
* @return Whether that Pointer is the null Pointer.
*/
public static boolean isNull(ComparableWord that) {
/* This method will be deleted soon. */
return ((PointerBase) that).isNull();
}
/**
* Predicate to check for a non-null Pointer value.
*
* @return Whether that Pointer is not the null Pointer.
*/
public static boolean isNonNull(ComparableWord that) {
/* This method will be deleted soon. */
return ((PointerBase) that).isNonNull();
}
/**
* Round a Pointer down to the nearest smaller multiple.
*
* @param that The Pointer to be rounded up.
* @param multiple The multiple to which that Pointer should be decreased.
* @return That Pointer, but rounded down.
*/
public static Pointer roundDown(PointerBase that, Unsigned multiple) {
return (Pointer) UnsignedUtils.roundDown((Unsigned) that, multiple);
}
/**
* Round a Pointer up to the nearest larger multiple.
*
* @param that The Pointer to be rounded up.
* @param multiple The multiple to which that Pointer should be increased.
* @return That Pointer, but rounded up.
*/
public static Pointer roundUp(PointerBase that, Unsigned multiple) {
return (Pointer) UnsignedUtils.roundUp((Unsigned) that, multiple);
}
/**
* Check that a Pointer is an even multiple.
*
* @param that The Pointer to be verified as a multiple.
* @param multiple The multiple against which the Pointer should be verified.
* @return true if that Pointer is a multiple, false otherwise.
*/
public static boolean isAMultiple(PointerBase that, Unsigned multiple) {
return that.equal(PointerUtils.roundDown(that, multiple));
}
/**
* Return the distance between two Pointers.
*
* @param pointer1 A first Pointer.
* @param pointer2 A second Pointer.
* @return The distance in bytes between the two Pointers.
*/
public static Unsigned absoluteDifference(PointerBase pointer1, PointerBase pointer2) {
Pointer p1 = (Pointer) pointer1;
Pointer p2 = (Pointer) pointer2;
final Unsigned result;
if (p1.aboveOrEqual(p2)) {
result = p1.subtract(p2);
} else {
result = p2.subtract(p1);
}
return result;
}
/**
* The minimum of two Pointers.
*
* @param x A Pointer.
* @param y Another Pointer.
* @return The whichever Pointer is smaller.
*/
public static <T extends PointerBase> T min(T x, T y) {
return (((Pointer) x).belowOrEqual((Pointer) y)) ? x : y;
}
/**
* The maximum of two Pointers.
*
* @param x A Pointer.
* @param y Another Pointer.
* @return The whichever Pointer is larger.
*/
public static <T extends PointerBase> T max(T x, T y) {
return (((Pointer) x).aboveOrEqual((Pointer) y)) ? x : y;
}
}

View File

@ -24,7 +24,7 @@
*/
package org.graalvm.word;
public interface Signed extends ComparableWord {
public interface SignedWord extends ComparableWord {
/**
* Returns a Signed whose value is {@code (this + val)}.
@ -32,7 +32,7 @@ public interface Signed extends ComparableWord {
* @param val value to be added to this Signed.
* @return {@code this + val}
*/
Signed add(Signed val);
SignedWord add(SignedWord val);
/**
* Returns a Signed whose value is {@code (this - val)}.
@ -40,7 +40,7 @@ public interface Signed extends ComparableWord {
* @param val value to be subtracted from this Signed.
* @return {@code this - val}
*/
Signed subtract(Signed val);
SignedWord subtract(SignedWord val);
/**
* Returns a Signed whose value is {@code (this * val)}.
@ -48,7 +48,7 @@ public interface Signed extends ComparableWord {
* @param val value to be multiplied by this Signed.
* @return {@code this * val}
*/
Signed multiply(Signed val);
SignedWord multiply(SignedWord val);
/**
* Returns a Signed whose value is {@code (this / val)}.
@ -56,7 +56,7 @@ public interface Signed extends ComparableWord {
* @param val value by which this Signed is to be divided.
* @return {@code this / val}
*/
Signed signedDivide(Signed val);
SignedWord signedDivide(SignedWord val);
/**
* Returns a Signed whose value is {@code (this % val)}.
@ -64,7 +64,7 @@ public interface Signed extends ComparableWord {
* @param val value by which this Signed is to be divided, and the remainder computed.
* @return {@code this % val}
*/
Signed signedRemainder(Signed val);
SignedWord signedRemainder(SignedWord val);
/**
* Returns a Signed whose value is {@code (this << n)}.
@ -72,7 +72,7 @@ public interface Signed extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this << n}
*/
Signed shiftLeft(Unsigned n);
SignedWord shiftLeft(UnsignedWord n);
/**
* Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
@ -80,7 +80,7 @@ public interface Signed extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this >> n}
*/
Signed signedShiftRight(Unsigned n);
SignedWord signedShiftRight(UnsignedWord n);
/**
* Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
@ -89,7 +89,7 @@ public interface Signed extends ComparableWord {
* @param val value to be AND'ed with this Signed.
* @return {@code this & val}
*/
Signed and(Signed val);
SignedWord and(SignedWord val);
/**
* Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
@ -98,7 +98,7 @@ public interface Signed extends ComparableWord {
* @param val value to be OR'ed with this Signed.
* @return {@code this | val}
*/
Signed or(Signed val);
SignedWord or(SignedWord val);
/**
* Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
@ -107,7 +107,7 @@ public interface Signed extends ComparableWord {
* @param val value to be XOR'ed with this Signed.
* @return {@code this ^ val}
*/
Signed xor(Signed val);
SignedWord xor(SignedWord val);
/**
* Returns a Signed whose value is {@code (~this)}. (This method returns a negative value if and
@ -115,7 +115,7 @@ public interface Signed extends ComparableWord {
*
* @return {@code ~this}
*/
Signed not();
SignedWord not();
/**
* Compares this Signed with the specified value.
@ -123,7 +123,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this == val}
*/
boolean equal(Signed val);
boolean equal(SignedWord val);
/**
* Compares this Signed with the specified value.
@ -131,7 +131,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this != val}
*/
boolean notEqual(Signed val);
boolean notEqual(SignedWord val);
/**
* Compares this Signed with the specified value.
@ -139,7 +139,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this < val}
*/
boolean lessThan(Signed val);
boolean lessThan(SignedWord val);
/**
* Compares this Signed with the specified value.
@ -147,7 +147,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this <= val}
*/
boolean lessOrEqual(Signed val);
boolean lessOrEqual(SignedWord val);
/**
* Compares this Signed with the specified value.
@ -155,7 +155,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this > val}
*/
boolean greaterThan(Signed val);
boolean greaterThan(SignedWord val);
/**
* Compares this Signed with the specified value.
@ -163,7 +163,7 @@ public interface Signed extends ComparableWord {
* @param val value to which this Signed is to be compared.
* @return {@code this >= val}
*/
boolean greaterOrEqual(Signed val);
boolean greaterOrEqual(SignedWord val);
/**
* Returns a Signed whose value is {@code (this + val)}.
@ -171,7 +171,7 @@ public interface Signed extends ComparableWord {
* @param val value to be added to this Signed.
* @return {@code this + val}
*/
Signed add(int val);
SignedWord add(int val);
/**
* Returns a Signed whose value is {@code (this - val)}.
@ -179,7 +179,7 @@ public interface Signed extends ComparableWord {
* @param val value to be subtracted from this Signed.
* @return {@code this - val}
*/
Signed subtract(int val);
SignedWord subtract(int val);
/**
* Returns a Signed whose value is {@code (this * val)}.
@ -187,7 +187,7 @@ public interface Signed extends ComparableWord {
* @param val value to be multiplied by this Signed.
* @return {@code this * val}
*/
Signed multiply(int val);
SignedWord multiply(int val);
/**
* Returns a Signed whose value is {@code (this / val)}.
@ -195,7 +195,7 @@ public interface Signed extends ComparableWord {
* @param val value by which this Signed is to be divided.
* @return {@code this / val}
*/
Signed signedDivide(int val);
SignedWord signedDivide(int val);
/**
* Returns a Signed whose value is {@code (this % val)}.
@ -203,7 +203,7 @@ public interface Signed extends ComparableWord {
* @param val value by which this Signed is to be divided, and the remainder computed.
* @return {@code this % val}
*/
Signed signedRemainder(int val);
SignedWord signedRemainder(int val);
/**
* Returns a Signed whose value is {@code (this << n)}.
@ -211,7 +211,7 @@ public interface Signed extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this << n}
*/
Signed shiftLeft(int n);
SignedWord shiftLeft(int n);
/**
* Returns a Signed whose value is {@code (this >> n)}. Sign extension is performed.
@ -219,7 +219,7 @@ public interface Signed extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this >> n}
*/
Signed signedShiftRight(int n);
SignedWord signedShiftRight(int n);
/**
* Returns a Signed whose value is {@code (this & val)}. (This method returns a negative Signed
@ -228,7 +228,7 @@ public interface Signed extends ComparableWord {
* @param val value to be AND'ed with this Signed.
* @return {@code this & val}
*/
Signed and(int val);
SignedWord and(int val);
/**
* Returns a Signed whose value is {@code (this | val)}. (This method returns a negative Signed
@ -237,7 +237,7 @@ public interface Signed extends ComparableWord {
* @param val value to be OR'ed with this Signed.
* @return {@code this | val}
*/
Signed or(int val);
SignedWord or(int val);
/**
* Returns a Signed whose value is {@code (this ^ val)}. (This method returns a negative Signed
@ -246,7 +246,7 @@ public interface Signed extends ComparableWord {
* @param val value to be XOR'ed with this Signed.
* @return {@code this ^ val}
*/
Signed xor(int val);
SignedWord xor(int val);
/**
* Compares this Signed with the specified value.

View File

@ -1,90 +0,0 @@
/*
* Copyright (c) 2015, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.word;
/**
* Utility methods on Unsigned values.
*/
public final class UnsignedUtils {
private UnsignedUtils() {
// This is a class of static methods, so no need for any instances.
}
/**
* Round an Unsigned down to the nearest smaller multiple.
*
* @param that The Unsigned to be rounded down.
* @param multiple The multiple to which that Unsigned should be decreased.
* @return That Unsigned, but rounded down.
*/
public static Unsigned roundDown(Unsigned that, Unsigned multiple) {
return that.unsignedDivide(multiple).multiply(multiple);
}
/**
* Round an Unsigned up to the nearest larger multiple.
*
* @param that The Unsigned to be rounded up.
* @param multiple The multiple to which that Unsigned should be increased.
* @return That Unsigned, but rounded up.
*/
public static Unsigned roundUp(Unsigned that, Unsigned multiple) {
return UnsignedUtils.roundDown(that.add(multiple.subtract(1)), multiple);
}
/**
* Check that an Unsigned is an even multiple.
*
* @param that The Unsigned to be verified as a multiple.
* @param multiple The multiple against which the Unsigned should be verified.
* @return true if that Unsigned is a multiple, false otherwise.
*/
public static boolean isAMultiple(Unsigned that, Unsigned multiple) {
return that.equal(UnsignedUtils.roundDown(that, multiple));
}
/**
* The minimum of two Unsigneds.
*
* @param x An Unsigned.
* @param y Another Unsigned.
* @return The whichever Unsigned is smaller.
*/
public static Unsigned min(Unsigned x, Unsigned y) {
return (x.belowOrEqual(y)) ? x : y;
}
/**
* The maximum of two Unsigneds.
*
* @param x An Unsigned.
* @param y Another Unsigned.
* @return The whichever Unsigned is larger.
*/
public static Unsigned max(Unsigned x, Unsigned y) {
return (x.aboveOrEqual(y)) ? x : y;
}
}

View File

@ -24,7 +24,7 @@
*/
package org.graalvm.word;
public interface Unsigned extends ComparableWord {
public interface UnsignedWord extends ComparableWord {
/**
* Returns a Unsigned whose value is {@code (this + val)}.
@ -32,7 +32,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be added to this Unsigned.
* @return {@code this + val}
*/
Unsigned add(Unsigned val);
UnsignedWord add(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this - val)}.
@ -40,7 +40,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be subtracted from this Unsigned.
* @return {@code this - val}
*/
Unsigned subtract(Unsigned val);
UnsignedWord subtract(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this * val)}.
@ -48,7 +48,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be multiplied by this Unsigned.
* @return {@code this * val}
*/
Unsigned multiply(Unsigned val);
UnsignedWord multiply(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this / val)}.
@ -56,7 +56,7 @@ public interface Unsigned extends ComparableWord {
* @param val value by which this Unsigned is to be divided.
* @return {@code this / val}
*/
Unsigned unsignedDivide(Unsigned val);
UnsignedWord unsignedDivide(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this % val)}.
@ -64,7 +64,7 @@ public interface Unsigned extends ComparableWord {
* @param val value by which this Unsigned is to be divided, and the remainder computed.
* @return {@code this % val}
*/
Unsigned unsignedRemainder(Unsigned val);
UnsignedWord unsignedRemainder(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this << n)}.
@ -72,7 +72,7 @@ public interface Unsigned extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this << n}
*/
Unsigned shiftLeft(Unsigned n);
UnsignedWord shiftLeft(UnsignedWord n);
/**
* Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
@ -80,7 +80,7 @@ public interface Unsigned extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this >> n}
*/
Unsigned unsignedShiftRight(Unsigned n);
UnsignedWord unsignedShiftRight(UnsignedWord n);
/**
* Returns a Unsigned whose value is {@code (this & val)}.
@ -88,7 +88,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be AND'ed with this Unsigned.
* @return {@code this & val}
*/
Unsigned and(Unsigned val);
UnsignedWord and(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this | val)}.
@ -96,7 +96,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be OR'ed with this Unsigned.
* @return {@code this | val}
*/
Unsigned or(Unsigned val);
UnsignedWord or(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this ^ val)}.
@ -104,14 +104,14 @@ public interface Unsigned extends ComparableWord {
* @param val value to be XOR'ed with this Unsigned.
* @return {@code this ^ val}
*/
Unsigned xor(Unsigned val);
UnsignedWord xor(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (~this)}.
*
* @return {@code ~this}
*/
Unsigned not();
UnsignedWord not();
/**
* Compares this Unsigned with the specified value.
@ -119,7 +119,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this == val}
*/
boolean equal(Unsigned val);
boolean equal(UnsignedWord val);
/**
* Compares this Unsigned with the specified value.
@ -127,7 +127,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this != val}
*/
boolean notEqual(Unsigned val);
boolean notEqual(UnsignedWord val);
/**
* Compares this Unsigned with the specified value.
@ -135,7 +135,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this < val}
*/
boolean belowThan(Unsigned val);
boolean belowThan(UnsignedWord val);
/**
* Compares this Unsigned with the specified value.
@ -143,7 +143,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this <= val}
*/
boolean belowOrEqual(Unsigned val);
boolean belowOrEqual(UnsignedWord val);
/**
* Compares this Unsigned with the specified value.
@ -151,7 +151,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this > val}
*/
boolean aboveThan(Unsigned val);
boolean aboveThan(UnsignedWord val);
/**
* Compares this Unsigned with the specified value.
@ -159,7 +159,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to which this Unsigned is to be compared.
* @return {@code this >= val}
*/
boolean aboveOrEqual(Unsigned val);
boolean aboveOrEqual(UnsignedWord val);
/**
* Returns a Unsigned whose value is {@code (this + val)}.
@ -170,7 +170,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be added to this Unsigned.
* @return {@code this + val}
*/
Unsigned add(int val);
UnsignedWord add(int val);
/**
* Returns a Unsigned whose value is {@code (this - val)}.
@ -181,7 +181,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be subtracted from this Unsigned.
* @return {@code this - val}
*/
Unsigned subtract(int val);
UnsignedWord subtract(int val);
/**
* Returns a Unsigned whose value is {@code (this * val)}.
@ -192,7 +192,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be multiplied by this Unsigned.
* @return {@code this * val}
*/
Unsigned multiply(int val);
UnsignedWord multiply(int val);
/**
* Returns a Unsigned whose value is {@code (this / val)}.
@ -203,7 +203,7 @@ public interface Unsigned extends ComparableWord {
* @param val value by which this Unsigned is to be divided.
* @return {@code this / val}
*/
Unsigned unsignedDivide(int val);
UnsignedWord unsignedDivide(int val);
/**
* Returns a Unsigned whose value is {@code (this % val)}.
@ -214,7 +214,7 @@ public interface Unsigned extends ComparableWord {
* @param val value by which this Unsigned is to be divided, and the remainder computed.
* @return {@code this % val}
*/
Unsigned unsignedRemainder(int val);
UnsignedWord unsignedRemainder(int val);
/**
* Returns a Unsigned whose value is {@code (this << n)}.
@ -225,7 +225,7 @@ public interface Unsigned extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this << n}
*/
Unsigned shiftLeft(int n);
UnsignedWord shiftLeft(int n);
/**
* Returns a Unsigned whose value is {@code (this >>> n)}. No sign extension is performed.
@ -236,7 +236,7 @@ public interface Unsigned extends ComparableWord {
* @param n shift distance, in bits.
* @return {@code this >> n}
*/
Unsigned unsignedShiftRight(int n);
UnsignedWord unsignedShiftRight(int n);
/**
* Returns a Unsigned whose value is {@code (this & val)}.
@ -247,7 +247,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be AND'ed with this Unsigned.
* @return {@code this & val}
*/
Unsigned and(int val);
UnsignedWord and(int val);
/**
* Returns a Unsigned whose value is {@code (this | val)}.
@ -258,7 +258,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be OR'ed with this Unsigned.
* @return {@code this | val}
*/
Unsigned or(int val);
UnsignedWord or(int val);
/**
* Returns a Unsigned whose value is {@code (this ^ val)}.
@ -269,7 +269,7 @@ public interface Unsigned extends ComparableWord {
* @param val value to be XOR'ed with this Unsigned.
* @return {@code this ^ val}
*/
Unsigned xor(int val);
UnsignedWord xor(int val);
/**
* Compares this Unsigned with the specified value.

View File

@ -28,7 +28,6 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
public abstract class WordFactory {
@ -54,19 +53,7 @@ public abstract class WordFactory {
<T extends WordBase> T box(long val);
}
protected static final BoxFactory boxFactory;
static {
try {
/*
* We know the implementation class, but cannot reference it statically because we need
* to break the dependency between the interface and the implementation.
*/
boxFactory = (BoxFactory) Class.forName("org.graalvm.compiler.word.Word$BoxFactoryImpl").getConstructor().newInstance();
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new ExceptionInInitializerError("Could not find and initialize the word type factory. The Graal compiler needs to be on the class path to use the word type.");
}
}
protected static BoxFactory boxFactory;
/**
* We allow subclassing, because only subclasses can access the protected inner classes that we
@ -105,7 +92,7 @@ public abstract class WordFactory {
* @return the value cast to Word
*/
@FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
public static <T extends Unsigned> T unsigned(long val) {
public static <T extends UnsignedWord> T unsigned(long val) {
return boxFactory.box(val);
}
@ -129,7 +116,7 @@ public abstract class WordFactory {
* @return the value cast to Word
*/
@FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
public static <T extends Unsigned> T unsigned(int val) {
public static <T extends UnsignedWord> T unsigned(int val) {
return boxFactory.box(val & 0xffffffffL);
}
@ -141,7 +128,7 @@ public abstract class WordFactory {
* @return the value cast to Word
*/
@FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
public static <T extends Signed> T signed(long val) {
public static <T extends SignedWord> T signed(long val) {
return boxFactory.box(val);
}
@ -153,7 +140,7 @@ public abstract class WordFactory {
* @return the value cast to Word
*/
@FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
public static <T extends Signed> T signed(int val) {
public static <T extends SignedWord> T signed(int val) {
return boxFactory.box(val);
}
}