Skip to content

Commit f8d52b2

Browse files
committed
[GR-36821] Add user-defined info object to FrameDescriptor
PullRequest: graal/10997
2 parents 749e1e3 + d056220 commit f8d52b2

File tree

4 files changed

+170
-5
lines changed

4 files changed

+170
-5
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package org.graalvm.compiler.truffle.test;
26+
27+
import org.graalvm.compiler.nodes.ConstantNode;
28+
import org.graalvm.compiler.nodes.ReturnNode;
29+
import org.graalvm.compiler.nodes.StructuredGraph;
30+
import org.graalvm.compiler.truffle.runtime.OptimizedCallTarget;
31+
import org.junit.Assert;
32+
import org.junit.Test;
33+
34+
import com.oracle.truffle.api.CompilerAsserts;
35+
import com.oracle.truffle.api.Truffle;
36+
import com.oracle.truffle.api.frame.Frame;
37+
import com.oracle.truffle.api.frame.FrameDescriptor;
38+
import com.oracle.truffle.api.frame.MaterializedFrame;
39+
import com.oracle.truffle.api.frame.VirtualFrame;
40+
import com.oracle.truffle.api.nodes.RootNode;
41+
42+
public class FrameDescriptorTest extends PartialEvaluationTest {
43+
44+
@Test
45+
public void constantInfo() {
46+
FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
47+
Object obj = new Object();
48+
FrameDescriptor fd = builder.info("foo").info(obj).build();
49+
RootNode root1 = new RootNode(null, fd) {
50+
@Override
51+
public String toString() {
52+
return "constantInfo1";
53+
}
54+
55+
@Override
56+
public Object execute(VirtualFrame frame) {
57+
CompilerAsserts.partialEvaluationConstant(frame.getFrameDescriptor().getInfo());
58+
return frame.getFrameDescriptor().getInfo();
59+
}
60+
};
61+
RootNode root2 = new RootNode(null, fd) {
62+
63+
private final FrameDescriptor descriptor = fd;
64+
65+
@Override
66+
public String toString() {
67+
return "constantInfo2";
68+
}
69+
70+
@Override
71+
public Object execute(VirtualFrame frame) {
72+
CompilerAsserts.partialEvaluationConstant(descriptor.getInfo());
73+
return descriptor.getInfo();
74+
}
75+
};
76+
MaterializedFrame materializedFrame = Truffle.getRuntime().createMaterializedFrame(new Object[]{}, fd);
77+
RootNode root3 = new RootNode(null) {
78+
79+
private final Frame fr = materializedFrame;
80+
81+
@Override
82+
public String toString() {
83+
return "constantInfo3";
84+
}
85+
86+
@Override
87+
public Object execute(VirtualFrame frame) {
88+
CompilerAsserts.partialEvaluationConstant(fr.getFrameDescriptor().getInfo());
89+
return fr.getFrameDescriptor().getInfo();
90+
}
91+
};
92+
testConstantReturn(root1, obj);
93+
testConstantReturn(root2, obj);
94+
testConstantReturn(root3, obj);
95+
}
96+
97+
private void testConstantReturn(RootNode rootNode, Object result) {
98+
OptimizedCallTarget callTarget = (OptimizedCallTarget) rootNode.getCallTarget();
99+
Assert.assertTrue(callTarget.call() == result);
100+
101+
StructuredGraph graph = partialEval(callTarget, new Object[]{});
102+
assertTrue(graph.getNodes().filter(ReturnNode.class).first().result() instanceof ConstantNode);
103+
compile(callTarget, graph);
104+
Assert.assertTrue("CallTarget is valid", callTarget.isValid());
105+
Assert.assertTrue(callTarget.call() == result);
106+
}
107+
108+
@SuppressWarnings("deprecation")
109+
private static void assertEmptyFrameDescriptor(FrameDescriptor fd, Object info) {
110+
Assert.assertEquals(0, fd.getNumberOfSlots());
111+
Assert.assertEquals(0, fd.getNumberOfAuxiliarySlots());
112+
Assert.assertEquals(0, fd.getSize());
113+
Assert.assertEquals(null, fd.getDefaultValue());
114+
Assert.assertTrue(info == fd.getInfo());
115+
}
116+
117+
@Test
118+
public void testEmpty() {
119+
FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
120+
FrameDescriptor fd = builder.build();
121+
assertEmptyFrameDescriptor(fd, null);
122+
assertEmptyFrameDescriptor(new FrameDescriptor(), null);
123+
assertEmptyFrameDescriptor(new FrameDescriptor(null), null);
124+
}
125+
126+
@Test
127+
public void testInfo() {
128+
FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
129+
Object obj = new Object();
130+
FrameDescriptor fd = builder.info("foo").info(obj).build();
131+
assertEmptyFrameDescriptor(fd, obj);
132+
}
133+
}

truffle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This changelog summarizes major changes between Truffle versions relevant to lan
1616
* GR-10128 Added the `website` property to the [TruffleLanguage.Registration](https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/TruffleLanguage.Registration.html#website--) and [TruffleInstrument.Registration](https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/instrumentation/TruffleInstrument.Registration.html#website--) allowing language and instrument developers to specify a URL for a web site with further information about their language/tool.
1717
* GR-10128 Added the `usageSyntax` property to the [Option](https://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/Option.html#usageSyntax--) allowing developers to specify the syntax their option expects. See the javadoc for more information.
1818
* Added `TruffleSafepoint.setAllowActions` to disable thread local actions temporarily for trusted internal guest code. Currently only allowed during the finalization of a context in `TruffleLanguage.finalizeContext(Object)`.
19+
* Added `FrameDescriptor.getInfo()` and `FrameDescriptor.Builder.info()` to associate a user-defined object with a frame descriptor.
1920

2021
## Version 22.0.0
2122
* Truffle DSL generated code now inherits all annotations on constructor parameters to the static create factory method.

truffle/src/com.oracle.truffle.api/snapshot.sigtest

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ meth public int getNumberOfSlots()
819819
meth public int getSize()
820820
anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="")
821821
meth public java.lang.Object getDefaultValue()
822+
meth public java.lang.Object getInfo()
822823
meth public java.lang.Object getSlotInfo(int)
823824
meth public java.lang.Object getSlotName(int)
824825
meth public java.lang.String toString()
@@ -836,16 +837,17 @@ meth public void setFrameSlotKind(com.oracle.truffle.api.frame.FrameSlot,com.ora
836837
anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="")
837838
meth public void setSlotKind(int,com.oracle.truffle.api.frame.FrameSlotKind)
838839
supr java.lang.Object
839-
hfds EMPTY_BYTE_ARRAY,NEVER_PART_OF_COMPILATION_MESSAGE,activeAuxiliarySlotCount,auxiliarySlotCount,auxiliarySlotMap,defaultValue,disabledAuxiliarySlots,identifierToNotInFrameAssumptionMap,identifierToSlotMap,indexedSlotInfos,indexedSlotNames,indexedSlotTags,materializeCalled,size,slots,version
840+
hfds EMPTY_BYTE_ARRAY,NEVER_PART_OF_COMPILATION_MESSAGE,activeAuxiliarySlotCount,auxiliarySlotCount,auxiliarySlotMap,defaultValue,descriptorInfo,disabledAuxiliarySlots,identifierToNotInFrameAssumptionMap,identifierToSlotMap,indexedSlotInfos,indexedSlotNames,indexedSlotTags,materializeCalled,size,slots,version
840841

841842
CLSS public final static com.oracle.truffle.api.frame.FrameDescriptor$Builder
842843
outer com.oracle.truffle.api.frame.FrameDescriptor
843844
meth public com.oracle.truffle.api.frame.FrameDescriptor build()
844845
meth public com.oracle.truffle.api.frame.FrameDescriptor$Builder defaultValue(java.lang.Object)
845846
meth public int addSlot(com.oracle.truffle.api.frame.FrameSlotKind,java.lang.Object,java.lang.Object)
846847
meth public int addSlots(int,com.oracle.truffle.api.frame.FrameSlotKind)
848+
meth public com.oracle.truffle.api.frame.FrameDescriptor$Builder info(java.lang.Object)
847849
supr java.lang.Object
848-
hfds DEFAULT_CAPACITY,defaultValue,infos,names,size,tags
850+
hfds DEFAULT_CAPACITY,defaultValue,descriptorInfo,infos,names,size,tags
849851

850852
CLSS public abstract interface com.oracle.truffle.api.frame.FrameInstance
851853
innr public final static !enum FrameAccess

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public final class FrameDescriptor implements Cloneable {
8888
private volatile EconomicMap<Object, Integer> auxiliarySlotMap;
8989
private volatile BitSet disabledAuxiliarySlots;
9090

91+
private final Object descriptorInfo;
92+
9193
/**
9294
* Number of entries (starting at index 0) that need to be allocated to encompass all active
9395
* auxiliary slots.
@@ -132,16 +134,18 @@ public FrameDescriptor(Object defaultValue) {
132134
this.indexedSlotTags = EMPTY_BYTE_ARRAY;
133135
this.indexedSlotNames = null;
134136
this.indexedSlotInfos = null;
137+
this.descriptorInfo = null;
135138

136139
this.defaultValue = defaultValue;
137140
newVersion(this);
138141
}
139142

140-
private FrameDescriptor(Object defaultValue, byte[] indexedSlotTags, Object[] indexedSlotNames, Object[] indexedSlotInfos) {
143+
private FrameDescriptor(Object defaultValue, byte[] indexedSlotTags, Object[] indexedSlotNames, Object[] indexedSlotInfos, Object info) {
141144
CompilerAsserts.neverPartOfCompilation("do not create a FrameDescriptor from compiled code");
142145
this.indexedSlotTags = indexedSlotTags;
143146
this.indexedSlotNames = indexedSlotNames;
144147
this.indexedSlotInfos = indexedSlotInfos;
148+
this.descriptorInfo = info;
145149

146150
this.defaultValue = defaultValue;
147151
newVersion(this);
@@ -528,7 +532,7 @@ public FrameDescriptor copy() {
528532
CompilerAsserts.neverPartOfCompilation(NEVER_PART_OF_COMPILATION_MESSAGE);
529533
synchronized (this) {
530534
FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue, indexedSlotTags == null ? null : indexedSlotTags.clone(),
531-
indexedSlotNames == null ? null : indexedSlotNames.clone(), indexedSlotInfos == null ? null : indexedSlotInfos.clone());
535+
indexedSlotNames == null ? null : indexedSlotNames.clone(), indexedSlotInfos == null ? null : indexedSlotInfos.clone(), descriptorInfo);
532536
for (int i = 0; i < slots.size(); i++) {
533537
FrameSlot slot = slots.get(i);
534538
clonedFrameDescriptor.addFrameSlot(slot.getIdentifier(), slot.getInfo(), FrameSlotKind.Illegal);
@@ -836,6 +840,15 @@ public int getNumberOfAuxiliarySlots() {
836840
return activeAuxiliarySlotCount;
837841
}
838842

843+
/**
844+
* @return the user-defined info object associated with this frame descriptor
845+
*
846+
* @since 22.1
847+
*/
848+
public Object getInfo() {
849+
return descriptorInfo;
850+
}
851+
839852
/**
840853
* Builds a new frame descriptor with index-based frame slots.
841854
*
@@ -870,6 +883,7 @@ public static final class Builder {
870883
private Object[] names;
871884
private Object[] infos;
872885
private int size;
886+
private Object descriptorInfo;
873887

874888
private Builder(int capacity) {
875889
this.tags = new byte[capacity];
@@ -951,14 +965,29 @@ public int addSlot(FrameSlotKind kind, Object name, Object info) {
951965
return newIndex;
952966
}
953967

968+
/**
969+
* Adds a user-defined info object to the frame descriptor. The contents of this object are
970+
* strongly referenced from the frame descriptor and can be queried using
971+
* {@link FrameDescriptor#getInfo()}. They do not influence the semantics of the frame
972+
* descriptor in any other way.
973+
*
974+
* @param info the user-defined info object
975+
*
976+
* @since 22.1
977+
*/
978+
public Builder info(Object info) {
979+
this.descriptorInfo = info;
980+
return this;
981+
}
982+
954983
/**
955984
* Uses the data provided to this builder to create a new {@link FrameDescriptor}.
956985
*
957986
* @return the newly created {@link FrameDescriptor}
958987
* @since 22.0
959988
*/
960989
public FrameDescriptor build() {
961-
return new FrameDescriptor(defaultValue, Arrays.copyOf(tags, size), names == null ? null : Arrays.copyOf(names, size), infos == null ? null : Arrays.copyOf(infos, size));
990+
return new FrameDescriptor(defaultValue, Arrays.copyOf(tags, size), names == null ? null : Arrays.copyOf(names, size), infos == null ? null : Arrays.copyOf(infos, size), descriptorInfo);
962991
}
963992
}
964993
}

0 commit comments

Comments
 (0)