8199755: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
f69402ef44
commit
839458fd21
@ -439,7 +439,7 @@ jdk.internal.vm.compiler_ADD_JAVAC_FLAGS += -parameters -XDstringConcat=inline \
|
||||
#
|
||||
|
||||
jdk.internal.vm.compiler_EXCLUDES += \
|
||||
org.graalvm.collections.test \
|
||||
jdk.internal.vm.compiler.collections.test \
|
||||
org.graalvm.compiler.core.match.processor \
|
||||
org.graalvm.compiler.nodeinfo.processor \
|
||||
org.graalvm.compiler.options.processor \
|
||||
|
@ -47,8 +47,8 @@ ifeq ($(INCLUDE_GRAAL), true)
|
||||
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_MATCH_PROCESSOR, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := \
|
||||
$(SRC_DIR)/org.graalvm.word/src \
|
||||
$(SRC_DIR)/org.graalvm.collections/src \
|
||||
$(SRC_DIR)/jdk.internal.vm.compiler.word/src \
|
||||
$(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.core/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.core.common/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
|
||||
@ -102,7 +102,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
||||
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := \
|
||||
$(SRC_DIR)/org.graalvm.collections/src \
|
||||
$(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.options/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \
|
||||
$(SRC_DIR)/org.graalvm.util/src \
|
||||
@ -118,8 +118,8 @@ ifeq ($(INCLUDE_GRAAL), true)
|
||||
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_REPLACEMENTS_VERIFIER, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := \
|
||||
$(SRC_DIR)/org.graalvm.word/src \
|
||||
$(SRC_DIR)/org.graalvm.collections/src \
|
||||
$(SRC_DIR)/jdk.internal.vm.compiler.word/src \
|
||||
$(SRC_DIR)/jdk.internal.vm.compiler.collections/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.bytecode/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
|
||||
|
@ -30,11 +30,11 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.core.GraalCompilerOptions;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.Management;
|
||||
import org.graalvm.compiler.debug.TTY;
|
||||
import org.graalvm.compiler.debug.DebugContext.Activation;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
@ -52,8 +52,6 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
|
||||
private static final AtomicInteger ids = new AtomicInteger();
|
||||
|
||||
private static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
|
||||
|
||||
private final Main main;
|
||||
|
||||
private OptionValues graalOptions;
|
||||
@ -99,7 +97,7 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
|
||||
final long threadId = Thread.currentThread().getId();
|
||||
|
||||
final boolean printCompilation = GraalCompilerOptions.PrintCompilation.getValue(graalOptions) && !TTY.isSuppressed();
|
||||
final boolean printCompilation = GraalCompilerOptions.PrintCompilation.getValue(graalOptions) && !TTY.isSuppressed() && GraalServices.isThreadAllocatedMemorySupported();
|
||||
if (printCompilation) {
|
||||
TTY.println(getMethodDescription() + "...");
|
||||
}
|
||||
@ -108,7 +106,7 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
final long allocatedBytesBefore;
|
||||
if (printCompilation) {
|
||||
start = System.currentTimeMillis();
|
||||
allocatedBytesBefore = printCompilation ? threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
|
||||
allocatedBytesBefore = GraalServices.getThreadAllocatedBytes(threadId);
|
||||
} else {
|
||||
start = 0L;
|
||||
allocatedBytesBefore = 0L;
|
||||
@ -125,7 +123,7 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
if (printCompilation) {
|
||||
final long stop = System.currentTimeMillis();
|
||||
final int targetCodeSize = compResult != null ? compResult.getTargetCodeSize() : -1;
|
||||
final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId);
|
||||
final long allocatedBytesAfter = GraalServices.getThreadAllocatedBytes(threadId);
|
||||
final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
|
||||
|
||||
TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes));
|
||||
|
@ -45,7 +45,7 @@ import org.graalvm.compiler.graph.Node.NodeIntrinsic;
|
||||
import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
|
||||
import org.graalvm.compiler.hotspot.word.MetaspacePointer;
|
||||
import org.graalvm.compiler.replacements.Snippets;
|
||||
import org.graalvm.word.WordBase;
|
||||
import jdk.internal.vm.compiler.word.WordBase;
|
||||
|
||||
final class GraalFilters {
|
||||
private List<ResolvedJavaType> specialClasses;
|
||||
|
@ -141,7 +141,7 @@ public final class Main {
|
||||
graalOptions = new OptionValues(graalOptions, TieredAOT, options.tiered);
|
||||
}
|
||||
graalOptions = new OptionValues(graalOptions, GeneratePIC, true, ImmutableCode, true);
|
||||
GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler(JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
|
||||
GraalJVMCICompiler graalCompiler = HotSpotGraalCompilerFactory.createCompiler("JAOTC", JVMCI.getRuntime(), graalOptions, CompilerConfigurationFactory.selectFactory(null, graalOptions));
|
||||
HotSpotGraalRuntimeProvider runtime = (HotSpotGraalRuntimeProvider) graalCompiler.getGraalRuntime();
|
||||
HotSpotHostBackend backend = (HotSpotHostBackend) runtime.getCapability(RuntimeProvider.class).getHostBackend();
|
||||
MetaAccessProvider metaAccess = backend.getProviders().getMetaAccess();
|
||||
|
@ -22,8 +22,154 @@
|
||||
*/
|
||||
package org.graalvm.compiler.hotspot.management;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.MBeanRegistrationException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerFactory;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.graalvm.compiler.debug.TTY;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
|
||||
import org.graalvm.compiler.serviceprovider.ServiceProvider;
|
||||
|
||||
/**
|
||||
* Placeholder until next Graal update.
|
||||
* Dynamically registers an MBean with the {@link ManagementFactory#getPlatformMBeanServer()}.
|
||||
*
|
||||
* Polling for an active platform MBean server is done by calling
|
||||
* {@link MBeanServerFactory#findMBeanServer(String)} with an argument value of {@code null}. Once
|
||||
* this returns an non-empty list, {@link ManagementFactory#getPlatformMBeanServer()} can be called
|
||||
* to obtain a reference to the platform MBean server instance.
|
||||
*/
|
||||
public final class HotSpotGraalManagement {
|
||||
@ServiceProvider(HotSpotGraalManagementRegistration.class)
|
||||
public final class HotSpotGraalManagement implements HotSpotGraalManagementRegistration {
|
||||
|
||||
private HotSpotGraalRuntimeMBean bean;
|
||||
private volatile boolean needsRegistration = true;
|
||||
HotSpotGraalManagement nextDeferred;
|
||||
|
||||
@Override
|
||||
public void initialize(HotSpotGraalRuntime runtime) {
|
||||
if (bean == null) {
|
||||
if (runtime.getManagement() != this) {
|
||||
throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName());
|
||||
}
|
||||
try {
|
||||
String name = runtime.getName().replace(':', '_');
|
||||
ObjectName objectName = new ObjectName("org.graalvm.compiler.hotspot:type=" + name);
|
||||
bean = new HotSpotGraalRuntimeMBean(objectName, runtime);
|
||||
registration.add(this);
|
||||
} catch (MalformedObjectNameException err) {
|
||||
err.printStackTrace(TTY.out);
|
||||
}
|
||||
} else if (bean.getRuntime() != runtime) {
|
||||
throw new IllegalArgumentException("Cannot change the runtime a management interface is associated with");
|
||||
}
|
||||
}
|
||||
|
||||
static final class RegistrationThread extends Thread {
|
||||
|
||||
private MBeanServer platformMBeanServer;
|
||||
private HotSpotGraalManagement deferred;
|
||||
|
||||
RegistrationThread() {
|
||||
super("HotSpotGraalManagement Bean Registration");
|
||||
this.setPriority(Thread.MIN_PRIORITY);
|
||||
this.setDaemon(true);
|
||||
this.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll for active MBean server every 2 seconds.
|
||||
*/
|
||||
private static final int POLL_INTERVAL_MS = 2000;
|
||||
|
||||
/**
|
||||
* Adds a {@link HotSpotGraalManagement} to register with an active MBean server when one
|
||||
* becomes available.
|
||||
*/
|
||||
synchronized void add(HotSpotGraalManagement e) {
|
||||
if (deferred != null) {
|
||||
e.nextDeferred = deferred;
|
||||
}
|
||||
deferred = e;
|
||||
|
||||
// Notify the registration thread that there is now
|
||||
// a deferred registration to process
|
||||
notify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes and clears any deferred registrations.
|
||||
*/
|
||||
private void process() {
|
||||
for (HotSpotGraalManagement m = deferred; m != null; m = m.nextDeferred) {
|
||||
HotSpotGraalRuntimeMBean bean = m.bean;
|
||||
if (m.needsRegistration && bean != null) {
|
||||
try {
|
||||
platformMBeanServer.registerMBean(bean, bean.getObjectName());
|
||||
} catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
|
||||
e.printStackTrace(TTY.out);
|
||||
// Registration failed - don't try again
|
||||
m.bean = null;
|
||||
}
|
||||
m.needsRegistration = false;
|
||||
}
|
||||
}
|
||||
deferred = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
// Wait until there are deferred registrations to process
|
||||
while (deferred == null) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
poll();
|
||||
Thread.sleep(POLL_INTERVAL_MS);
|
||||
} catch (InterruptedException e) {
|
||||
// Be verbose about unexpected interruption and then continue
|
||||
e.printStackTrace(TTY.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for active MBean server and if available, processes deferred registrations.
|
||||
*/
|
||||
synchronized void poll() {
|
||||
if (platformMBeanServer == null) {
|
||||
ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
|
||||
if (!servers.isEmpty()) {
|
||||
platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
process();
|
||||
}
|
||||
} else {
|
||||
process();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final RegistrationThread registration = new RegistrationThread();
|
||||
|
||||
@Override
|
||||
public ObjectName poll(boolean sync) {
|
||||
if (sync) {
|
||||
registration.poll();
|
||||
}
|
||||
if (bean == null || needsRegistration) {
|
||||
// initialize() has not been called, it failed or registration failed
|
||||
return null;
|
||||
}
|
||||
return bean.getObjectName();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2018, 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.management;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeList;
|
||||
import javax.management.AttributeNotFoundException;
|
||||
import javax.management.DynamicMBean;
|
||||
import javax.management.InvalidAttributeValueException;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.MBeanOperationInfo;
|
||||
import javax.management.MBeanParameterInfo;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.core.common.SuppressFBWarnings;
|
||||
import org.graalvm.compiler.debug.TTY;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
|
||||
import org.graalvm.compiler.options.OptionDescriptor;
|
||||
import org.graalvm.compiler.options.OptionDescriptors;
|
||||
import org.graalvm.compiler.options.OptionsParser;
|
||||
|
||||
/**
|
||||
* MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
|
||||
*/
|
||||
final class HotSpotGraalRuntimeMBean implements DynamicMBean {
|
||||
|
||||
/**
|
||||
* The runtime instance to which this bean provides a management connection.
|
||||
*/
|
||||
private final HotSpotGraalRuntime runtime;
|
||||
|
||||
/**
|
||||
* The object name under which the bean is registered.
|
||||
*/
|
||||
private final ObjectName objectName;
|
||||
|
||||
HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
|
||||
this.objectName = objectName;
|
||||
this.runtime = runtime;
|
||||
}
|
||||
|
||||
ObjectName getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
HotSpotGraalRuntime getRuntime() {
|
||||
return runtime;
|
||||
}
|
||||
|
||||
private static final boolean DEBUG = Boolean.getBoolean(HotSpotGraalRuntimeMBean.class.getSimpleName() + ".debug");
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name) throws AttributeNotFoundException {
|
||||
String[] result = runtime.getOptionValues(name);
|
||||
String value = result[0];
|
||||
if (value == null) {
|
||||
throw new AttributeNotFoundException(name);
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.printf("getAttribute: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName());
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want")
|
||||
@Override
|
||||
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException {
|
||||
String name = attribute.getName();
|
||||
Object value = attribute.getValue();
|
||||
String svalue = String.valueOf(value);
|
||||
if (DEBUG) {
|
||||
System.out.printf("setAttribute: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName());
|
||||
}
|
||||
String[] result = runtime.setOptionValues(new String[]{name}, new String[]{svalue});
|
||||
if (result[0] != name) {
|
||||
if (result[0] == null) {
|
||||
throw new AttributeNotFoundException(name);
|
||||
}
|
||||
throw new InvalidAttributeValueException(result[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeList getAttributes(String[] names) {
|
||||
String[] values = runtime.getOptionValues(names);
|
||||
AttributeList list = new AttributeList();
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
String value = values[i];
|
||||
String name = names[i];
|
||||
if (value == null) {
|
||||
TTY.printf("No such option named %s%n", name);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.printf("getAttributes: %s = %s (type: %s)%n", name, value, value == null ? "null" : value.getClass().getName());
|
||||
}
|
||||
list.add(new Attribute(name, value));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality on the receiver is what we want")
|
||||
@Override
|
||||
public AttributeList setAttributes(AttributeList attributes) {
|
||||
String[] names = new String[attributes.size()];
|
||||
String[] values = new String[attributes.size()];
|
||||
|
||||
int i = 0;
|
||||
for (Attribute attr : attributes.asList()) {
|
||||
String name = attr.getName();
|
||||
names[i] = name;
|
||||
Object value = attr.getValue();
|
||||
String svalue = String.valueOf(value);
|
||||
values[i] = svalue;
|
||||
if (DEBUG) {
|
||||
System.out.printf("setAttributes: %s = %s (type: %s)%n", name, svalue, value == null ? "null" : value.getClass().getName());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
String[] result = runtime.setOptionValues(names, values);
|
||||
AttributeList setOk = new AttributeList();
|
||||
i = 0;
|
||||
for (Attribute attr : attributes.asList()) {
|
||||
if (names[i] == result[i]) {
|
||||
setOk.add(attr);
|
||||
} else if (result[i] == null) {
|
||||
TTY.printf("Error setting %s to %s: unknown option%n", attr.getName(), attr.getValue());
|
||||
} else {
|
||||
TTY.printf("Error setting %s to %s: %s%n", attr.getName(), attr.getValue(), result[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return setOk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {
|
||||
try {
|
||||
if (DEBUG) {
|
||||
System.out.printf("invoke: %s%s%n", actionName, Arrays.asList(params));
|
||||
}
|
||||
Object retvalue = runtime.invokeManagementAction(actionName, params);
|
||||
if (DEBUG) {
|
||||
System.out.printf("invoke: %s%s = %s%n", actionName, Arrays.asList(params), retvalue);
|
||||
}
|
||||
return retvalue;
|
||||
} catch (Exception ex) {
|
||||
throw new ReflectionException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MBeanInfo getMBeanInfo() {
|
||||
List<MBeanAttributeInfo> attrs = new ArrayList<>();
|
||||
for (OptionDescriptor option : getOptionDescriptors().getValues()) {
|
||||
Class<?> optionValueType = option.getOptionValueType();
|
||||
if (Enum.class.isAssignableFrom(optionValueType)) {
|
||||
// Enum values are passed through
|
||||
// the management interface as Strings.
|
||||
optionValueType = String.class;
|
||||
}
|
||||
attrs.add(new MBeanAttributeInfo(option.getName(), optionValueType.getName(), option.getHelp(), true, true, false));
|
||||
}
|
||||
attrs.sort(new Comparator<MBeanAttributeInfo>() {
|
||||
@Override
|
||||
public int compare(MBeanAttributeInfo o1, MBeanAttributeInfo o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
MBeanOperationInfo[] ops = {
|
||||
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
|
||||
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
|
||||
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
|
||||
}, "void", MBeanOperationInfo.ACTION),
|
||||
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
|
||||
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
|
||||
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
|
||||
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
|
||||
}, "void", MBeanOperationInfo.ACTION),
|
||||
new MBeanOperationInfo("dumpMethod", "Enable IGV dumps for provided method", new MBeanParameterInfo[]{
|
||||
new MBeanParameterInfo("className", "java.lang.String", "Class to observe"),
|
||||
new MBeanParameterInfo("methodName", "java.lang.String", "Method to observe"),
|
||||
new MBeanParameterInfo("filter", "java.lang.String", "The parameter for Dump option"),
|
||||
new MBeanParameterInfo("host", "java.lang.String", "The host where the IGV tool is running at"),
|
||||
new MBeanParameterInfo("port", "int", "The port where the IGV tool is listening at"),
|
||||
}, "void", MBeanOperationInfo.ACTION)
|
||||
};
|
||||
|
||||
return new MBeanInfo(
|
||||
HotSpotGraalRuntimeMBean.class.getName(),
|
||||
"Graal",
|
||||
attrs.toArray(new MBeanAttributeInfo[attrs.size()]),
|
||||
null, ops, null);
|
||||
}
|
||||
|
||||
private static EconomicMap<String, OptionDescriptor> getOptionDescriptors() {
|
||||
EconomicMap<String, OptionDescriptor> result = EconomicMap.create();
|
||||
for (OptionDescriptors set : OptionsParser.getOptionsLoader()) {
|
||||
for (OptionDescriptor option : set) {
|
||||
result.put(option.getName(), option);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2018, 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.management;
|
||||
|
||||
import static java.lang.Thread.currentThread;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.compiler.serviceprovider.ServiceProvider;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices.JMXService;
|
||||
|
||||
import com.sun.management.ThreadMXBean;
|
||||
|
||||
/**
|
||||
* Implementation of {@link JMXService} for JDK 11 and later.
|
||||
*/
|
||||
@ServiceProvider(JMXService.class)
|
||||
public class JMXServiceProvider extends JMXService {
|
||||
private final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
|
||||
|
||||
@Override
|
||||
protected long getThreadAllocatedBytes(long id) {
|
||||
return threadMXBean.getThreadAllocatedBytes(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getCurrentThreadCpuTime() {
|
||||
long[] times = threadMXBean.getThreadCpuTime(new long[]{currentThread().getId()});
|
||||
return times[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isThreadAllocatedMemorySupported() {
|
||||
return threadMXBean.isThreadAllocatedMemorySupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCurrentThreadCpuTimeSupported() {
|
||||
return threadMXBean.isThreadCpuTimeSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getInputArguments() {
|
||||
return ManagementFactory.getRuntimeMXBean().getInputArguments();
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2018, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK 11 and later versioned overlay for the {@code jdk.internal.vm.compiler.management} module.
|
||||
* This cannot be used in JDK 10 where {@code jdk.internal.vm.compiler.management} is a
|
||||
* non-upgradeable module.
|
||||
*/
|
||||
package org.graalvm.compiler.hotspot.management;
|
@ -22,15 +22,15 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import org.graalvm.collections.UnmodifiableEconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicSet;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@ -31,10 +31,10 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
import org.graalvm.collections.UnmodifiableMapCursor;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.MapCursor;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
@ -22,12 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -22,14 +22,14 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -22,9 +22,9 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -22,9 +22,9 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections.test;
|
||||
package jdk.internal.vm.compiler.collections.test;
|
||||
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
/**
|
||||
* Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
/**
|
||||
* Cursor to iterate over a mutable map.
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
/**
|
||||
* Unmodifiable memory efficient map data structure.
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
/**
|
||||
* Unmodifiable memory efficient set data structure.
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
||||
|
||||
/**
|
||||
* Cursor to iterate over a map without changing its contents.
|
@ -22,12 +22,17 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
@ApiInfo(
|
||||
group="Graal SDK"
|
||||
)
|
||||
*/
|
||||
/**
|
||||
* The Graal-SDK collections package contains memory efficient data structures.
|
||||
*
|
||||
* @see org.graalvm.collections.EconomicMap
|
||||
* @see org.graalvm.collections.EconomicSet
|
||||
* @see jdk.internal.vm.compiler.collections.EconomicMap
|
||||
* @see jdk.internal.vm.compiler.collections.EconomicSet
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package org.graalvm.collections;
|
||||
package jdk.internal.vm.compiler.collections;
|
@ -22,8 +22,13 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* A machine-word-sized value that can be compared for equality.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface ComparableWord extends WordBase {
|
||||
|
||||
/**
|
||||
@ -31,6 +36,8 @@ public interface ComparableWord extends WordBase {
|
||||
*
|
||||
* @param val value to which this word is to be compared.
|
||||
* @return {@code this == val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean equal(ComparableWord val);
|
||||
|
||||
@ -39,6 +46,8 @@ public interface ComparableWord extends WordBase {
|
||||
*
|
||||
* @param val value to which this word is to be compared.
|
||||
* @return {@code this != val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean notEqual(ComparableWord val);
|
||||
}
|
@ -22,17 +22,19 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
// JaCoCo Exclude
|
||||
|
||||
/**
|
||||
* Marker interface for location identities. A different location identity of two memory accesses
|
||||
* guarantees that the two accesses do not interfere.
|
||||
*
|
||||
* <p>
|
||||
* Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
|
||||
* comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
|
||||
* {@link java.util.IdentityHashMap}s with {@link LocationIdentity} values as keys.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class LocationIdentity {
|
||||
|
||||
@ -60,13 +62,39 @@ public abstract class LocationIdentity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new location identity. Subclasses are responsible to provide proper implementations
|
||||
* of {@link #equals} and {@link #hashCode}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
protected LocationIdentity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the given location is the union of all possible mutable locations. A write to
|
||||
* such a location kill all reads from mutable locations and a read from this location is killed
|
||||
* by any write (except for initialization writes).
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
|
||||
|
||||
/**
|
||||
* Location only allowed to be used for writes. Indicates that a completely new memory location
|
||||
* is written. Kills no read. The previous value at the given location must be either
|
||||
* uninitialized or null. Writes to this location do not need a GC pre-barrier.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static final LocationIdentity INIT_LOCATION = new InitLocationIdentity();
|
||||
|
||||
/**
|
||||
* Indicates that the given location is the union of all possible mutable locations. A write to
|
||||
* such a location kill all reads from mutable locations and a read from this location is killed
|
||||
* by any write (except for initialization writes).
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static LocationIdentity any() {
|
||||
return ANY_LOCATION;
|
||||
@ -76,6 +104,8 @@ public abstract class LocationIdentity {
|
||||
* Location only allowed to be used for writes. Indicates that a completely new memory location
|
||||
* is written. Kills no read. The previous value at the given location must be either
|
||||
* uninitialized or null. Writes to this location do not need a GC pre-barrier.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public static LocationIdentity init() {
|
||||
return INIT_LOCATION;
|
||||
@ -84,25 +114,53 @@ public abstract class LocationIdentity {
|
||||
/**
|
||||
* Denotes a location is unchanging in all cases. Not that this is different than the Java
|
||||
* notion of final which only requires definite assignment.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract boolean isImmutable();
|
||||
|
||||
/**
|
||||
* The inversion of {@link #isImmutable}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final boolean isMutable() {
|
||||
return !isImmutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this location identity is {@link #any}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final boolean isAny() {
|
||||
return this == ANY_LOCATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this location identity is {@link #init}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final boolean isInit() {
|
||||
return this == INIT_LOCATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this location identity is not {@link #any}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final boolean isSingle() {
|
||||
return this != ANY_LOCATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the memory slice denoted by this location identity may overlap with the
|
||||
* provided other location identity.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final boolean overlaps(LocationIdentity other) {
|
||||
return isAny() || other.isAny() || this.equals(other);
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* Lowest-level memory access of native C memory.
|
||||
@ -30,6 +30,8 @@ package org.graalvm.word;
|
||||
* Do not use these methods to access Java objects. These methods access the raw memory without any
|
||||
* null checks, read- or write barriers. Even when the VM uses compressed pointers, then readObject
|
||||
* and writeObject methods access uncompressed pointers.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface Pointer extends UnsignedWord, PointerBase {
|
||||
|
||||
@ -39,6 +41,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* that can i.e., processed by the garbage collector.
|
||||
*
|
||||
* @return this Pointer cast to Object.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object toObject();
|
||||
|
||||
@ -48,6 +52,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* that can i.e., processed by the garbage collector and the Pointer does not contain 0.
|
||||
*
|
||||
* @return this Pointer cast to non-null Object.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object toObjectNonNull();
|
||||
|
||||
@ -62,6 +68,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
byte readByte(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -76,6 +84,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
char readChar(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -90,6 +100,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
short readShort(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -104,6 +116,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int readInt(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -118,6 +132,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long readLong(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -132,6 +148,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
float readFloat(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -146,6 +164,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
double readDouble(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -160,6 +180,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T readWord(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -174,6 +196,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object readObject(WordBase offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -184,6 +208,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
byte readByte(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -194,6 +220,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
char readChar(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -204,6 +232,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
short readShort(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -214,6 +244,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int readInt(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -224,6 +256,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long readLong(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -234,6 +268,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
float readFloat(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -244,6 +280,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
double readDouble(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -254,6 +292,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -264,6 +304,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the read
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object readObject(int offset, LocationIdentity locationIdentity);
|
||||
|
||||
@ -278,6 +320,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -292,6 +336,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeChar(WordBase offset, char val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -306,6 +352,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeShort(WordBase offset, short val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -320,6 +368,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeInt(WordBase offset, int val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -334,6 +384,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeLong(WordBase offset, long val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -348,6 +400,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -362,6 +416,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -376,6 +432,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -390,6 +448,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -404,6 +464,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -414,6 +476,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeByte(int offset, byte val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -424,6 +488,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeChar(int offset, char val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -434,6 +500,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeShort(int offset, short val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -444,6 +512,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeInt(int offset, int val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -454,6 +524,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeLong(int offset, long val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -464,6 +536,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeFloat(int offset, float val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -474,6 +548,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeDouble(int offset, double val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -484,6 +560,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeWord(int offset, WordBase val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -494,6 +572,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void initializeLong(int offset, long val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -504,6 +584,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param locationIdentity the identity of the write
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeObject(int offset, Object val, LocationIdentity locationIdentity);
|
||||
|
||||
@ -517,6 +599,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
byte readByte(WordBase offset);
|
||||
|
||||
@ -530,6 +614,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
char readChar(WordBase offset);
|
||||
|
||||
@ -543,6 +629,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
short readShort(WordBase offset);
|
||||
|
||||
@ -556,6 +644,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int readInt(WordBase offset);
|
||||
|
||||
@ -569,6 +659,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long readLong(WordBase offset);
|
||||
|
||||
@ -582,6 +674,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
float readFloat(WordBase offset);
|
||||
|
||||
@ -595,6 +689,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
double readDouble(WordBase offset);
|
||||
|
||||
@ -608,6 +704,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T readWord(WordBase offset);
|
||||
|
||||
@ -621,6 +719,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object readObject(WordBase offset);
|
||||
|
||||
@ -630,6 +730,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
byte readByte(int offset);
|
||||
|
||||
@ -639,6 +741,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
char readChar(int offset);
|
||||
|
||||
@ -648,6 +752,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
short readShort(int offset);
|
||||
|
||||
@ -657,6 +763,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int readInt(int offset);
|
||||
|
||||
@ -666,6 +774,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long readLong(int offset);
|
||||
|
||||
@ -675,6 +785,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
float readFloat(int offset);
|
||||
|
||||
@ -684,6 +796,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
double readDouble(int offset);
|
||||
|
||||
@ -693,6 +807,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T readWord(int offset);
|
||||
|
||||
@ -702,6 +818,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @return the result of the memory access
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object readObject(int offset);
|
||||
|
||||
@ -715,6 +833,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeByte(WordBase offset, byte val);
|
||||
|
||||
@ -728,6 +848,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeChar(WordBase offset, char val);
|
||||
|
||||
@ -741,6 +863,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeShort(WordBase offset, short val);
|
||||
|
||||
@ -754,6 +878,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeInt(WordBase offset, int val);
|
||||
|
||||
@ -767,6 +893,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeLong(WordBase offset, long val);
|
||||
|
||||
@ -780,6 +908,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeFloat(WordBase offset, float val);
|
||||
|
||||
@ -793,6 +923,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeDouble(WordBase offset, double val);
|
||||
|
||||
@ -806,6 +938,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeWord(WordBase offset, WordBase val);
|
||||
|
||||
@ -819,23 +953,157 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeObject(WordBase offset, Object val);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
* <p>
|
||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||
* {@link WordBase} to avoid 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
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
@ -844,6 +1112,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeByte(int offset, byte val);
|
||||
|
||||
@ -853,6 +1123,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeChar(int offset, char val);
|
||||
|
||||
@ -862,6 +1134,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeShort(int offset, short val);
|
||||
|
||||
@ -871,6 +1145,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeInt(int offset, int val);
|
||||
|
||||
@ -880,6 +1156,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeLong(int offset, long val);
|
||||
|
||||
@ -889,6 +1167,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeFloat(int offset, float val);
|
||||
|
||||
@ -898,6 +1178,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeDouble(int offset, double val);
|
||||
|
||||
@ -907,6 +1189,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeWord(int offset, WordBase val);
|
||||
|
||||
@ -916,50 +1200,216 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param val the value to be written to memory
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void writeObject(int offset, Object val);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
<T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return The value after the atomic exchange
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
||||
|
||||
/**
|
||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
||||
* offset are in bytes.
|
||||
*
|
||||
* @param offset the signed offset for the memory access
|
||||
* @param expectedValue the expected value of the atomic exchange
|
||||
* @param newValue the new value of the atomic exchange
|
||||
* @param locationIdentity the identity of the memory location
|
||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||
* equal to the expected value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||
|
||||
// Math functions that are defined in Unsigned, but known to preserve the
|
||||
// pointer-characteristics.
|
||||
// It is therefore safe that they return a static type of Pointer instead of Unsigned.
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this + val)}.
|
||||
*
|
||||
* @param val value to be added to this Pointer.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer add(UnsignedWord val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this + val)}.
|
||||
*
|
||||
* @param val value to be added to this Pointer.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer add(int val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this - val)}.
|
||||
*
|
||||
* @param val value to be subtracted from this Pointer.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer subtract(UnsignedWord val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this - val)}.
|
||||
*
|
||||
* @param val value to be subtracted from this Pointer.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer subtract(int val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this & val)}.
|
||||
*
|
||||
* @param val value to be AND'ed with this Pointer.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer and(UnsignedWord val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this & val)}.
|
||||
*
|
||||
* @param val value to be AND'ed with this Pointer.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer and(int val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this | val)}.
|
||||
*
|
||||
* @param val value to be OR'ed with this Pointer.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer or(UnsignedWord val);
|
||||
|
||||
/**
|
||||
* Returns a Pointer whose value is {@code (this | val)}.
|
||||
*
|
||||
* @param val value to be OR'ed with this Pointer.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
Pointer or(int val);
|
||||
}
|
@ -22,21 +22,27 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not
|
||||
* necessarily all the memory access methods defined in {@link Pointer}).
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface PointerBase extends ComparableWord {
|
||||
|
||||
/**
|
||||
* Returns true if this pointer is the {@link WordFactory#nullPointer null pointer}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean isNull();
|
||||
|
||||
/**
|
||||
* Returns true if this pointer is not the {@link WordFactory#nullPointer null pointer}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean isNonNull();
|
||||
}
|
@ -22,8 +22,13 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* Represents a signed word-sized value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface SignedWord extends ComparableWord {
|
||||
|
||||
/**
|
||||
@ -31,6 +36,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be added to this Signed.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord add(SignedWord val);
|
||||
|
||||
@ -39,6 +46,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be subtracted from this Signed.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord subtract(SignedWord val);
|
||||
|
||||
@ -47,6 +56,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be multiplied by this Signed.
|
||||
* @return {@code this * val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord multiply(SignedWord val);
|
||||
|
||||
@ -55,6 +66,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Signed is to be divided.
|
||||
* @return {@code this / val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedDivide(SignedWord val);
|
||||
|
||||
@ -63,6 +76,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Signed is to be divided, and the remainder computed.
|
||||
* @return {@code this % val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedRemainder(SignedWord val);
|
||||
|
||||
@ -71,6 +86,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this << n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord shiftLeft(UnsignedWord n);
|
||||
|
||||
@ -79,6 +96,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this >> n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedShiftRight(UnsignedWord n);
|
||||
|
||||
@ -88,6 +107,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be AND'ed with this Signed.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord and(SignedWord val);
|
||||
|
||||
@ -97,6 +118,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be OR'ed with this Signed.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord or(SignedWord val);
|
||||
|
||||
@ -106,6 +129,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be XOR'ed with this Signed.
|
||||
* @return {@code this ^ val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord xor(SignedWord val);
|
||||
|
||||
@ -114,6 +139,8 @@ public interface SignedWord extends ComparableWord {
|
||||
* only if this Signed is non-negative.)
|
||||
*
|
||||
* @return {@code ~this}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord not();
|
||||
|
||||
@ -122,6 +149,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this == val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean equal(SignedWord val);
|
||||
|
||||
@ -130,6 +159,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this != val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean notEqual(SignedWord val);
|
||||
|
||||
@ -138,6 +169,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this < val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean lessThan(SignedWord val);
|
||||
|
||||
@ -146,6 +179,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this <= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean lessOrEqual(SignedWord val);
|
||||
|
||||
@ -154,6 +189,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this > val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean greaterThan(SignedWord val);
|
||||
|
||||
@ -162,6 +199,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this >= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean greaterOrEqual(SignedWord val);
|
||||
|
||||
@ -170,6 +209,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be added to this Signed.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord add(int val);
|
||||
|
||||
@ -178,6 +219,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be subtracted from this Signed.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord subtract(int val);
|
||||
|
||||
@ -186,6 +229,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be multiplied by this Signed.
|
||||
* @return {@code this * val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord multiply(int val);
|
||||
|
||||
@ -194,6 +239,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Signed is to be divided.
|
||||
* @return {@code this / val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedDivide(int val);
|
||||
|
||||
@ -202,6 +249,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Signed is to be divided, and the remainder computed.
|
||||
* @return {@code this % val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedRemainder(int val);
|
||||
|
||||
@ -210,6 +259,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this << n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord shiftLeft(int n);
|
||||
|
||||
@ -218,6 +269,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this >> n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord signedShiftRight(int n);
|
||||
|
||||
@ -227,6 +280,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be AND'ed with this Signed.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord and(int val);
|
||||
|
||||
@ -236,6 +291,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be OR'ed with this Signed.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord or(int val);
|
||||
|
||||
@ -245,6 +302,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be XOR'ed with this Signed.
|
||||
* @return {@code this ^ val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
SignedWord xor(int val);
|
||||
|
||||
@ -253,6 +312,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this == val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean equal(int val);
|
||||
|
||||
@ -261,6 +322,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this != val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean notEqual(int val);
|
||||
|
||||
@ -269,6 +332,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this < val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean lessThan(int val);
|
||||
|
||||
@ -277,6 +342,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this <= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean lessOrEqual(int val);
|
||||
|
||||
@ -285,6 +352,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this > val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean greaterThan(int val);
|
||||
|
||||
@ -293,6 +362,8 @@ public interface SignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Signed is to be compared.
|
||||
* @return {@code this >= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean greaterOrEqual(int val);
|
||||
}
|
@ -22,8 +22,13 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* Represents an unsigned word-sized value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface UnsignedWord extends ComparableWord {
|
||||
|
||||
/**
|
||||
@ -31,6 +36,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be added to this Unsigned.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord add(UnsignedWord val);
|
||||
|
||||
@ -39,6 +46,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be subtracted from this Unsigned.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord subtract(UnsignedWord val);
|
||||
|
||||
@ -47,6 +56,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be multiplied by this Unsigned.
|
||||
* @return {@code this * val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord multiply(UnsignedWord val);
|
||||
|
||||
@ -55,6 +66,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Unsigned is to be divided.
|
||||
* @return {@code this / val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedDivide(UnsignedWord val);
|
||||
|
||||
@ -63,6 +76,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Unsigned is to be divided, and the remainder computed.
|
||||
* @return {@code this % val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedRemainder(UnsignedWord val);
|
||||
|
||||
@ -71,6 +86,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this << n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord shiftLeft(UnsignedWord n);
|
||||
|
||||
@ -79,6 +96,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this >> n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedShiftRight(UnsignedWord n);
|
||||
|
||||
@ -87,6 +106,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be AND'ed with this Unsigned.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord and(UnsignedWord val);
|
||||
|
||||
@ -95,6 +116,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be OR'ed with this Unsigned.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord or(UnsignedWord val);
|
||||
|
||||
@ -103,6 +126,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be XOR'ed with this Unsigned.
|
||||
* @return {@code this ^ val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord xor(UnsignedWord val);
|
||||
|
||||
@ -110,6 +135,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
* Returns a Unsigned whose value is {@code (~this)}.
|
||||
*
|
||||
* @return {@code ~this}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord not();
|
||||
|
||||
@ -118,6 +145,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this == val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean equal(UnsignedWord val);
|
||||
|
||||
@ -126,6 +155,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this != val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean notEqual(UnsignedWord val);
|
||||
|
||||
@ -134,6 +165,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this < val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean belowThan(UnsignedWord val);
|
||||
|
||||
@ -142,6 +175,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this <= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean belowOrEqual(UnsignedWord val);
|
||||
|
||||
@ -150,6 +185,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this > val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean aboveThan(UnsignedWord val);
|
||||
|
||||
@ -158,6 +195,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this >= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean aboveOrEqual(UnsignedWord val);
|
||||
|
||||
@ -169,6 +208,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be added to this Unsigned.
|
||||
* @return {@code this + val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord add(int val);
|
||||
|
||||
@ -180,6 +221,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be subtracted from this Unsigned.
|
||||
* @return {@code this - val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord subtract(int val);
|
||||
|
||||
@ -191,6 +234,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be multiplied by this Unsigned.
|
||||
* @return {@code this * val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord multiply(int val);
|
||||
|
||||
@ -202,6 +247,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Unsigned is to be divided.
|
||||
* @return {@code this / val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedDivide(int val);
|
||||
|
||||
@ -213,6 +260,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value by which this Unsigned is to be divided, and the remainder computed.
|
||||
* @return {@code this % val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedRemainder(int val);
|
||||
|
||||
@ -224,6 +273,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this << n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord shiftLeft(int n);
|
||||
|
||||
@ -235,6 +286,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param n shift distance, in bits.
|
||||
* @return {@code this >> n}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord unsignedShiftRight(int n);
|
||||
|
||||
@ -246,6 +299,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be AND'ed with this Unsigned.
|
||||
* @return {@code this & val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord and(int val);
|
||||
|
||||
@ -257,6 +312,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be OR'ed with this Unsigned.
|
||||
* @return {@code this | val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord or(int val);
|
||||
|
||||
@ -268,6 +325,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to be XOR'ed with this Unsigned.
|
||||
* @return {@code this ^ val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
UnsignedWord xor(int val);
|
||||
|
||||
@ -279,6 +338,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this == val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean equal(int val);
|
||||
|
||||
@ -290,6 +351,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this != val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean notEqual(int val);
|
||||
|
||||
@ -301,6 +364,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this < val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean belowThan(int val);
|
||||
|
||||
@ -312,6 +377,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this <= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean belowOrEqual(int val);
|
||||
|
||||
@ -323,6 +390,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this > val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean aboveThan(int val);
|
||||
|
||||
@ -334,6 +403,8 @@ public interface UnsignedWord extends ComparableWord {
|
||||
*
|
||||
* @param val value to which this Unsigned is to be compared.
|
||||
* @return {@code this >= val}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean aboveOrEqual(int val);
|
||||
}
|
@ -22,16 +22,28 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
/**
|
||||
* The root of the interface hierarchy for machine-word-sized values.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface WordBase {
|
||||
|
||||
/**
|
||||
* Conversion to a Java primitive value.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
long rawValue();
|
||||
|
||||
/**
|
||||
* This is deprecated because of the easy to mistype name collision between {@link #equals} and
|
||||
* the other word based equality routines. In general you should never be statically calling
|
||||
* this method anyway.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
@ -22,44 +22,20 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.word;
|
||||
package jdk.internal.vm.compiler.word;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
|
||||
import jdk.internal.vm.compiler.word.impl.WordFactoryOpcode;
|
||||
import jdk.internal.vm.compiler.word.impl.WordFactoryOperation;
|
||||
|
||||
public abstract class WordFactory {
|
||||
/**
|
||||
* Provides factory method to create machine-word-sized values.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class WordFactory {
|
||||
|
||||
/**
|
||||
* Links a method to a canonical operation represented by an {@link FactoryOpcode} val.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
protected @interface FactoryOperation {
|
||||
FactoryOpcode opcode();
|
||||
}
|
||||
|
||||
/**
|
||||
* The canonical {@link FactoryOperation} represented by a method in a word type.
|
||||
*/
|
||||
protected enum FactoryOpcode {
|
||||
ZERO,
|
||||
FROM_UNSIGNED,
|
||||
FROM_SIGNED,
|
||||
}
|
||||
|
||||
protected interface BoxFactory {
|
||||
<T extends WordBase> T box(long val);
|
||||
}
|
||||
|
||||
protected static BoxFactory boxFactory;
|
||||
|
||||
/**
|
||||
* We allow subclassing, because only subclasses can access the protected inner classes that we
|
||||
* use to mark the operations.
|
||||
*/
|
||||
protected WordFactory() {
|
||||
private WordFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,10 +43,12 @@ public abstract class WordFactory {
|
||||
* unsigned zero.
|
||||
*
|
||||
* @return the constant 0.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.ZERO)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
|
||||
public static <T extends WordBase> T zero() {
|
||||
return boxFactory.box(0L);
|
||||
return WordBoxFactory.box(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,10 +56,12 @@ public abstract class WordFactory {
|
||||
* unsigned {@link #zero}.
|
||||
*
|
||||
* @return the null pointer.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.ZERO)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
|
||||
public static <T extends PointerBase> T nullPointer() {
|
||||
return boxFactory.box(0L);
|
||||
return WordBoxFactory.box(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,10 +70,12 @@ public abstract class WordFactory {
|
||||
*
|
||||
* @param val a 64 bit unsigned value
|
||||
* @return the value cast to Word
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
|
||||
public static <T extends UnsignedWord> T unsigned(long val) {
|
||||
return boxFactory.box(val);
|
||||
return WordBoxFactory.box(val);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,10 +84,12 @@ public abstract class WordFactory {
|
||||
*
|
||||
* @param val a 64 bit unsigned value
|
||||
* @return the value cast to PointerBase
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
|
||||
public static <T extends PointerBase> T pointer(long val) {
|
||||
return boxFactory.box(val);
|
||||
return WordBoxFactory.box(val);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,10 +98,12 @@ public abstract class WordFactory {
|
||||
*
|
||||
* @param val a 32 bit unsigned value
|
||||
* @return the value cast to Word
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.FROM_UNSIGNED)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
|
||||
public static <T extends UnsignedWord> T unsigned(int val) {
|
||||
return boxFactory.box(val & 0xffffffffL);
|
||||
return WordBoxFactory.box(val & 0xffffffffL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,10 +112,12 @@ public abstract class WordFactory {
|
||||
*
|
||||
* @param val a 64 bit signed value
|
||||
* @return the value cast to Word
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
|
||||
public static <T extends SignedWord> T signed(long val) {
|
||||
return boxFactory.box(val);
|
||||
return WordBoxFactory.box(val);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,9 +126,11 @@ public abstract class WordFactory {
|
||||
*
|
||||
* @param val a 32 bit signed value
|
||||
* @return the value cast to Word
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@FactoryOperation(opcode = FactoryOpcode.FROM_SIGNED)
|
||||
@WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
|
||||
public static <T extends SignedWord> T signed(int val) {
|
||||
return boxFactory.box(val);
|
||||
return WordBoxFactory.box(val);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2018, 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 jdk.internal.vm.compiler.word.impl;
|
||||
|
||||
import jdk.internal.vm.compiler.word.WordBase;
|
||||
|
||||
/**
|
||||
* Base class for a factory to create boxed {@link Word} instances. A concrete subclass must
|
||||
* initialize {@link #boxFactory}.
|
||||
*/
|
||||
public abstract class WordBoxFactory {
|
||||
|
||||
protected static WordBoxFactory boxFactory;
|
||||
|
||||
protected abstract <T extends WordBase> T boxImpl(long val);
|
||||
|
||||
public static <T extends WordBase> T box(long val) {
|
||||
return boxFactory.boxImpl(val);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2018, 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 jdk.internal.vm.compiler.word.impl;
|
||||
|
||||
/**
|
||||
* The canonical {@link WordFactoryOperation} represented by a method in a word type.
|
||||
*/
|
||||
public enum WordFactoryOpcode {
|
||||
ZERO,
|
||||
FROM_UNSIGNED,
|
||||
FROM_SIGNED,
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2018, 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 jdk.internal.vm.compiler.word.impl;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Links a method to a canonical operation represented by an {@link WordFactoryOpcode} val.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface WordFactoryOperation {
|
||||
WordFactoryOpcode opcode();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2018, 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.
|
||||
*/
|
||||
/*
|
||||
@ApiInfo(
|
||||
group="Graal SDK"
|
||||
)
|
||||
*/
|
||||
/**
|
||||
* This package provides a low-level mechanism to use machine-word-sized values in Java. The package
|
||||
* can only be used in the context of native images or Graal snippets.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package jdk.internal.vm.compiler.word;
|
@ -36,9 +36,10 @@ module jdk.internal.vm.compiler {
|
||||
uses org.graalvm.compiler.hotspot.CompilerConfigurationFactory;
|
||||
uses org.graalvm.compiler.hotspot.HotSpotBackendFactory;
|
||||
uses org.graalvm.compiler.hotspot.HotSpotCodeCacheListener;
|
||||
uses org.graalvm.compiler.options.OptionValuesAccess;
|
||||
uses org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
|
||||
uses org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
|
||||
|
||||
exports jdk.internal.vm.compiler.collections to jdk.internal.vm.compiler.management;
|
||||
exports org.graalvm.compiler.api.directives to jdk.aot;
|
||||
exports org.graalvm.compiler.api.runtime to jdk.aot;
|
||||
exports org.graalvm.compiler.api.replacements to jdk.aot;
|
||||
@ -46,9 +47,13 @@ module jdk.internal.vm.compiler {
|
||||
exports org.graalvm.compiler.bytecode to jdk.aot;
|
||||
exports org.graalvm.compiler.code to jdk.aot;
|
||||
exports org.graalvm.compiler.core to jdk.aot;
|
||||
exports org.graalvm.compiler.core.common to jdk.aot;
|
||||
exports org.graalvm.compiler.core.common to
|
||||
jdk.aot,
|
||||
jdk.internal.vm.compiler.management;
|
||||
exports org.graalvm.compiler.core.target to jdk.aot;
|
||||
exports org.graalvm.compiler.debug to jdk.aot;
|
||||
exports org.graalvm.compiler.debug to
|
||||
jdk.aot,
|
||||
jdk.internal.vm.compiler.management;
|
||||
exports org.graalvm.compiler.graph to jdk.aot;
|
||||
exports org.graalvm.compiler.hotspot to
|
||||
jdk.aot,
|
||||
@ -62,12 +67,17 @@ module jdk.internal.vm.compiler {
|
||||
exports org.graalvm.compiler.lir.phases to jdk.aot;
|
||||
exports org.graalvm.compiler.nodes to jdk.aot;
|
||||
exports org.graalvm.compiler.nodes.graphbuilderconf to jdk.aot;
|
||||
exports org.graalvm.compiler.options to jdk.aot;
|
||||
exports org.graalvm.compiler.options to
|
||||
jdk.aot,
|
||||
jdk.internal.vm.compiler.management;
|
||||
exports org.graalvm.compiler.phases to jdk.aot;
|
||||
exports org.graalvm.compiler.phases.tiers to jdk.aot;
|
||||
exports org.graalvm.compiler.printer to jdk.aot;
|
||||
exports org.graalvm.compiler.runtime to jdk.aot;
|
||||
exports org.graalvm.compiler.replacements to jdk.aot;
|
||||
exports org.graalvm.compiler.serviceprovider to
|
||||
jdk.aot,
|
||||
jdk.internal.vm.compiler.management;
|
||||
exports org.graalvm.compiler.word to jdk.aot;
|
||||
exports org.graalvm.word to jdk.aot;
|
||||
exports jdk.internal.vm.compiler.word to jdk.aot;
|
||||
}
|
||||
|
@ -206,12 +206,12 @@ class TestProtectedAssembler extends AArch64Assembler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bfm(int size, Register dst, Register src, int r, int s) {
|
||||
public void bfm(int size, Register dst, Register src, int r, int s) {
|
||||
super.bfm(size, dst, src, r, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void ubfm(int size, Register dst, Register src, int r, int s) {
|
||||
public void ubfm(int size, Register dst, Register src, int r, int s) {
|
||||
super.ubfm(size, dst, src, r, s);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BICS
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BLR;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CAS;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
|
||||
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
|
||||
@ -118,6 +119,9 @@ import org.graalvm.compiler.core.common.NumUtil;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
|
||||
import org.graalvm.compiler.debug.GraalError;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
import jdk.vm.ci.aarch64.AArch64.CPUFeature;
|
||||
import jdk.vm.ci.aarch64.AArch64.Flag;
|
||||
import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
|
||||
@ -471,6 +475,9 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
private static final int BarrierOp = 0xD503301F;
|
||||
private static final int BarrierKindOffset = 8;
|
||||
|
||||
private static final int CASAcquireOffset = 22;
|
||||
private static final int CASReleaseOffset = 15;
|
||||
|
||||
/**
|
||||
* Encoding for all instructions.
|
||||
*/
|
||||
@ -501,6 +508,8 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
LDP(0b1 << 22),
|
||||
STP(0b0 << 22),
|
||||
|
||||
CAS(0x08A07C00),
|
||||
|
||||
ADR(0x00000000),
|
||||
ADRP(0x80000000),
|
||||
|
||||
@ -740,6 +749,14 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
super(target);
|
||||
}
|
||||
|
||||
public boolean supports(CPUFeature feature) {
|
||||
return ((AArch64) target.arch).getFeatures().contains(feature);
|
||||
}
|
||||
|
||||
public boolean isFlagSet(Flag flag) {
|
||||
return ((AArch64) target.arch).getFlags().contains(flag);
|
||||
}
|
||||
|
||||
/* Conditional Branch (5.2.1) */
|
||||
|
||||
/**
|
||||
@ -1311,6 +1328,20 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
|
||||
}
|
||||
|
||||
/* Compare And Swap */
|
||||
public void cas(int size, Register rs, Register rt, Register rn, boolean acquire, boolean release) {
|
||||
assert size == 32 || size == 64;
|
||||
int transferSize = NumUtil.log2Ceil(size / 8);
|
||||
compareAndSwapInstruction(CAS, rs, rt, rn, transferSize, acquire, release);
|
||||
}
|
||||
|
||||
private void compareAndSwapInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize, boolean acquire, boolean release) {
|
||||
assert log2TransferSize >= 0 && log2TransferSize < 4;
|
||||
assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
|
||||
int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
|
||||
emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt) | (acquire ? 1 : 0) << CASAcquireOffset | (release ? 1 : 0) << CASReleaseOffset);
|
||||
}
|
||||
|
||||
/* PC-relative Address Calculation (5.4.4) */
|
||||
|
||||
/**
|
||||
@ -1576,7 +1607,7 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
* @param r must be in the range 0 to size - 1
|
||||
* @param s must be in the range 0 to size - 1
|
||||
*/
|
||||
protected void bfm(int size, Register dst, Register src, int r, int s) {
|
||||
public void bfm(int size, Register dst, Register src, int r, int s) {
|
||||
bitfieldInstruction(BFM, dst, src, r, s, generalFromSize(size));
|
||||
}
|
||||
|
||||
@ -1589,7 +1620,7 @@ public abstract class AArch64Assembler extends Assembler {
|
||||
* @param r must be in the range 0 to size - 1
|
||||
* @param s must be in the range 0 to size - 1
|
||||
*/
|
||||
protected void ubfm(int size, Register dst, Register src, int r, int s) {
|
||||
public void ubfm(int size, Register dst, Register src, int r, int s) {
|
||||
bitfieldInstruction(UBFM, dst, src, r, s, generalFromSize(size));
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||
import org.graalvm.compiler.graph.NodeSourcePosition;
|
||||
|
||||
|
@ -32,8 +32,8 @@ import org.graalvm.compiler.core.common.PermanentBailoutException;
|
||||
public abstract class SourceStackTraceBailoutException extends PermanentBailoutException {
|
||||
private static final long serialVersionUID = 2144811793442316776L;
|
||||
|
||||
public static SourceStackTraceBailoutException create(Throwable cause, String format, StackTraceElement[] elements) {
|
||||
return new SourceStackTraceBailoutException(cause, format) {
|
||||
public static SourceStackTraceBailoutException create(Throwable cause, String reason, StackTraceElement[] elements) {
|
||||
return new SourceStackTraceBailoutException(cause, reason) {
|
||||
|
||||
private static final long serialVersionUID = 6279381376051787907L;
|
||||
|
||||
@ -46,7 +46,7 @@ public abstract class SourceStackTraceBailoutException extends PermanentBailoutE
|
||||
};
|
||||
}
|
||||
|
||||
private SourceStackTraceBailoutException(Throwable cause, String format) {
|
||||
super(cause, format);
|
||||
private SourceStackTraceBailoutException(Throwable cause, String reason) {
|
||||
super(cause, "%s", reason);
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ import org.graalvm.compiler.lir.SwitchStrategy;
|
||||
import org.graalvm.compiler.lir.Variable;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Compare;
|
||||
@ -51,13 +52,14 @@ import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondMoveOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Move;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Move.CompareAndSwapOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
|
||||
import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
|
||||
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||
import org.graalvm.compiler.lir.gen.LIRGenerator;
|
||||
import org.graalvm.compiler.phases.util.Providers;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
import jdk.vm.ci.aarch64.AArch64Kind;
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
import jdk.vm.ci.code.RegisterValue;
|
||||
@ -422,6 +424,21 @@ public abstract class AArch64LIRGenerator extends LIRGenerator {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
|
||||
LIRKind resultKind = LIRKind.value(AArch64Kind.DWORD);
|
||||
// DMS TODO: check calling conversion and registers used
|
||||
RegisterValue res = AArch64.r0.asValue(resultKind);
|
||||
RegisterValue cnt1 = AArch64.r1.asValue(length1.getValueKind());
|
||||
RegisterValue cnt2 = AArch64.r2.asValue(length2.getValueKind());
|
||||
emitMove(cnt1, length1);
|
||||
emitMove(cnt2, length2);
|
||||
append(new AArch64ArrayCompareToOp(this, kind1, kind2, res, array1, array2, cnt1, cnt2));
|
||||
Variable result = newVariable(resultKind);
|
||||
emitMove(result, res);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
|
||||
Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
|
||||
|
@ -22,11 +22,10 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.graalvm.compiler.replacements.aarch64;
|
||||
package org.graalvm.compiler.core.aarch64;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64Kind;
|
||||
import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator;
|
||||
import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator;
|
||||
|
||||
import org.graalvm.compiler.core.common.type.IntegerStamp;
|
||||
import org.graalvm.compiler.core.common.type.Stamp;
|
||||
import org.graalvm.compiler.graph.NodeClass;
|
||||
@ -42,7 +41,7 @@ import org.graalvm.compiler.nodes.extended.GuardingNode;
|
||||
import org.graalvm.compiler.nodes.memory.ReadNode;
|
||||
import org.graalvm.compiler.nodes.memory.address.AddressNode;
|
||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||
import org.graalvm.word.LocationIdentity;
|
||||
import jdk.internal.vm.compiler.word.LocationIdentity;
|
||||
|
||||
/**
|
||||
* AArch64-specific subclass of ReadNode that knows how to merge ZeroExtend and SignExtend into the
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2018, 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.
|
||||
*
|
||||
@ -22,7 +22,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.graalvm.compiler.replacements.aarch64;
|
||||
package org.graalvm.compiler.core.aarch64;
|
||||
|
||||
import org.graalvm.compiler.graph.Node;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
@ -46,7 +46,7 @@ public class AArch64ReadReplacementPhase extends Phase {
|
||||
}
|
||||
if (node instanceof ReadNode) {
|
||||
ReadNode readNode = (ReadNode) node;
|
||||
if (readNode.getUsageCount() == 1) {
|
||||
if (readNode.hasExactlyOneUsage()) {
|
||||
Node usage = readNode.getUsageAt(0);
|
||||
if (usage instanceof ZeroExtendNode || usage instanceof SignExtendNode) {
|
||||
AArch64ReadNode.replace(readNode);
|
@ -22,14 +22,37 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.aarch64;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.graalvm.compiler.java.DefaultSuitesCreator;
|
||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.phases.BasePhase;
|
||||
import org.graalvm.compiler.phases.Phase;
|
||||
import org.graalvm.compiler.phases.PhaseSuite;
|
||||
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
||||
import org.graalvm.compiler.phases.tiers.LowTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.Suites;
|
||||
|
||||
public class AArch64SuitesCreator extends DefaultSuitesCreator {
|
||||
private final Class<? extends Phase> insertReadReplacementBefore;
|
||||
|
||||
public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins) {
|
||||
public AArch64SuitesCreator(CompilerConfiguration compilerConfiguration, Plugins plugins, Class<? extends Phase> insertReadReplacementBefore) {
|
||||
super(compilerConfiguration, plugins);
|
||||
this.insertReadReplacementBefore = insertReadReplacementBefore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Suites createSuites(OptionValues options) {
|
||||
Suites suites = super.createSuites(options);
|
||||
|
||||
ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(insertReadReplacementBefore);
|
||||
// Put AArch64ReadReplacementPhase right before the SchedulePhase
|
||||
while (PhaseSuite.findNextPhase(findPhase, insertReadReplacementBefore)) {
|
||||
// Search for last occurrence of SchedulePhase
|
||||
}
|
||||
findPhase.previous();
|
||||
findPhase.add(new AArch64ReadReplacementPhase());
|
||||
return suites;
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ package org.graalvm.compiler.core.amd64;
|
||||
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
|
||||
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
import org.graalvm.compiler.lir.VirtualStackSlot;
|
||||
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
|
||||
|
@ -262,6 +262,9 @@ public final class GraalOptions {
|
||||
@Option(help = "Track the NodeSourcePosition.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> TrackNodeSourcePosition = new OptionKey<>(false);
|
||||
|
||||
@Option(help = "Track source stack trace where a node was inserted into the graph.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> TrackNodeInsertion = new OptionKey<>(false);
|
||||
|
||||
@Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> MatchExpressions = new OptionKey<>(true);
|
||||
|
||||
@ -276,7 +279,10 @@ public final class GraalOptions {
|
||||
|
||||
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
|
||||
@Option(help = "Enable tracing of inlining decision.", type = OptionType.Debug)
|
||||
|
||||
@Option(help = "file:doc-files/TraceInliningHelp.txt", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> TraceInlining = new OptionKey<>(false);
|
||||
|
||||
@Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> TraceInliningForStubsAndSnippets = new OptionKey<>(false);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class PermanentBailoutException extends BailoutException {
|
||||
}
|
||||
|
||||
public PermanentBailoutException(String reason) {
|
||||
super(true, reason);
|
||||
super(true, "%s", reason);
|
||||
}
|
||||
|
||||
public PermanentBailoutException(Throwable cause, String format, Object... args) {
|
||||
|
@ -22,8 +22,8 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.common.alloc;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.common.GraalOptions;
|
||||
|
||||
import jdk.vm.ci.code.Register;
|
||||
|
@ -0,0 +1,8 @@
|
||||
Enable tracing of inlining decisions.
|
||||
Output format:
|
||||
compilation of 'Signature of the compilation root method':
|
||||
at 'Signature of the root method' ['Bytecode index']: <'Phase'> 'Child method signature': 'Decision made about this callsite'
|
||||
at 'Signature of the child method' ['Bytecode index']:
|
||||
|--<'Phase 1'> 'Grandchild method signature': 'First decision made about this callsite'
|
||||
\--<'Phase 2'> 'Grandchild method signature': 'Second decision made about this callsite'
|
||||
at 'Signature of the child method' ['Bytecode index']: <'Phase'> 'Another grandchild method signature': 'The only decision made about this callsite.'
|
@ -23,7 +23,7 @@
|
||||
package org.graalvm.compiler.core.common.spi;
|
||||
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
import org.graalvm.word.LocationIdentity;
|
||||
import jdk.internal.vm.compiler.word.LocationIdentity;
|
||||
|
||||
import jdk.vm.ci.code.ValueKindFactory;
|
||||
|
||||
|
@ -25,8 +25,8 @@ package org.graalvm.compiler.core.common.util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
|
||||
/**
|
||||
* Creates an array of T objects order by the occurrence frequency of each object. The most
|
||||
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.common.util;
|
||||
|
||||
import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.graalvm.compiler.debug.GraalError;
|
||||
|
||||
/**
|
||||
* Reflection based access to the Module API introduced by JDK 9. This allows the API to be used in
|
||||
* code that must be compiled on a JDK prior to 9. Use of this class must be guarded by a test for
|
||||
* JDK 9 or later. For example:
|
||||
*
|
||||
* <pre>
|
||||
* if (Util.JAVA_SPECIFICATION_VERSION >= 9) {
|
||||
* // Use of ModuleAPI
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public final class ModuleAPI {
|
||||
|
||||
public ModuleAPI(Class<?> declaringClass, String name, Class<?>... parameterTypes) {
|
||||
try {
|
||||
this.method = declaringClass.getMethod(name, parameterTypes);
|
||||
} catch (Exception e) {
|
||||
throw new GraalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public final Method method;
|
||||
|
||||
public Class<?> getReturnType() {
|
||||
return method.getReturnType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Class.getModule()}.
|
||||
*/
|
||||
public static final ModuleAPI getModule;
|
||||
|
||||
/**
|
||||
* {@code java.lang.Module.getResourceAsStream(String)}.
|
||||
*/
|
||||
public static final ModuleAPI getResourceAsStream;
|
||||
|
||||
/**
|
||||
* {@code java.lang.Module.isExported(String, Module)}.
|
||||
*/
|
||||
public static final ModuleAPI isExportedTo;
|
||||
|
||||
/**
|
||||
* Invokes the static Module API method represented by this object.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T invokeStatic(Object... args) {
|
||||
checkAvailability();
|
||||
assert Modifier.isStatic(method.getModifiers());
|
||||
try {
|
||||
return (T) method.invoke(null, args);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new GraalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the non-static Module API method represented by this object.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T invoke(Object receiver, Object... args) {
|
||||
checkAvailability();
|
||||
assert !Modifier.isStatic(method.getModifiers());
|
||||
try {
|
||||
return (T) method.invoke(receiver, args);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new GraalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAvailability() throws GraalError {
|
||||
if (method == null) {
|
||||
throw new GraalError("Cannot use Module API on JDK " + JAVA_SPECIFICATION_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
if (JAVA_SPECIFICATION_VERSION >= 9) {
|
||||
getModule = new ModuleAPI(Class.class, "getModule");
|
||||
Class<?> moduleClass = getModule.getReturnType();
|
||||
getResourceAsStream = new ModuleAPI(moduleClass, "getResourceAsStream", String.class);
|
||||
isExportedTo = new ModuleAPI(moduleClass, "isExported", String.class, moduleClass);
|
||||
} else {
|
||||
ModuleAPI unavailable = new ModuleAPI();
|
||||
getModule = unavailable;
|
||||
getResourceAsStream = unavailable;
|
||||
isExportedTo = unavailable;
|
||||
}
|
||||
}
|
||||
|
||||
private ModuleAPI() {
|
||||
method = null;
|
||||
}
|
||||
}
|
@ -58,9 +58,9 @@ import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
||||
import org.graalvm.compiler.core.match.MatchRule;
|
||||
|
@ -80,7 +80,7 @@ import org.graalvm.compiler.phases.verify.VerifyUpdateUsages;
|
||||
import org.graalvm.compiler.phases.verify.VerifyUsageWithEquals;
|
||||
import org.graalvm.compiler.phases.verify.VerifyVirtualizableUsage;
|
||||
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||
import org.graalvm.word.LocationIdentity;
|
||||
import jdk.internal.vm.compiler.word.LocationIdentity;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
@ -103,14 +103,6 @@ import jdk.vm.ci.meta.Value;
|
||||
*/
|
||||
public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
|
||||
public CheckGraalInvariants() {
|
||||
try {
|
||||
Class.forName("java.lang.management.ManagementFactory");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
Assume.assumeNoException("cannot run without java.management JDK9 module", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldVerifyEquals(ResolvedJavaMethod m) {
|
||||
if (m.getName().equals("identityEquals")) {
|
||||
ResolvedJavaType c = m.getDeclaringClass();
|
||||
@ -148,7 +140,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
}
|
||||
|
||||
protected boolean shouldLoadClass(String className) {
|
||||
return !className.equals("module-info");
|
||||
return !className.equals("module-info") && !className.startsWith("META-INF.versions.");
|
||||
}
|
||||
|
||||
protected void handleClassLoadingException(Throwable t) {
|
||||
@ -191,7 +183,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
||||
for (final Enumeration<? extends ZipEntry> entry = zipFile.entries(); entry.hasMoreElements();) {
|
||||
final ZipEntry zipEntry = entry.nextElement();
|
||||
String name = zipEntry.getName();
|
||||
if (name.endsWith(".class")) {
|
||||
if (name.endsWith(".class") && !name.startsWith("META-INF/versions/")) {
|
||||
String className = name.substring(0, name.length() - ".class".length()).replace('/', '.');
|
||||
if (isInNativeImage(className)) {
|
||||
/*
|
||||
|
@ -27,7 +27,7 @@ import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.test;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.DebugContext.Scope;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
|
@ -26,8 +26,6 @@ import static org.graalvm.compiler.core.GraalCompiler.compileGraph;
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.OptAssumptions;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
|
||||
import org.graalvm.compiler.nodes.FullInfopointNode;
|
||||
@ -37,6 +35,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
|
||||
import org.graalvm.compiler.phases.OptimisticOptimizations;
|
||||
import org.graalvm.compiler.phases.PhaseSuite;
|
||||
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.code.site.Call;
|
||||
import jdk.vm.ci.code.site.Infopoint;
|
||||
@ -50,6 +49,11 @@ public class InfopointReasonTest extends GraalCompilerTest {
|
||||
|
||||
public static final String[] STRINGS = new String[]{"world", "everyone", "you"};
|
||||
|
||||
public InfopointReasonTest() {
|
||||
// Call testMethod to ensure all method references are resolved.
|
||||
testMethod();
|
||||
}
|
||||
|
||||
public String testMethod() {
|
||||
StringBuilder sb = new StringBuilder("Hello ");
|
||||
for (String s : STRINGS) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2018, 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
|
||||
@ -116,6 +116,7 @@ public class MarkUnsafeAccessTest extends GraalCompilerTest {
|
||||
|
||||
@Test
|
||||
public void testCompiled() throws IOException {
|
||||
Assume.assumeFalse("Crashes on AArch64 (GR-8351)", System.getProperty("os.arch").equalsIgnoreCase("aarch64"));
|
||||
ResolvedJavaMethod getMethod = asResolvedJavaMethod(getMethod(ByteBuffer.class, "get", new Class<?>[]{}));
|
||||
ResolvedJavaType mbbClass = getMetaAccess().lookupJavaType(MappedByteBuffer.class);
|
||||
ResolvedJavaMethod getMethodImpl = mbbClass.findUniqueConcreteMethod(getMethod).getResult();
|
||||
|
@ -33,7 +33,7 @@ import org.graalvm.compiler.loop.LoopsData;
|
||||
import org.graalvm.compiler.nodes.FieldLocationIdentity;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.memory.Access;
|
||||
import org.graalvm.word.LocationIdentity;
|
||||
import jdk.internal.vm.compiler.word.LocationIdentity;
|
||||
|
||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||
|
||||
|
@ -31,12 +31,13 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.MapCursor;
|
||||
import org.graalvm.compiler.options.Option;
|
||||
import org.graalvm.compiler.options.OptionDescriptor;
|
||||
import org.graalvm.compiler.options.OptionDescriptors;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionType;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
/**
|
||||
@ -108,8 +109,8 @@ public class ReflectionOptionDescriptors implements OptionDescriptors {
|
||||
ParameterizedType pt = (ParameterizedType) declaredType;
|
||||
Type[] actualTypeArguments = pt.getActualTypeArguments();
|
||||
assert actualTypeArguments.length == 1;
|
||||
Class<?> optionType = (Class<?>) actualTypeArguments[0];
|
||||
descriptors.put(fieldName, OptionDescriptor.create(fieldName, optionType, help, declaringClass, fieldName, (OptionKey<?>) f.get(null)));
|
||||
Class<?> optionValueType = (Class<?>) actualTypeArguments[0];
|
||||
descriptors.put(fieldName, OptionDescriptor.create(fieldName, OptionType.Debug, optionValueType, help, declaringClass, fieldName, (OptionKey<?>) f.get(null)));
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ package org.graalvm.compiler.core.test;
|
||||
|
||||
import org.graalvm.compiler.core.common.type.Stamp;
|
||||
import org.graalvm.compiler.core.common.type.StampFactory;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
@ -36,21 +35,23 @@ import jdk.vm.ci.meta.MemoryAccessProvider;
|
||||
*/
|
||||
public class StampMemoryAccessTest extends GraalCompilerTest {
|
||||
|
||||
@Ignore("not all JVMCI versions are safe yet")
|
||||
@Test
|
||||
public void testReadPrimitive() {
|
||||
MemoryAccessProvider memory = getConstantReflection().getMemoryAccessProvider();
|
||||
JavaConstant base = getSnippetReflection().forObject("");
|
||||
Stamp stamp = StampFactory.forKind(JavaKind.Long);
|
||||
assertTrue(stamp.readConstant(memory, base, 128) == null);
|
||||
JavaConstant objectBase = getSnippetReflection().forObject("");
|
||||
assertTrue(stamp.readConstant(memory, objectBase, 128) == null);
|
||||
JavaConstant arrayBase = getSnippetReflection().forObject(new int[]{});
|
||||
assertTrue(stamp.readConstant(memory, arrayBase, 128) == null);
|
||||
}
|
||||
|
||||
@Ignore("not all JVMCI versions are safe yet")
|
||||
@Test
|
||||
public void testReadObject() {
|
||||
MemoryAccessProvider memory = getConstantReflection().getMemoryAccessProvider();
|
||||
JavaConstant base = getSnippetReflection().forObject("");
|
||||
Stamp stamp = StampFactory.forKind(JavaKind.Object);
|
||||
assertTrue(stamp.readConstant(memory, base, 128) == null);
|
||||
JavaConstant objectBase = getSnippetReflection().forObject("");
|
||||
assertTrue(stamp.readConstant(memory, objectBase, 128) == null);
|
||||
JavaConstant arrayBase = getSnippetReflection().forObject(new int[]{});
|
||||
assertTrue(stamp.readConstant(memory, arrayBase, 128) == null);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
||||
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
@ -405,6 +406,8 @@ public class EscapeAnalysisTest extends EATestBase {
|
||||
*/
|
||||
@Test
|
||||
public void testNewNode() {
|
||||
// Trackking of creation interferes with escape analysis
|
||||
Assume.assumeFalse(Node.TRACK_CREATION_POSITION);
|
||||
testEscapeAnalysis("testNewNodeSnippet", null, false);
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,11 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.test.inlining;
|
||||
|
||||
import org.graalvm.compiler.core.common.GraalOptions;
|
||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.DebugDumpScope;
|
||||
import org.graalvm.compiler.debug.TTY;
|
||||
import org.graalvm.compiler.graph.Node;
|
||||
import org.graalvm.compiler.nodes.FullInfopointNode;
|
||||
import org.graalvm.compiler.nodes.Invoke;
|
||||
@ -32,18 +34,22 @@ import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph.Builder;
|
||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.phases.OptimisticOptimizations;
|
||||
import org.graalvm.compiler.phases.PhaseSuite;
|
||||
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
|
||||
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
|
||||
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.code.site.InfopointReason;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class InliningTest extends GraalCompilerTest {
|
||||
|
||||
@Test
|
||||
@ -198,6 +204,40 @@ public class InliningTest extends GraalCompilerTest {
|
||||
assertFewMethodInfopoints(assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet", true)));
|
||||
}
|
||||
|
||||
public static void traceInliningTest() {
|
||||
callTrivial();
|
||||
}
|
||||
|
||||
private static void callTrivial() {
|
||||
callNonTrivial();
|
||||
}
|
||||
|
||||
private static double callNonTrivial() {
|
||||
double x = 0.0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
x += i * 1.21;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("try")
|
||||
public void testTracing() {
|
||||
OptionValues options = new OptionValues(getInitialOptions(), GraalOptions.TraceInlining, true);
|
||||
StructuredGraph graph;
|
||||
try (TTY.Filter f = new TTY.Filter()) {
|
||||
graph = getGraph("traceInliningTest", options, false);
|
||||
}
|
||||
String inliningTree = graph.getInliningLog().formatAsTree(false);
|
||||
String expectedRegex = "compilation of org.graalvm.compiler.core.test.inlining.InliningTest.traceInliningTest.*: \\R" +
|
||||
" at .*org.graalvm.compiler.core.test.inlining.InliningTest.traceInliningTest.*: <GraphBuilderPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callTrivial.*: yes, inline method\\R" +
|
||||
" at .*org.graalvm.compiler.core.test.inlining.InliningTest.callTrivial.*: .*\\R" +
|
||||
" .*<GraphBuilderPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callNonTrivial.*: .*(.*\\R)*" +
|
||||
" .*<InliningPhase> org.graalvm.compiler.core.test.inlining.InliningTest.callNonTrivial.*: .*(.*\\R)*";
|
||||
Pattern expectedPattern = Pattern.compile(expectedRegex, Pattern.MULTILINE);
|
||||
Assert.assertTrue("Got: " + inliningTree, expectedPattern.matcher(inliningTree).matches());
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public static int invokeLeafClassMethodSnippet(SubClassA subClassA) {
|
||||
return subClassA.publicFinalMethod() + subClassA.publicNotOverriddenMethod() + subClassA.publicOverriddenMethod();
|
||||
@ -233,9 +273,13 @@ public class InliningTest extends GraalCompilerTest {
|
||||
return superClass.protectedOverriddenMethod();
|
||||
}
|
||||
|
||||
@SuppressWarnings("try")
|
||||
private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
|
||||
DebugContext debug = getDebugContext();
|
||||
return getGraph(snippet, null, eagerInfopointMode);
|
||||
}
|
||||
|
||||
@SuppressWarnings("try")
|
||||
private StructuredGraph getGraph(final String snippet, OptionValues options, final boolean eagerInfopointMode) {
|
||||
DebugContext debug = options == null ? getDebugContext() : getDebugContext(options, null, null);
|
||||
try (DebugContext.Scope s = debug.scope("InliningTest", new DebugDumpScope(snippet, true))) {
|
||||
ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
|
||||
Builder builder = builder(method, AllowAssumptions.YES, debug);
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.core.test.inlining;
|
||||
|
||||
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.TTY;
|
||||
@ -137,7 +137,8 @@ public class NestedLoopEffectsPhaseComplexityTest extends GraalCompilerTest {
|
||||
ResolvedJavaMethod calleeMethod = next.callTarget().targetMethod();
|
||||
for (int i = 0; i < inliningCount; i++) {
|
||||
next = callerGraph.getNodes(MethodCallTargetNode.TYPE).first().invoke();
|
||||
EconomicSet<Node> canonicalizeNodes = InliningUtil.inlineForCanonicalization(next, calleeGraph, false, calleeMethod);
|
||||
EconomicSet<Node> canonicalizeNodes = InliningUtil.inlineForCanonicalization(next, calleeGraph, false, calleeMethod, null,
|
||||
"Called explicitly from a unit test.", "Test case");
|
||||
canonicalizer.applyIncremental(callerGraph, context, canonicalizeNodes);
|
||||
callerGraph.getDebug().dump(DebugContext.DETAILED_LEVEL, callerGraph, "After inlining %s into %s iteration %d", calleeMethod, callerMethod, i);
|
||||
}
|
||||
|
@ -23,10 +23,11 @@
|
||||
package org.graalvm.compiler.core;
|
||||
|
||||
import static org.graalvm.compiler.core.GraalCompilerOptions.PrintCompilation;
|
||||
import static org.graalvm.compiler.serviceprovider.GraalServices.getCurrentThreadAllocatedBytes;
|
||||
import static org.graalvm.compiler.serviceprovider.GraalServices.isThreadAllocatedMemorySupported;
|
||||
|
||||
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;
|
||||
|
||||
@ -58,11 +59,6 @@ public final class CompilationPrinter {
|
||||
*/
|
||||
public static CompilationPrinter begin(OptionValues options, CompilationIdentifier id, JavaMethod method, int entryBCI) {
|
||||
if (PrintCompilation.getValue(options) && !TTY.isSuppressed()) {
|
||||
try {
|
||||
Class.forName("java.lang.management.ManagementFactory");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new IllegalArgumentException("PrintCompilation option requires java.management module");
|
||||
}
|
||||
return new CompilationPrinter(id, method, entryBCI);
|
||||
}
|
||||
return DISABLED;
|
||||
@ -83,9 +79,8 @@ public final class CompilationPrinter {
|
||||
this.id = id;
|
||||
this.entryBCI = entryBCI;
|
||||
|
||||
final long threadId = Thread.currentThread().getId();
|
||||
start = System.nanoTime();
|
||||
allocatedBytesBefore = getAllocatedBytes(threadId);
|
||||
allocatedBytesBefore = isThreadAllocatedMemorySupported() ? getCurrentThreadAllocatedBytes() : -1;
|
||||
}
|
||||
|
||||
private String getMethodDescription() {
|
||||
@ -101,24 +96,17 @@ public final class CompilationPrinter {
|
||||
*/
|
||||
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));
|
||||
if (allocatedBytesBefore == -1) {
|
||||
TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dB", duration, bytecodeSize, targetCodeSize));
|
||||
} else {
|
||||
final long allocatedBytesAfter = getCurrentThreadAllocatedBytes();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -122,8 +122,10 @@ public abstract class CompilationWrapper<T> {
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param cause the cause of the bailout or failure
|
||||
*/
|
||||
protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey) {
|
||||
protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey, Throwable cause) {
|
||||
if (actionKey == CompilationFailureAction) {
|
||||
if (ExitVMOnException.getValue(options)) {
|
||||
assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
|
||||
@ -175,7 +177,7 @@ public abstract class CompilationWrapper<T> {
|
||||
actionKey = CompilationFailureAction;
|
||||
causeType = "failure";
|
||||
}
|
||||
ExceptionAction action = lookupAction(initialOptions, actionKey);
|
||||
ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
|
||||
|
||||
action = adjustAction(initialOptions, actionKey, action);
|
||||
|
||||
@ -262,22 +264,34 @@ public abstract class CompilationWrapper<T> {
|
||||
DumpPath, dumpPath.getPath());
|
||||
|
||||
try (DebugContext retryDebug = createRetryDebugContext(retryOptions)) {
|
||||
return performCompilation(retryDebug);
|
||||
T res = performCompilation(retryDebug);
|
||||
maybeExitVM(action);
|
||||
return res;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
T res = handleException(cause);
|
||||
maybeExitVM(action);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeExitVM(ExceptionAction action) {
|
||||
if (action == ExitVM) {
|
||||
synchronized (ExceptionAction.class) {
|
||||
try {
|
||||
// Give other compiler threads a chance to flush
|
||||
// error handling output.
|
||||
ExceptionAction.class.wait(2000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
TTY.println("Exiting VM after retry compilation of " + this);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts {@code initialAction} if necessary based on
|
||||
* {@link GraalCompilerOptions#MaxCompilationProblemsPerAction}.
|
||||
|
@ -25,10 +25,12 @@ package org.graalvm.compiler.core;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
|
||||
import org.graalvm.compiler.core.common.GraalOptions;
|
||||
import org.graalvm.compiler.core.common.PermanentBailoutException;
|
||||
import org.graalvm.compiler.core.common.RetryableBailoutException;
|
||||
import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder;
|
||||
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
|
||||
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
|
||||
@ -188,8 +190,18 @@ public class GraalCompiler {
|
||||
* {@code graph.method()} or {@code graph.name}
|
||||
*/
|
||||
private static void checkForRequestedCrash(StructuredGraph graph) {
|
||||
String methodPattern = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
|
||||
if (methodPattern != null) {
|
||||
String value = GraalCompilerOptions.CrashAt.getValue(graph.getOptions());
|
||||
if (value != null) {
|
||||
boolean bailout = false;
|
||||
boolean permanentBailout = false;
|
||||
String methodPattern = value;
|
||||
if (value.endsWith(":Bailout")) {
|
||||
methodPattern = value.substring(0, value.length() - ":Bailout".length());
|
||||
bailout = true;
|
||||
} else if (value.endsWith(":PermanentBailout")) {
|
||||
methodPattern = value.substring(0, value.length() - ":PermanentBailout".length());
|
||||
permanentBailout = true;
|
||||
}
|
||||
String crashLabel = null;
|
||||
if (graph.name != null && graph.name.contains(methodPattern)) {
|
||||
crashLabel = graph.name;
|
||||
@ -204,6 +216,12 @@ public class GraalCompiler {
|
||||
}
|
||||
}
|
||||
if (crashLabel != null) {
|
||||
if (permanentBailout) {
|
||||
throw new PermanentBailoutException("Forced crash after compiling " + crashLabel);
|
||||
}
|
||||
if (bailout) {
|
||||
throw new RetryableBailoutException("Forced crash after compiling " + crashLabel);
|
||||
}
|
||||
throw new RuntimeException("Forced crash after compiling " + crashLabel);
|
||||
}
|
||||
}
|
||||
|
@ -38,12 +38,14 @@ public class GraalCompilerOptions {
|
||||
public static final OptionKey<Boolean> PrintCompilation = new OptionKey<>(false);
|
||||
@Option(help = "Pattern for method(s) that will trigger an exception when compiled. " +
|
||||
"This option exists to test handling compilation crashes gracefully. " +
|
||||
"See the MethodFilter option for the pattern syntax. ", type = OptionType.Debug)
|
||||
"See the MethodFilter option for the pattern syntax. A ':Bailout' " +
|
||||
"suffix will raise a bailout exception and a ':PermanentBailout' " +
|
||||
"suffix will raise a permanent bailout exception.", type = OptionType.Debug)
|
||||
public static final OptionKey<String> CrashAt = new OptionKey<>(null);
|
||||
@Option(help = "file:doc-files/CompilationBailoutActionHelp.txt", type = OptionType.User)
|
||||
public static final EnumOptionKey<ExceptionAction> CompilationBailoutAction = new EnumOptionKey<>(ExceptionAction.Silent);
|
||||
@Option(help = "Specifies the action to take when compilation fails with a bailout exception. " +
|
||||
"The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
|
||||
"The accepted values are the same as for CompilationBailoutAction.", type = OptionType.User)
|
||||
public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Diagnose);
|
||||
@Option(help = "The maximum number of compilation failures or bailouts to handle with the action specified " +
|
||||
"by CompilationFailureAction or CompilationBailoutAction before changing to a less verbose action.", type = OptionType.User)
|
||||
|
@ -26,8 +26,8 @@ import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.debug.CounterKey;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.GraalError;
|
||||
|
@ -33,8 +33,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.UnmodifiableMapCursor;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
import org.graalvm.compiler.core.common.calc.Condition;
|
||||
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
|
||||
|
@ -28,8 +28,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
||||
import org.graalvm.compiler.core.match.MatchPattern.Result;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
|
@ -27,9 +27,9 @@ import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.MapCursor;
|
||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.GraalError;
|
||||
|
@ -36,7 +36,10 @@ import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.LowTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.MidTierContext;
|
||||
|
||||
public class CoreCompilerConfiguration implements CompilerConfiguration {
|
||||
/**
|
||||
* The default configuration for the community edition of Graal.
|
||||
*/
|
||||
public class CommunityCompilerConfiguration implements CompilerConfiguration {
|
||||
|
||||
@Override
|
||||
public PhaseSuite<HighTierContext> createHighTier(OptionValues options) {
|
@ -36,6 +36,10 @@ import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.LowTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.MidTierContext;
|
||||
|
||||
/**
|
||||
* A compiler configuration that performs fewer Graal IR optimizations while using the same backend
|
||||
* as the {@link CommunityCompilerConfiguration}.
|
||||
*/
|
||||
public class EconomyCompilerConfiguration implements CompilerConfiguration {
|
||||
|
||||
@Override
|
||||
|
@ -22,8 +22,8 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.phases;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.graph.Graph.NodeEvent;
|
||||
import org.graalvm.compiler.graph.Graph.NodeEventScope;
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.core.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import org.graalvm.compiler.asm.Assembler;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||
@ -41,6 +41,7 @@ import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
|
||||
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.GraphSpeculationLog;
|
||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||
import org.graalvm.compiler.phases.tiers.SuitesProvider;
|
||||
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
||||
@ -209,7 +210,7 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
||||
try {
|
||||
preCodeInstallationTasks(tasks, compilationResult, predefinedInstalledCode);
|
||||
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
||||
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
||||
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, GraphSpeculationLog.unwrap(speculationLog), isDefault);
|
||||
assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
|
||||
} catch (Throwable t) {
|
||||
failCodeInstallationTasks(tasks, t);
|
||||
|
@ -34,7 +34,7 @@ import java.util.Collections;
|
||||
import java.util.Formatter;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.Assertions;
|
||||
import org.graalvm.compiler.debug.CounterKey;
|
||||
import org.graalvm.compiler.debug.DebugCloseable;
|
||||
|
@ -28,16 +28,14 @@ import static org.graalvm.compiler.debug.DebugContext.NO_DESCRIPTION;
|
||||
import static org.graalvm.compiler.debug.DebugContext.NO_GLOBAL_METRIC_VALUES;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.management.ThreadMXBean;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugCloseable;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
import org.graalvm.compiler.debug.Management;
|
||||
import org.graalvm.compiler.debug.TimerKey;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -47,12 +45,7 @@ public class TimerKeyTest {
|
||||
|
||||
@Before
|
||||
public void checkCapabilities() {
|
||||
try {
|
||||
ThreadMXBean threadMXBean = Management.getThreadMXBean();
|
||||
Assume.assumeTrue("skipping management interface test", threadMXBean.isCurrentThreadCpuTimeSupported());
|
||||
} catch (LinkageError err) {
|
||||
Assume.assumeNoException("Cannot run without java.management JDK9 module", err);
|
||||
}
|
||||
Assume.assumeTrue("skipping management interface test", GraalServices.isCurrentThreadCpuTimeSupported());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,10 +56,9 @@ public class TimerKeyTest {
|
||||
* {@code ms}
|
||||
*/
|
||||
private static long spin(long ms) {
|
||||
ThreadMXBean threadMXBean = Management.getThreadMXBean();
|
||||
long start = threadMXBean.getCurrentThreadCpuTime();
|
||||
long start = GraalServices.getCurrentThreadCpuTime();
|
||||
do {
|
||||
long durationMS = (threadMXBean.getCurrentThreadCpuTime() - start) / 1000;
|
||||
long durationMS = (GraalServices.getCurrentThreadCpuTime() - start) / 1000;
|
||||
if (durationMS >= ms) {
|
||||
return durationMS;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
package org.graalvm.compiler.debug;
|
||||
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
|
||||
class CounterKeyImpl extends AbstractKey implements CounterKey {
|
||||
|
||||
|
@ -264,9 +264,8 @@ final class DebugConfigImpl implements DebugConfig {
|
||||
firstSeen.put(o, o);
|
||||
if (DebugOptions.DumpOnError.getValue(options) || DebugOptions.Dump.getValue(options) != null) {
|
||||
debug.dump(DebugContext.BASIC_LEVEL, o, "Exception: %s", e);
|
||||
} else {
|
||||
debug.log("Context obj %s", o);
|
||||
}
|
||||
debug.log("Context obj %s", o);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -56,11 +56,12 @@ import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicSet;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
import org.graalvm.graphio.GraphOutput;
|
||||
|
||||
import jdk.vm.ci.meta.JavaMethod;
|
||||
@ -236,14 +237,15 @@ public final class DebugContext implements AutoCloseable {
|
||||
this.unscopedTimers = parseUnscopedMetricSpec(Timers.getValue(options), "".equals(timeValue), true);
|
||||
this.unscopedMemUseTrackers = parseUnscopedMetricSpec(MemUseTrackers.getValue(options), "".equals(trackMemUseValue), true);
|
||||
|
||||
if (unscopedTimers != null ||
|
||||
unscopedMemUseTrackers != null ||
|
||||
timeValue != null ||
|
||||
trackMemUseValue != null) {
|
||||
try {
|
||||
Class.forName("java.lang.management.ManagementFactory");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new IllegalArgumentException("Time, Timers, MemUseTrackers and TrackMemUse options require java.management module");
|
||||
if (unscopedTimers != null || timeValue != null) {
|
||||
if (!GraalServices.isCurrentThreadCpuTimeSupported()) {
|
||||
throw new IllegalArgumentException("Time and Timers options require VM support for querying CPU time");
|
||||
}
|
||||
}
|
||||
|
||||
if (unscopedMemUseTrackers != null || trackMemUseValue != null) {
|
||||
if (!GraalServices.isThreadAllocatedMemorySupported()) {
|
||||
throw new IllegalArgumentException("MemUseTrackers and TrackMemUse options require VM support for querying thread allocated memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,11 +27,12 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import org.graalvm.compiler.options.Option;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionType;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
|
||||
/**
|
||||
* Options that configure a {@link DebugContext} and related functionality.
|
||||
@ -133,9 +134,7 @@ public class DebugOptions {
|
||||
|
||||
@Option(help = "Host part of the address to which graphs are dumped.", type = OptionType.Debug)
|
||||
public static final OptionKey<String> PrintGraphHost = new OptionKey<>("127.0.0.1");
|
||||
@Option(help = "Port part of the address to which graphs are dumped in XML format (ignored if PrintBinaryGraphs=true).", type = OptionType.Debug)
|
||||
public static final OptionKey<Integer> PrintXmlGraphPort = new OptionKey<>(4444);
|
||||
@Option(help = "Port part of the address to which graphs are dumped in binary format (ignored if PrintBinaryGraphs=false).", type = OptionType.Debug)
|
||||
@Option(help = "Port part of the address to which graphs are dumped in binary format.", type = OptionType.Debug)
|
||||
public static final OptionKey<Integer> PrintBinaryGraphPort = new OptionKey<>(4445);
|
||||
@Option(help = "Schedule graphs as they are dumped.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> PrintGraphWithSchedule = new OptionKey<>(false);
|
||||
@ -164,23 +163,10 @@ public class DebugOptions {
|
||||
@Option(help = "Do not compile anything on bootstrap but just initialize the compiler.", type = OptionType.Debug)
|
||||
public static final OptionKey<Boolean> BootstrapInitializeOnly = new OptionKey<>(false);
|
||||
|
||||
// These will be removed at some point
|
||||
@Option(help = "Deprecated - use PrintGraphHost instead.", type = OptionType.Debug)
|
||||
static final OptionKey<String> PrintIdealGraphAddress = new DebugOptions.DeprecatedOptionKey<>(PrintGraphHost);
|
||||
@Option(help = "Deprecated - use PrintGraphWithSchedule instead.", type = OptionType.Debug)
|
||||
static final OptionKey<Boolean> PrintIdealGraphSchedule = new DebugOptions.DeprecatedOptionKey<>(PrintGraphWithSchedule);
|
||||
@Option(help = "Deprecated - use PrintGraph instead.", type = OptionType.Debug)
|
||||
static final OptionKey<Boolean> PrintIdealGraph = new DebugOptions.DeprecatedOptionKey<>(PrintGraph);
|
||||
@Option(help = "Deprecated - use PrintGraphFile instead.", type = OptionType.Debug)
|
||||
static final OptionKey<Boolean> PrintIdealGraphFile = new DebugOptions.DeprecatedOptionKey<>(PrintGraphFile);
|
||||
@Option(help = "Deprecated - use PrintXmlGraphPort instead.", type = OptionType.Debug)
|
||||
static final OptionKey<Integer> PrintIdealGraphPort = new DebugOptions.DeprecatedOptionKey<>(PrintXmlGraphPort);
|
||||
// @formatter:on
|
||||
|
||||
/**
|
||||
* 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 PathUtilities#getGlobalTimeStamp()}.
|
||||
* the default value of {@link #DumpPath} and {@link GraalServices#getGlobalTimeStamp()}.
|
||||
*
|
||||
* This method will ensure the returned directory exists, printing a message to {@link TTY} if
|
||||
* it creates it.
|
||||
@ -193,14 +179,16 @@ public class DebugOptions {
|
||||
if (DumpPath.hasBeenSet(options)) {
|
||||
dumpDir = Paths.get(DumpPath.getValue(options));
|
||||
} else {
|
||||
dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(PathUtilities.getGlobalTimeStamp()));
|
||||
dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(GraalServices.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.toString());
|
||||
if (ShowDumpFiles.getValue(options)) {
|
||||
TTY.println("Dumping debug output in %s", dumpDir.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
|
||||
/**
|
||||
* Manages a directory into which diagnostics such crash reports and dumps should be written. The
|
||||
@ -69,26 +70,6 @@ public class DiagnosticsOutputDirectory {
|
||||
return getPath(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unique identifier for this execution such as a process ID.
|
||||
*/
|
||||
protected String getExecutionID() {
|
||||
try {
|
||||
String runtimeName = java.lang.management.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;
|
||||
} catch (LinkageError err) {
|
||||
return String.valueOf(org.graalvm.compiler.debug.PathUtilities.getGlobalTimeStamp());
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized String getPath(boolean createIfNull) {
|
||||
if (path == null && createIfNull) {
|
||||
path = createPath();
|
||||
@ -120,7 +101,7 @@ public class DiagnosticsOutputDirectory {
|
||||
// directory specified by the DumpPath option.
|
||||
baseDir = Paths.get(".");
|
||||
}
|
||||
return baseDir.resolve("graal_diagnostics_" + getExecutionID()).toAbsolutePath().toString();
|
||||
return baseDir.resolve("graal_diagnostics_" + GraalServices.getExecutionID()).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,9 +29,9 @@ import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.MapCursor;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ package org.graalvm.compiler.debug;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
|
||||
/**
|
||||
* Registry for allocating a globally unique integer id to each {@link AbstractKey}.
|
||||
|
@ -1,226 +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.
|
||||
*
|
||||
* 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 static java.lang.Thread.currentThread;
|
||||
|
||||
public class Management {
|
||||
|
||||
private static final com.sun.management.ThreadMXBean threadMXBean = Management.initThreadMXBean();
|
||||
|
||||
/**
|
||||
* The amount of memory allocated by
|
||||
* {@link com.sun.management.ThreadMXBean#getThreadAllocatedBytes(long)} itself.
|
||||
*/
|
||||
private static final long threadMXBeanOverhead = -getCurrentThreadAllocatedBytes() + getCurrentThreadAllocatedBytes();
|
||||
|
||||
public static long getCurrentThreadAllocatedBytes() {
|
||||
return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead;
|
||||
}
|
||||
|
||||
private static com.sun.management.ThreadMXBean initThreadMXBean() {
|
||||
try {
|
||||
return (com.sun.management.ThreadMXBean) java.lang.management.ManagementFactory.getThreadMXBean();
|
||||
} catch (Error err) {
|
||||
return new UnimplementedBean();
|
||||
}
|
||||
}
|
||||
|
||||
public static java.lang.management.ThreadMXBean getThreadMXBean() {
|
||||
return threadMXBean;
|
||||
}
|
||||
|
||||
private static class UnimplementedBean implements java.lang.management.ThreadMXBean, com.sun.management.ThreadMXBean {
|
||||
|
||||
@Override
|
||||
public javax.management.ObjectName getObjectName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getThreadAllocatedBytes(long arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getThreadAllocatedBytes(long[] arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getThreadCpuTime(long[] arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getThreadUserTime(long[] arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadAllocatedMemoryEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadAllocatedMemorySupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThreadAllocatedMemoryEnabled(boolean arg0) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThreadCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPeakThreadCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalStartedThreadCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDaemonThreadCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getAllThreadIds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo getThreadInfo(long id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo getThreadInfo(long id, int maxDepth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadContentionMonitoringSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadContentionMonitoringEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThreadContentionMonitoringEnabled(boolean enable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentThreadCpuTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCurrentThreadUserTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getThreadCpuTime(long id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getThreadUserTime(long id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadCpuTimeSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentThreadCpuTimeSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreadCpuTimeEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThreadCpuTimeEnabled(boolean enable) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] findMonitorDeadlockedThreads() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetPeakThreadCount() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] findDeadlockedThreads() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjectMonitorUsageSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSynchronizerUsageSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.lang.management.ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,8 @@
|
||||
*/
|
||||
package org.graalvm.compiler.debug;
|
||||
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
|
||||
/**
|
||||
* Tracks memory usage within a scope using {@link com.sun.management.ThreadMXBean}. This facility
|
||||
* should be employed using the try-with-resources pattern:
|
||||
@ -52,6 +54,6 @@ public interface MemUseTrackerKey extends MetricKey {
|
||||
MemUseTrackerKey doc(String string);
|
||||
|
||||
static long getCurrentThreadAllocatedBytes() {
|
||||
return Management.getCurrentThreadAllocatedBytes();
|
||||
return GraalServices.getCurrentThreadAllocatedBytes();
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
||||
|
||||
import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
||||
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
|
||||
class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey {
|
||||
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
|
||||
/**
|
||||
* A key for a metric.
|
||||
|
@ -29,7 +29,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
@ -39,19 +38,6 @@ import org.graalvm.compiler.options.OptionValues;
|
||||
*/
|
||||
public class PathUtilities {
|
||||
|
||||
private static final AtomicLong globalTimeStamp = new AtomicLong();
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
return globalTimeStamp.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value based on {@code name} that can be passed to {@link Paths#get(String, String...)}
|
||||
* without causing an {@link InvalidPathException}.
|
||||
|
@ -22,21 +22,13 @@
|
||||
*/
|
||||
package org.graalvm.compiler.debug;
|
||||
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
|
||||
/**
|
||||
* A consistent source of timing data that should be used by all facilities in the debug package.
|
||||
*/
|
||||
public class TimeSource {
|
||||
private static final boolean USING_BEAN;
|
||||
private static final java.lang.management.ThreadMXBean threadMXBean;
|
||||
|
||||
static {
|
||||
threadMXBean = Management.getThreadMXBean();
|
||||
if (threadMXBean.isThreadCpuTimeSupported()) {
|
||||
USING_BEAN = true;
|
||||
} else {
|
||||
USING_BEAN = false;
|
||||
}
|
||||
}
|
||||
private static final boolean USING_THREAD_CPU_TIME = GraalServices.isCurrentThreadCpuTimeSupported();
|
||||
|
||||
/**
|
||||
* Gets the current time of this thread in nanoseconds from the most accurate timer available on
|
||||
@ -50,7 +42,7 @@ public class TimeSource {
|
||||
* @return the current thread's time in nanoseconds
|
||||
*/
|
||||
public static long getTimeNS() {
|
||||
return USING_BEAN ? threadMXBean.getCurrentThreadCpuTime() : System.nanoTime();
|
||||
return USING_THREAD_CPU_TIME ? GraalServices.getCurrentThreadCpuTime() : System.nanoTime();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.graalvm.collections.Pair;
|
||||
import jdk.internal.vm.compiler.collections.Pair;
|
||||
|
||||
final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
|
||||
static class FlatTimer extends AbstractKey implements TimerKey {
|
||||
|
@ -1,241 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
This configuration file was written by the eclipse-cs plugin configuration editor
|
||||
-->
|
||||
<!--
|
||||
Checkstyle-Configuration: Checks
|
||||
Description: none
|
||||
-->
|
||||
<module name="Checker">
|
||||
<property name="severity" value="error"/>
|
||||
<module name="TreeWalker">
|
||||
<module name="AvoidStarImport">
|
||||
<property name="allowClassImports" value="false"/>
|
||||
<property name="allowStaticMemberImports" value="false"/>
|
||||
</module>
|
||||
<property name="tabWidth" value="4"/>
|
||||
<module name="FileContentsHolder"/>
|
||||
<module name="JavadocStyle">
|
||||
<property name="checkHtml" value="false"/>
|
||||
</module>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^(([a-z][a-zA-Z0-9]*$)|(_[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$))"/>
|
||||
</module>
|
||||
<module name="MethodName"/>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="TypeName">
|
||||
<property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="250"/>
|
||||
</module>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
|
||||
</module>
|
||||
<module name="NoWhitespaceBefore">
|
||||
<property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
|
||||
</module>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad">
|
||||
<property name="tokens" value="RPAREN,TYPECAST"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAND,LE,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
|
||||
</module>
|
||||
<module name="RedundantModifier"/>
|
||||
<module name="AvoidNestedBlocks">
|
||||
<property name="allowInSwitchCase" value="true"/>
|
||||
</module>
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="text"/>
|
||||
<property name="tokens" value="LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_IF,LITERAL_TRY,LITERAL_WHILE,STATIC_INIT"/>
|
||||
</module>
|
||||
<module name="LeftCurly"/>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="RightCurly"/>
|
||||
<module name="EmptyStatement"/>
|
||||
<module name="HiddenField">
|
||||
<property name="severity" value="ignore"/>
|
||||
<property name="ignoreConstructorParameter" value="true"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="FinalClass"/>
|
||||
<module name="HideUtilityClassConstructor">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="UpperEll"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="FinalLocalVariable">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="StringLiteralEquality">
|
||||
<property name="severity" value="error"/>
|
||||
</module>
|
||||
<module name="SuperFinalize"/>
|
||||
<module name="UnnecessaryParentheses">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="Indentation">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="StaticVariableName">
|
||||
<property name="format" value="^[A-Za-z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="DefaultComesLast"/>
|
||||
<module name="InnerAssignment">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="ModifiedControlVariable"/>
|
||||
<module name="MutableException">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="ParameterAssignment">
|
||||
<property name="severity" value="ignore"/>
|
||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<metadata name="net.sf.eclipsecs.core.comment" value="Illegal trailing whitespace(s) at the end of the line."/>
|
||||
<property name="format" value="\s$"/>
|
||||
<property name="message" value="Illegal trailing whitespace(s) at the end of the line."/>
|
||||
<property name="ignoreComments" value="false"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for trailing spaces at the end of a line"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<metadata name="net.sf.eclipsecs.core.comment" value="illegal space before a comma"/>
|
||||
<property name="format" value=" ,"/>
|
||||
<property name="message" value="illegal space before a comma"/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Checks for whitespace before a comma."/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.customMessage" value="Illegal whitespace before a comma."/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="[^\x00-\x7F]"/>
|
||||
<property name="message" value="Only use ASCII characters."/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="new (Hashtable|Vector|Stack|StringBuffer)[^\w]"/>
|
||||
<property name="message" value="Don't use old synchronized collection classes"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="instanceof MoveOp"/>
|
||||
<property name="message" value="Do not use `op instanceof MoveOp`. Use `MoveOp.isMoveOp(op)` instead!"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="instanceof ValueMoveOp"/>
|
||||
<property name="message" value="Do not use `op instanceof ValueMoveOp`. Use `ValueMoveOp.isValueMoveOp(op)` instead!"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="instanceof LoadConstantOp"/>
|
||||
<property name="message" value="Do not use `op instanceof LoadConstantOp`. Use `LoadConstantOp.isLoadConstantOp(op)` instead!"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="\(MoveOp\)"/>
|
||||
<property name="message" value="Do not cast directly to `MoveOp`. Use `MoveOp.asMoveOp(op)` instead!"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="\(ValueMoveOp\)"/>
|
||||
<property name="message" value="Do not cast directly to `ValueMoveOp`. Use `ValueMoveOp.asValueMoveOp(op)` instead!"/>
|
||||
</module>
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="\(LoadConstantOp\)"/>
|
||||
<property name="message" value="Do not cast directly to `LoadConstantOp`. Use `LoadConstantOp.asLoadConstantOp(op)` instead!"/>
|
||||
</module>
|
||||
</module>
|
||||
<module name="RegexpHeader">
|
||||
<property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates\. All rights reserved\.\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], .*\. All rights reserved\.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER\.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation\.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE\. See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\)\.\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc\., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www\.oracle\.com if you need additional information or have any\n \* questions\.\n \*/\n"/>
|
||||
<property name="multiLines" value="3"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
<module name="FileTabCharacter">
|
||||
<property name="severity" value="error"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
<module name="NewlineAtEndOfFile">
|
||||
<property name="lineSeparator" value="lf"/>
|
||||
</module>
|
||||
<module name="Translation"/>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
|
||||
<property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
|
||||
<property name="checkFormat" value="ConstantNameCheck"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="Checkstyle: stop method name check"/>
|
||||
<property name="onCommentFormat" value="Checkstyle: resume method name check"/>
|
||||
<property name="checkFormat" value="MethodName"/>
|
||||
<property name="checkC" value="false"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
|
||||
<property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
|
||||
<property name="checkFormat" value="ParameterAssignment"/>
|
||||
<property name="checkC" value="false"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
|
||||
<property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
|
||||
<property name="checkFormat" value="FinalLocalVariable"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="Checkstyle: stop"/>
|
||||
<property name="onCommentFormat" value="Checkstyle: resume"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
|
||||
<property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
|
||||
<property name="checkFormat" value="InnerAssignment"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="Checkstyle: stop field name check"/>
|
||||
<property name="onCommentFormat" value="Checkstyle: resume field name check"/>
|
||||
<property name="checkFormat" value="MemberName"/>
|
||||
<property name="checkC" value="false"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
|
||||
</module>
|
||||
<module name="RegexpMultiline">
|
||||
<metadata name="net.sf.eclipsecs.core.comment" value="illegal Windows line ending"/>
|
||||
<property name="format" value="\r\n"/>
|
||||
<property name="message" value="illegal Windows line ending"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CheckStyle: stop header check"/>
|
||||
<property name="onCommentFormat" value="CheckStyle: resume header check"/>
|
||||
<property name="checkFormat" value=".*Header"/>
|
||||
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CheckStyle: stop line length check"/>
|
||||
<property name="onCommentFormat" value="CheckStyle: resume line length check"/>
|
||||
<property name="checkFormat" value="LineLength"/>
|
||||
</module>
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CheckStyle: start generated"/>
|
||||
<property name="onCommentFormat" value="CheckStyle: stop generated"/>
|
||||
<property name="checkFormat" value=".*Name|.*LineLength|.*Header"/>
|
||||
</module>
|
||||
</module>
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.graph;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
|
||||
|
||||
/**
|
||||
* This class is a container of a graph that needs to be readonly and optionally a lazily created
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
package org.graalvm.compiler.graph;
|
||||
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.TrackNodeInsertion;
|
||||
import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Default;
|
||||
import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Track;
|
||||
import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.UpdateOnly;
|
||||
@ -33,15 +34,16 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
|
||||
import org.graalvm.compiler.core.common.GraalOptions;
|
||||
import org.graalvm.compiler.debug.CounterKey;
|
||||
import org.graalvm.compiler.debug.DebugCloseable;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.GraalError;
|
||||
import org.graalvm.compiler.debug.TimerKey;
|
||||
import org.graalvm.compiler.graph.Node.NodeInsertionStackTrace;
|
||||
import org.graalvm.compiler.graph.Node.ValueNumberable;
|
||||
import org.graalvm.compiler.graph.iterators.NodeIterable;
|
||||
import org.graalvm.compiler.options.Option;
|
||||
@ -49,6 +51,8 @@ import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionType;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
/**
|
||||
* This class is a graph container, it contains the set of nodes that belong to this graph.
|
||||
*/
|
||||
@ -195,7 +199,7 @@ public class Graph {
|
||||
* was opened
|
||||
*/
|
||||
public DebugCloseable withNodeSourcePosition(Node node) {
|
||||
return withNodeSourcePosition(node.sourcePosition);
|
||||
return withNodeSourcePosition(node.getNodeSourcePosition());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -719,6 +723,9 @@ public class Graph {
|
||||
assert node.getNodeClass().valueNumberable();
|
||||
T other = this.findDuplicate(node);
|
||||
if (other != null) {
|
||||
if (other.getNodeSourcePosition() == null) {
|
||||
other.setNodeSourcePosition(node.getNodeSourcePosition());
|
||||
}
|
||||
return other;
|
||||
} else {
|
||||
T result = addHelper(node);
|
||||
@ -1097,6 +1104,9 @@ public class Graph {
|
||||
if (currentNodeSourcePosition != null && trackNodeSourcePosition()) {
|
||||
node.setNodeSourcePosition(currentNodeSourcePosition);
|
||||
}
|
||||
if (TrackNodeInsertion.getValue(getOptions())) {
|
||||
node.setInsertionPosition(new NodeInsertionStackTrace());
|
||||
}
|
||||
|
||||
updateNodeCaches(node);
|
||||
|
||||
@ -1189,6 +1199,23 @@ public class Graph {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean verifySourcePositions() {
|
||||
if (trackNodeSourcePosition()) {
|
||||
ResolvedJavaMethod root = null;
|
||||
for (Node node : getNodes()) {
|
||||
NodeSourcePosition pos = node.getNodeSourcePosition();
|
||||
if (pos != null) {
|
||||
if (root == null) {
|
||||
root = pos.getRootMethod();
|
||||
} else {
|
||||
assert pos.verifyRootMethod(root) : node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Node getNode(int id) {
|
||||
return nodes[id];
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Formattable;
|
||||
@ -84,7 +85,8 @@ import sun.misc.Unsafe;
|
||||
public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
|
||||
public static final NodeClass<?> TYPE = null;
|
||||
public static final boolean USE_UNSAFE_TO_CLONE = true;
|
||||
|
||||
public static final boolean TRACK_CREATION_POSITION = Boolean.getBoolean("debug.graal.TrackNodeCreationPosition");
|
||||
|
||||
static final int DELETED_ID_START = -1000000000;
|
||||
static final int INITIAL_ID = -1;
|
||||
@ -230,6 +232,40 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
public static final int NODE_LIST = -2;
|
||||
public static final int NOT_ITERABLE = -1;
|
||||
|
||||
static class NodeStackTrace {
|
||||
final StackTraceElement[] stackTrace;
|
||||
|
||||
NodeStackTrace() {
|
||||
this.stackTrace = new Throwable().getStackTrace();
|
||||
}
|
||||
|
||||
private String getString(String label) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (label != null) {
|
||||
sb.append(label).append(": ");
|
||||
}
|
||||
for (StackTraceElement ste : stackTrace) {
|
||||
sb.append("at ").append(ste.toString()).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String getStrackTraceString() {
|
||||
return getString(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getString(getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
static class NodeCreationStackTrace extends NodeStackTrace {
|
||||
}
|
||||
|
||||
static class NodeInsertionStackTrace extends NodeStackTrace {
|
||||
}
|
||||
|
||||
public Node(NodeClass<? extends Node> c) {
|
||||
init(c);
|
||||
}
|
||||
@ -239,6 +275,9 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
this.nodeClass = c;
|
||||
id = INITIAL_ID;
|
||||
extraUsages = NO_NODES;
|
||||
if (TRACK_CREATION_POSITION) {
|
||||
setCreationPosition(new NodeCreationStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
final int id() {
|
||||
@ -577,32 +616,95 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* The position of the bytecode that generated this node.
|
||||
* Information associated with this node. A single value is stored directly in the field.
|
||||
* Multiple values are stored by creating an Object[].
|
||||
*/
|
||||
NodeSourcePosition sourcePosition;
|
||||
private Object annotation;
|
||||
|
||||
private <T> T getNodeInfo(Class<T> clazz) {
|
||||
assert clazz != Object[].class;
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
if (clazz.isInstance(annotation)) {
|
||||
return clazz.cast(annotation);
|
||||
}
|
||||
if (annotation.getClass() == Object[].class) {
|
||||
Object[] annotations = (Object[]) annotation;
|
||||
for (Object ann : annotations) {
|
||||
if (clazz.isInstance(ann)) {
|
||||
return clazz.cast(ann);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> void setNodeInfo(Class<T> clazz, T value) {
|
||||
assert clazz != Object[].class;
|
||||
if (annotation == null || clazz.isInstance(annotation)) {
|
||||
// Replace the current value
|
||||
this.annotation = value;
|
||||
} else if (annotation.getClass() == Object[].class) {
|
||||
Object[] annotations = (Object[]) annotation;
|
||||
for (int i = 0; i < annotations.length; i++) {
|
||||
if (clazz.isInstance(annotations[i])) {
|
||||
annotations[i] = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Object[] newAnnotations = Arrays.copyOf(annotations, annotations.length + 1);
|
||||
newAnnotations[annotations.length] = value;
|
||||
this.annotation = newAnnotations;
|
||||
} else {
|
||||
this.annotation = new Object[]{this.annotation, value};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source position information for this node or null if it doesn't exist.
|
||||
*/
|
||||
|
||||
public NodeSourcePosition getNodeSourcePosition() {
|
||||
return sourcePosition;
|
||||
return getNodeInfo(NodeSourcePosition.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source position to {@code sourcePosition}.
|
||||
* Set the source position to {@code sourcePosition}. Setting it to null is ignored so that it's
|
||||
* not accidentally cleared. Use {@link #clearNodeSourcePosition()} instead.
|
||||
*/
|
||||
public void setNodeSourcePosition(NodeSourcePosition sourcePosition) {
|
||||
assert sourcePosition != null || this.sourcePosition == null || this.sourcePosition.isPlaceholder() : "Invalid source position at node with id " + id;
|
||||
this.sourcePosition = sourcePosition;
|
||||
// assert sourcePosition == null || graph == null || graph.trackNodeSourcePosition;
|
||||
if (sourcePosition == null) {
|
||||
return;
|
||||
}
|
||||
setNodeInfo(NodeSourcePosition.class, sourcePosition);
|
||||
}
|
||||
|
||||
public void clearNodeSourcePosition() {
|
||||
setNodeInfo(NodeSourcePosition.class, null);
|
||||
}
|
||||
|
||||
public NodeCreationStackTrace getCreationPosition() {
|
||||
return getNodeInfo(NodeCreationStackTrace.class);
|
||||
}
|
||||
|
||||
public void setCreationPosition(NodeCreationStackTrace trace) {
|
||||
setNodeInfo(NodeCreationStackTrace.class, trace);
|
||||
}
|
||||
|
||||
public NodeInsertionStackTrace getInsertionPosition() {
|
||||
return getNodeInfo(NodeInsertionStackTrace.class);
|
||||
}
|
||||
|
||||
public void setInsertionPosition(NodeInsertionStackTrace trace) {
|
||||
setNodeInfo(NodeInsertionStackTrace.class, trace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the source position only if it is null.
|
||||
*/
|
||||
public void updateNodeSourcePosition(Supplier<NodeSourcePosition> sourcePositionSupp) {
|
||||
if (this.sourcePosition == null) {
|
||||
if (this.getNodeSourcePosition() == null) {
|
||||
setNodeSourcePosition(sourcePositionSupp.get());
|
||||
}
|
||||
}
|
||||
@ -919,8 +1021,8 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
}
|
||||
newNode.graph = into;
|
||||
newNode.id = INITIAL_ID;
|
||||
if (sourcePosition != null && (into == null || into.updateNodeSourcePosition())) {
|
||||
newNode.setNodeSourcePosition(sourcePosition);
|
||||
if (getNodeSourcePosition() != null && (into == null || into.updateNodeSourcePosition())) {
|
||||
newNode.setNodeSourcePosition(getNodeSourcePosition());
|
||||
}
|
||||
if (into != null) {
|
||||
into.register(newNode);
|
||||
@ -1077,6 +1179,14 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
|
||||
if (pos != null) {
|
||||
map.put("nodeSourcePosition", pos);
|
||||
}
|
||||
NodeCreationStackTrace creation = getCreationPosition();
|
||||
if (creation != null) {
|
||||
map.put("nodeCreationPosition", creation.getStrackTraceString());
|
||||
}
|
||||
NodeInsertionStackTrace insertion = getInsertionPosition();
|
||||
if (insertion != null) {
|
||||
map.put("nodeInsertionPosition", insertion.getStrackTraceString());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,8 @@ import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.common.FieldIntrospection;
|
||||
import org.graalvm.compiler.core.common.Fields;
|
||||
import org.graalvm.compiler.core.common.FieldsScanner;
|
||||
|
@ -26,8 +26,8 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
import jdk.internal.vm.compiler.collections.EconomicMap;
|
||||
import jdk.internal.vm.compiler.collections.MapCursor;
|
||||
|
||||
public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user