Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2025, 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
Expand Down Expand Up @@ -29,15 +29,16 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import jdk.graal.compiler.api.test.Graal;
import jdk.graal.compiler.runtime.RuntimeProvider;
import org.junit.Test;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleRuntime;
import com.oracle.truffle.api.impl.DefaultTruffleRuntime;
import com.oracle.truffle.api.impl.TVMCI;

import jdk.graal.compiler.api.test.Graal;
import jdk.graal.compiler.runtime.RuntimeProvider;

public class TruffleRuntimeTest {

@Test
Expand Down Expand Up @@ -75,12 +76,4 @@ public void testGetCapabilityObjectClass() {
assertNull("Expected null return value for Object.class", object);
}

@SuppressWarnings("deprecation")
@Test
public void testGetLayoutFactory() {
TruffleRuntime runtime = Truffle.getRuntime();
com.oracle.truffle.api.object.LayoutFactory layoutFactory = runtime.getCapability(com.oracle.truffle.api.object.LayoutFactory.class);
assertNotNull("LayoutFactory not found", layoutFactory);
// Rely on modules to only load trusted service providers
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2025, 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
Expand Down Expand Up @@ -125,7 +125,7 @@ public class KnownTruffleTypes extends AbstractKnownTruffleTypes {
// truffle.api.object
public final ResolvedJavaType Shape = lookupType("com.oracle.truffle.api.object.Shape");
public final ResolvedJavaType DynamicObject = lookupType("com.oracle.truffle.api.object.DynamicObject");
public final ResolvedJavaType UnsafeAccess = lookupType("com.oracle.truffle.object.UnsafeAccess");
public final ResolvedJavaType UnsafeAccess = lookupType("com.oracle.truffle.api.object.UnsafeAccess");

// truffle.api.string
public final ResolvedJavaType TruffleString = lookupType("com.oracle.truffle.api.strings.TruffleString");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
import jdk.graal.compiler.options.OptionType;
import jdk.graal.compiler.phases.util.Providers;
import jdk.graal.compiler.replacements.StandardGraphBuilderPlugins;
import jdk.graal.compiler.replacements.arraycopy.ArrayCopySnippets;
import jdk.graal.compiler.replacements.nodes.arithmetic.UnsignedMulHighNode;
import jdk.graal.compiler.serviceprovider.SpeculationReasonGroup;
import jdk.graal.compiler.truffle.KnownTruffleTypes;
Expand Down Expand Up @@ -133,6 +134,7 @@
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.SpeculationLog;
Expand Down Expand Up @@ -167,7 +169,7 @@ public static void registerInvocationPlugins(InvocationPlugins plugins, KnownTru
registerFrameWithoutBoxingPlugins(plugins, types, canDelayIntrinsification);
registerTruffleSafepointPlugins(plugins, types, canDelayIntrinsification);
registerNodePlugins(plugins, types, metaAccess, canDelayIntrinsification, providers.getConstantReflection());
registerDynamicObjectPlugins(plugins, types, canDelayIntrinsification);
registerDynamicObjectPlugins(plugins, types, canDelayIntrinsification, providers.getConstantReflection());
registerBufferPlugins(plugins, types, canDelayIntrinsification);
registerMemorySegmentPlugins(plugins, types, canDelayIntrinsification);
}
Expand Down Expand Up @@ -1111,9 +1113,83 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
}
}

private static void registerDynamicObjectPlugins(InvocationPlugins plugins, KnownTruffleTypes types, boolean canDelayIntrinsification) {
private static void registerDynamicObjectPlugins(InvocationPlugins plugins, KnownTruffleTypes types,
boolean canDelayIntrinsification, ConstantReflectionProvider constantReflection) {
if (!types.UnsafeAccess.isInitialized()) {
types.UnsafeAccess.initialize();
}

ResolvedJavaField[] staticFields = types.UnsafeAccess.getStaticFields();
JavaConstant anyConstant = null;
for (ResolvedJavaField field : staticFields) {
if (field.getName().equals("ANY_LOCATION")) {
anyConstant = constantReflection.readFieldValue(field, null);
break;
}
}

JavaKind[] usedJavaKinds = {JavaKind.Boolean, JavaKind.Byte, JavaKind.Int, JavaKind.Short, JavaKind.Long, JavaKind.Float, JavaKind.Double, JavaKind.Object};

Registration r = new Registration(plugins, new ResolvedJavaSymbol(types.UnsafeAccess));
registerUnsafeLoadStorePlugins(r, canDelayIntrinsification, null, JavaKind.Long);
registerUnsafeLoadStorePlugins(r, canDelayIntrinsification, anyConstant, usedJavaKinds);
registerUnsafeCast(r, types, canDelayIntrinsification);
registerBooleanCast(r);
registerArrayCopy(r);

registerDynamicObjectShapePlugins(plugins, types, canDelayIntrinsification);
}

private static void registerDynamicObjectShapePlugins(InvocationPlugins plugins, KnownTruffleTypes types, boolean canDelayIntrinsification) {
ResolvedJavaType dynamicObjectType = types.DynamicObject;
ResolvedJavaType shapeType = types.Shape;
ResolvedJavaSymbol dynamicObjectSymbol = new ResolvedJavaSymbol(dynamicObjectType);
ResolvedJavaSymbol shapeSymbol = new ResolvedJavaSymbol(shapeType);
Registration r = new Registration(plugins, dynamicObjectSymbol);
r.register(new RequiredInvocationPlugin("getShapeHelper", shapeSymbol) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode shape) {
Stamp piStamp = StampFactory.object(TypeReference.createTrusted(b.getAssumptions(), shapeType), true);
ValueNode piNode = PiNode.create(shape, piStamp);
b.addPush(JavaKind.Object, piNode);
return true;
}
});
r.register(new RequiredInvocationPlugin("setShapeHelper", Receiver.class, shapeSymbol, long.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode shape, ValueNode shapeOffset) {
if (canDelayIntrinsification) {
return false;
}
if (!shapeOffset.isConstant()) {
return false;
}
LocationIdentity locationIdentity = LocationIdentity.any();
boolean forceAnyLocation = true;
b.add(new RawStoreNode(receiver.get(true), shapeOffset, shape, JavaKind.Object, locationIdentity, true, null, forceAnyLocation));
return true;
}
});
}

private static void registerBooleanCast(Registration r) {
r.register(new RequiredInvocationPlugin("booleanCast", int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
b.addPush(JavaKind.Boolean, value);
return true;
}
});
r.register(new RequiredInvocationPlugin("intCast", boolean.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
b.addPush(JavaKind.Int, value);
return true;
}
});
}

private static void registerArrayCopy(Registration r) {
ArrayCopySnippets.registerSystemArraycopyPlugin(r, true);
}

public static void registerUnsafeCast(Registration r, KnownTruffleTypes types, boolean canDelayIntrinsification) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,6 @@ public void cleanup() {
invokeStaticMethod("com.oracle.truffle.api.library.LibraryFactory", "resetNativeImageState",
Collections.singletonList(ClassLoader.class), imageClassLoader);
invokeStaticMethod("com.oracle.truffle.api.source.Source", "resetNativeImageState", Collections.emptyList());
// clean up cached object layouts
invokeStaticMethod("com.oracle.truffle.object.LayoutImpl", "resetNativeImageState", Collections.emptyList());
}

@Override
Expand Down Expand Up @@ -583,8 +581,8 @@ public void duringSetup(DuringSetupAccess a) {
metaAccess = access.getMetaAccess();

uncachedDispatchField = access.findField(LibraryFactory.class, "uncachedDispatch");
layoutInfoMapField = access.findField("com.oracle.truffle.object.DefaultLayout$LayoutInfo", "LAYOUT_INFO_MAP");
layoutMapField = access.findField("com.oracle.truffle.object.DefaultLayout", "LAYOUT_MAP");
layoutInfoMapField = access.findField("com.oracle.truffle.api.object.LayoutImpl", "LAYOUT_INFO_MAP");
layoutMapField = access.findField("com.oracle.truffle.api.object.LayoutImpl", "LAYOUT_MAP");
libraryFactoryCacheField = access.findField("com.oracle.truffle.api.library.LibraryFactory$ResolvedDispatch", "CACHE");
if (Options.TruffleCheckPreinitializedFiles.getValue()) {
var classInitializationSupport = access.getHostVM().getClassInitializationSupport();
Expand Down Expand Up @@ -970,7 +968,7 @@ private static void initializeDynamicObjectLayoutImpl(Class<?> javaClass) {
} catch (IllegalAccessException e) {
throw VMError.shouldNotReachHere(e);
}
invokeStaticMethod("com.oracle.truffle.object.LayoutImpl", "initializeDynamicObjectLayout", List.of(Class.class, MethodHandles.Lookup.class), javaClass, privateLookup);
invokeStaticMethod("com.oracle.truffle.api.object.LayoutImpl", "initializeDynamicObjectLayout", List.of(Class.class, MethodHandles.Lookup.class), javaClass, privateLookup);
}

private static void registerDynamicObjectFields(BeforeAnalysisAccessImpl config) {
Expand Down Expand Up @@ -1578,14 +1576,8 @@ static void logFallback(String message) {
}
}

@TargetClass(className = "com.oracle.truffle.object.CoreLocations$DynamicObjectFieldLocation", onlyWith = TruffleBaseFeature.IsEnabled.class)
final class Target_com_oracle_truffle_object_CoreLocations_DynamicObjectFieldLocation {
@Alias @RecomputeFieldValue(kind = Kind.AtomicFieldUpdaterOffset) //
private long offset;
}

@TargetClass(className = "com.oracle.truffle.object.CoreLocations$DynamicLongFieldLocation", onlyWith = TruffleBaseFeature.IsEnabled.class)
final class Target_com_oracle_truffle_object_CoreLocations_DynamicLongFieldLocation {
@TargetClass(className = "com.oracle.truffle.api.object.FieldInfo", onlyWith = TruffleBaseFeature.IsEnabled.class)
final class Target_com_oracle_truffle_api_object_FieldInfo {
@Alias @RecomputeFieldValue(kind = Kind.AtomicFieldUpdaterOffset) //
private long offset;
}
Expand Down
5 changes: 5 additions & 0 deletions truffle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ This changelog summarizes major changes between Truffle versions relevant to lan
* GR-64533 By default every specialization is now included for {@link GenerateUncached}, except specializations that require a {@link Specialization#limit() limit} and are replaced, those are excluded by default. By setting `@Specialization(excludeForUncached=..)` explicitly the default behavior can be overridden, e.g. to include or exclude a specialization for uncached. Specializations which are no longer compatible with uncached will produce a warning instead of an error for compatibility reasons until all languages are migrated. It is therefore expected that language implementations may see new warnings with this version.
* GR-64124 Added `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode, int)` that supports batch polling for bytecode OSR. Using this method avoids checking for bytecode OSR on every loop backedge.
* GR-64124 Deprecated `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode)`. Use `BytecodeOSRNode.pollOSRBackEdge(BytecodeOSRNode, int)` instead. Please note that the old method did call `TruffleSafepoint.poll(Node)`, but the the new method does not. Please double check that your bytecode interpreter polls Truffle safepoints at loop back-edges.
* GR-64086 Added extended Dynamic Object Model Layout that adds:
* A shape obsolescence strategy enabling optimistic type speculation for primitive property values with gradual migration to more general shapes on speculation failure (moving primitive slots to reference slots), eventually converging on a general enough shape tree. Reduces shape polymorphism by obsoleting and merging too specific shapes in favor of more general shapes.
* Automatic reference type tracking based on assumptions, eliminating redundant type checks.
* Automatic single-assignment tracking based on assumptions allowing languages to assume that a property is effectively final (i.e. stays unchanged after the initial assignment) as well as constant-fold values of a constant receiver with a known shape.
* You can still disable the new layout and switch back to the previous implementation using the system property: `-Dtruffle.object.LayoutFactory=com.oracle.truffle.api.object.CoreLayoutFactory`.

## Version 24.2.0
* GR-60636 Truffle now stops compiling when the code cache fills up on HotSpot. A warning is printed when that happens.
Expand Down
19 changes: 9 additions & 10 deletions truffle/mx.truffle/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@
"sourceDirs" : ["src"],
"dependencies" : [
"com.oracle.truffle.api.interop",
"com.oracle.truffle.object",
],
"requires" : [
"jdk.unsupported", # sun.misc.Unsafe
Expand Down Expand Up @@ -789,22 +790,19 @@
"com.oracle.truffle.object" : {
"subDir" : "src",
"sourceDirs" : ["src"],
"dependencies" : ["com.oracle.truffle.api.object"],
"requires" : [
"jdk.unsupported", # sun.misc.Unsafe
],
"dependencies" : ["com.oracle.truffle.api"],
"checkstyle" : "com.oracle.truffle.api",
"javaCompliance" : "17+",
"annotationProcessors" : ["TRUFFLE_DSL_PROCESSOR"],
"annotationProcessors" : [],
"workingSets" : "Truffle",
"graalCompilerSourceEdition": "ignore",
},

"com.oracle.truffle.object.basic.test" : {
"com.oracle.truffle.api.object.test" : {
"subDir" : "src",
"sourceDirs" : ["src"],
"dependencies" : [
"com.oracle.truffle.object",
"com.oracle.truffle.api.object",
"com.oracle.truffle.api.test",
"mx:JUNIT"
],
Expand Down Expand Up @@ -1635,7 +1633,6 @@
],
"uses" : [
"com.oracle.truffle.api.impl.TruffleLocator",
"com.oracle.truffle.api.object.LayoutFactory",
"com.oracle.truffle.runtime.LoopNodeFactory",
"com.oracle.truffle.runtime.TruffleTypes",
"com.oracle.truffle.runtime.EngineCacheSupport",
Expand Down Expand Up @@ -1724,6 +1721,8 @@
# Qualified exports
"com.oracle.truffle.api.impl to org.graalvm.locator, org.graalvm.truffle.runtime, com.oracle.truffle.enterprise, org.graalvm.truffle.runtime.svm, com.oracle.truffle.enterprise.svm, com.oracle.truffle.truffle_nfi_panama",
"com.oracle.truffle.object to com.oracle.truffle.enterprise, org.graalvm.truffle.runtime, com.oracle.truffle.enterprise, org.graalvm.truffle.runtime.svm, com.oracle.truffle.enterprise.svm",
"com.oracle.truffle.object.enterprise to com.oracle.truffle.enterprise",
# GR-64984: Exports to com.oracle.truffle.enterprise are only needed for jdk21.
],
"opens" : [
"com.oracle.truffle.polyglot to org.graalvm.truffle.runtime",
Expand Down Expand Up @@ -1765,7 +1764,7 @@
"com.oracle.truffle.api.profiles",
"com.oracle.truffle.api.debug",
"com.oracle.truffle.api.utilities",
"com.oracle.truffle.object",
"com.oracle.truffle.api.object",
"com.oracle.truffle.api.strings",
"com.oracle.truffle.polyglot",
"com.oracle.truffle.host",
Expand Down Expand Up @@ -2201,7 +2200,7 @@
"com.oracle.truffle.api.debug.test",
"com.oracle.truffle.api.strings.test",
"com.oracle.truffle.api.bytecode.test",
"com.oracle.truffle.object.basic.test",
"com.oracle.truffle.api.object.test",
"com.oracle.truffle.api.staticobject.test",
],
"exclude" : [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -89,7 +89,7 @@
* receiver types of third parties or the JDK. For example the Truffle interop library has default
* exports for most {@link Number} types, {@link String} and {@link Boolean} type.
* <p>
* In order to enable AOT generation for a a library annotate the class with {@link GenerateAOT} and
* In order to enable AOT generation for a library annotate the class with {@link GenerateAOT} and
* enable exports to be used for AOT by setting {@link ExportLibrary#useForAOT()} to
* <code>true</code>.
*
Expand Down Expand Up @@ -326,7 +326,7 @@
boolean defaultExportLookupEnabled() default false;

/**
* Allows the use of {@link DynamicDispatchLibrary} with this library. By default dynamic
* Allows the use of {@link DynamicDispatchLibrary} with this library. By default, dynamic
* dispatch is enabled. If this flag is set to <code>false</code> then the
* {@link DynamicDispatchLibrary#dispatch(Object) dispatch} method will not be used for this
* library. Only default exports and exports declared with the receiver type will be used
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down
Loading
Loading