8184768: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
040ada2f40
commit
76b7f30159
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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) ? ":=" : "=";
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,7 @@ public class WordTypes {
|
||||
this.objectAccessType = metaAccess.lookupJavaType(ObjectAccess.class);
|
||||
this.barrieredAccessType = metaAccess.lookupJavaType(BarrieredAccess.class);
|
||||
|
||||
Word.ensureInitialized();
|
||||
this.wordImplType.initialize();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user