1 /*
2  * Copyright (c) 2009, 2019, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.nodes;
26 
27 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
28 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
29 
30 import java.util.Map;
31 
32 import org.graalvm.compiler.core.common.LIRKind;
33 import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
34 import org.graalvm.compiler.core.common.type.FloatStamp;
35 import org.graalvm.compiler.core.common.type.IntegerStamp;
36 import org.graalvm.compiler.core.common.type.Stamp;
37 import org.graalvm.compiler.core.common.type.StampFactory;
38 import org.graalvm.compiler.debug.GraalError;
39 import org.graalvm.compiler.graph.Node;
40 import org.graalvm.compiler.graph.NodeClass;
41 import org.graalvm.compiler.graph.NodeMap;
42 import org.graalvm.compiler.graph.iterators.NodeIterable;
43 import org.graalvm.compiler.lir.ConstantValue;
44 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
45 import org.graalvm.compiler.nodeinfo.NodeInfo;
46 import org.graalvm.compiler.nodeinfo.Verbosity;
47 import org.graalvm.compiler.nodes.calc.FloatingNode;
48 import org.graalvm.compiler.nodes.cfg.Block;
49 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
50 import org.graalvm.compiler.nodes.spi.LIRLowerable;
51 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
52 
53 import jdk.vm.ci.code.CodeUtil;
54 import jdk.vm.ci.meta.Constant;
55 import jdk.vm.ci.meta.ConstantReflectionProvider;
56 import jdk.vm.ci.meta.JavaConstant;
57 import jdk.vm.ci.meta.JavaKind;
58 import jdk.vm.ci.meta.MetaAccessProvider;
59 import jdk.vm.ci.meta.PrimitiveConstant;
60 import jdk.vm.ci.meta.ResolvedJavaType;
61 
62 /**
63  * The {@code ConstantNode} represents a {@link Constant constant}.
64  */
65 @NodeInfo(nameTemplate = "C({p#rawvalue}) {p#stampKind}", cycles = CYCLES_0, size = SIZE_1)
66 public final class ConstantNode extends FloatingNode implements LIRLowerable, ArrayLengthProvider {
67 
68     public static final NodeClass<ConstantNode> TYPE = NodeClass.create(ConstantNode.class);
69 
70     protected final Constant value;
71 
72     private final int stableDimension;
73     private final boolean isDefaultStable;
74 
createPrimitive(JavaConstant value)75     private static ConstantNode createPrimitive(JavaConstant value) {
76         assert value.getJavaKind() != JavaKind.Object;
77         return new ConstantNode(value, StampFactory.forConstant(value));
78     }
79 
80     /**
81      * Constructs a new node representing the specified constant.
82      *
83      * @param value the constant
84      */
ConstantNode(Constant value, Stamp stamp)85     public ConstantNode(Constant value, Stamp stamp) {
86         this(value, stamp, 0, false);
87     }
88 
ConstantNode(Constant value, Stamp stamp, int stableDimension, boolean isDefaultStable)89     private ConstantNode(Constant value, Stamp stamp, int stableDimension, boolean isDefaultStable) {
90         super(TYPE, stamp);
91         assert stamp != null && stamp.isCompatible(value) : stamp + " " + value;
92         this.value = value;
93         this.stableDimension = stableDimension;
94         if (stableDimension == 0) {
95             /*
96              * Ensure that isDefaultStable has a canonical value to avoid having two constant nodes
97              * that only differ in this field. The value of isDefaultStable is only used when we
98              * have a stable array dimension.
99              */
100             this.isDefaultStable = false;
101         } else {
102             this.isDefaultStable = isDefaultStable;
103         }
104     }
105 
ConstantNode(@njectedNodeParameter Stamp stamp, @InjectedNodeParameter ConstantReflectionProvider constantReflection, @ConstantNodeParameter ResolvedJavaType type)106     public ConstantNode(@InjectedNodeParameter Stamp stamp, @InjectedNodeParameter ConstantReflectionProvider constantReflection, @ConstantNodeParameter ResolvedJavaType type) {
107         this(constantReflection.asJavaClass(type), stamp);
108     }
109 
110     /**
111      * @return the constant value represented by this node
112      */
getValue()113     public Constant getValue() {
114         return value;
115     }
116 
117     /**
118      * @return the number of stable dimensions if this is a stable array, otherwise 0
119      */
getStableDimension()120     public int getStableDimension() {
121         return stableDimension;
122     }
123 
124     /**
125      * @return true if this is a stable array and the default elements are considered stable
126      */
isDefaultStable()127     public boolean isDefaultStable() {
128         return isDefaultStable;
129     }
130 
131     /**
132      * Gathers all the {@link ConstantNode}s that are inputs to the
133      * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph.
134      */
getConstantNodes(StructuredGraph graph)135     public static NodeIterable<ConstantNode> getConstantNodes(StructuredGraph graph) {
136         return graph.getNodes().filter(ConstantNode.class);
137     }
138 
139     /**
140      * Replaces this node at its usages with another node.
141      */
replace(StructuredGraph graph, Node replacement)142     public void replace(StructuredGraph graph, Node replacement) {
143         assert graph == graph();
144         replaceAtUsagesAndDelete(replacement);
145     }
146 
147     @Override
generate(NodeLIRBuilderTool gen)148     public void generate(NodeLIRBuilderTool gen) {
149         LIRGeneratorTool lirTool = gen.getLIRGeneratorTool();
150         LIRKind kind = lirTool.getLIRKind(stamp(NodeView.DEFAULT));
151         if (onlyUsedInVirtualState()) {
152             gen.setResult(this, new ConstantValue(kind, value));
153         } else if (lirTool.canInlineConstant(value) || (lirTool.mayEmbedConstantLoad(value) && hasExactlyOneUsage() && onlyUsedInCurrentBlock())) {
154             gen.setResult(this, new ConstantValue(lirTool.toRegisterKind(kind), value));
155         } else {
156             gen.setResult(this, gen.getLIRGeneratorTool().emitConstant(kind, value));
157         }
158     }
159 
160     /**
161      * Expecting false for loop invariant.
162      */
onlyUsedInCurrentBlock()163     private boolean onlyUsedInCurrentBlock() {
164         assert graph().getLastSchedule() != null;
165         NodeMap<Block> nodeBlockMap = graph().getLastSchedule().getNodeToBlockMap();
166         Block currentBlock = nodeBlockMap.get(this);
167         for (Node usage : usages()) {
168             if (currentBlock != nodeBlockMap.get(usage)) {
169                 return false;
170             }
171         }
172         return true;
173     }
174 
onlyUsedInVirtualState()175     private boolean onlyUsedInVirtualState() {
176         for (Node n : this.usages()) {
177             if (n instanceof VirtualState) {
178                 // Only virtual usage.
179             } else {
180                 return false;
181             }
182         }
183         return true;
184     }
185 
forConstant(JavaConstant constant, MetaAccessProvider metaAccess, StructuredGraph graph)186     public static ConstantNode forConstant(JavaConstant constant, MetaAccessProvider metaAccess, StructuredGraph graph) {
187         if (constant.getJavaKind().getStackKind() == JavaKind.Int && constant.getJavaKind() != JavaKind.Int) {
188             return forInt(constant.asInt(), graph);
189         }
190         if (constant.getJavaKind() == JavaKind.Object) {
191             return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess)));
192         } else {
193             return unique(graph, createPrimitive(constant));
194         }
195     }
196 
forConstant(JavaConstant constant, int stableDimension, boolean isDefaultStable, MetaAccessProvider metaAccess)197     public static ConstantNode forConstant(JavaConstant constant, int stableDimension, boolean isDefaultStable, MetaAccessProvider metaAccess) {
198         if (constant.getJavaKind().getStackKind() == JavaKind.Int && constant.getJavaKind() != JavaKind.Int) {
199             return forInt(constant.asInt());
200         }
201         if (constant.getJavaKind() == JavaKind.Object) {
202             return new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess), stableDimension, isDefaultStable);
203         } else {
204             assert stableDimension == 0;
205             return createPrimitive(constant);
206         }
207     }
208 
forConstant(JavaConstant array, MetaAccessProvider metaAccess)209     public static ConstantNode forConstant(JavaConstant array, MetaAccessProvider metaAccess) {
210         return forConstant(array, 0, false, metaAccess);
211     }
212 
forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph)213     public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) {
214         return graph.unique(new ConstantNode(constant, stamp.constant(constant, metaAccess)));
215     }
216 
forConstant(Stamp stamp, Constant constant, int stableDimension, boolean isDefaultStable, MetaAccessProvider metaAccess)217     public static ConstantNode forConstant(Stamp stamp, Constant constant, int stableDimension, boolean isDefaultStable, MetaAccessProvider metaAccess) {
218         return new ConstantNode(constant, stamp.constant(constant, metaAccess), stableDimension, isDefaultStable);
219     }
220 
forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess)221     public static ConstantNode forConstant(Stamp stamp, Constant constant, MetaAccessProvider metaAccess) {
222         return new ConstantNode(constant, stamp.constant(constant, metaAccess));
223     }
224 
225     /**
226      * Returns a node for a Java primitive.
227      */
forPrimitive(JavaConstant constant, StructuredGraph graph)228     public static ConstantNode forPrimitive(JavaConstant constant, StructuredGraph graph) {
229         assert constant.getJavaKind() != JavaKind.Object;
230         return forConstant(constant, null, graph);
231     }
232 
233     /**
234      * Returns a node for a Java primitive.
235      */
forPrimitive(JavaConstant constant)236     public static ConstantNode forPrimitive(JavaConstant constant) {
237         assert constant.getJavaKind() != JavaKind.Object;
238         return forConstant(constant, null);
239     }
240 
241     /**
242      * Returns a node for a primitive of a given type.
243      */
forPrimitive(Stamp stamp, JavaConstant constant, StructuredGraph graph)244     public static ConstantNode forPrimitive(Stamp stamp, JavaConstant constant, StructuredGraph graph) {
245         if (stamp instanceof IntegerStamp) {
246             assert constant.getJavaKind().isNumericInteger() && stamp.getStackKind() == constant.getJavaKind().getStackKind();
247             IntegerStamp istamp = (IntegerStamp) stamp;
248             return forIntegerBits(istamp.getBits(), constant, graph);
249         } else {
250             assert constant.getJavaKind().isNumericFloat() && stamp.getStackKind() == constant.getJavaKind();
251             return forPrimitive(constant, graph);
252         }
253     }
254 
255     /**
256      * Returns a node for a primitive of a given type.
257      */
forPrimitive(Stamp stamp, Constant constant)258     public static ConstantNode forPrimitive(Stamp stamp, Constant constant) {
259         if (stamp instanceof IntegerStamp) {
260             PrimitiveConstant primitive = (PrimitiveConstant) constant;
261             assert primitive.getJavaKind().isNumericInteger() && stamp.getStackKind() == primitive.getJavaKind().getStackKind();
262             IntegerStamp istamp = (IntegerStamp) stamp;
263             return forIntegerBits(istamp.getBits(), primitive);
264         } else if (stamp instanceof FloatStamp) {
265             PrimitiveConstant primitive = (PrimitiveConstant) constant;
266             assert primitive.getJavaKind().isNumericFloat() && stamp.getStackKind() == primitive.getJavaKind();
267             return forConstant(primitive, null);
268         } else {
269             assert !(stamp instanceof AbstractObjectStamp);
270             return new ConstantNode(constant, stamp.constant(constant, null));
271         }
272     }
273 
274     /**
275      * Returns a node for a double constant.
276      *
277      * @param d the double value for which to create the instruction
278      * @return a node for a double constant
279      */
forDouble(double d, StructuredGraph graph)280     public static ConstantNode forDouble(double d, StructuredGraph graph) {
281         return unique(graph, createPrimitive(JavaConstant.forDouble(d)));
282     }
283 
284     /**
285      * Returns a node for a double constant.
286      *
287      * @param d the double value for which to create the instruction
288      * @return a node for a double constant
289      */
forDouble(double d)290     public static ConstantNode forDouble(double d) {
291         return createPrimitive(JavaConstant.forDouble(d));
292     }
293 
294     /**
295      * Returns a node for a float constant.
296      *
297      * @param f the float value for which to create the instruction
298      * @return a node for a float constant
299      */
forFloat(float f, StructuredGraph graph)300     public static ConstantNode forFloat(float f, StructuredGraph graph) {
301         return unique(graph, createPrimitive(JavaConstant.forFloat(f)));
302     }
303 
304     /**
305      * Returns a node for a float constant.
306      *
307      * @param f the float value for which to create the instruction
308      * @return a node for a float constant
309      */
forFloat(float f)310     public static ConstantNode forFloat(float f) {
311         return createPrimitive(JavaConstant.forFloat(f));
312     }
313 
314     /**
315      * Returns a node for an long constant.
316      *
317      * @param i the long value for which to create the instruction
318      * @return a node for an long constant
319      */
forLong(long i, StructuredGraph graph)320     public static ConstantNode forLong(long i, StructuredGraph graph) {
321         return unique(graph, createPrimitive(JavaConstant.forLong(i)));
322     }
323 
324     /**
325      * Returns a node for an long constant.
326      *
327      * @param i the long value for which to create the instruction
328      * @return a node for an long constant
329      */
forLong(long i)330     public static ConstantNode forLong(long i) {
331         return createPrimitive(JavaConstant.forLong(i));
332     }
333 
334     /**
335      * Returns a node for an integer constant.
336      *
337      * @param i the integer value for which to create the instruction
338      * @return a node for an integer constant
339      */
forInt(int i, StructuredGraph graph)340     public static ConstantNode forInt(int i, StructuredGraph graph) {
341         return unique(graph, createPrimitive(JavaConstant.forInt(i)));
342     }
343 
344     /**
345      * Returns a node for an integer constant.
346      *
347      * @param i the integer value for which to create the instruction
348      * @return a node for an integer constant
349      */
forInt(int i)350     public static ConstantNode forInt(int i) {
351         return createPrimitive(JavaConstant.forInt(i));
352     }
353 
354     /**
355      * Returns a node for a boolean constant.
356      *
357      * @param i the boolean value for which to create the instruction
358      * @return a node representing the boolean
359      */
forBoolean(boolean i, StructuredGraph graph)360     public static ConstantNode forBoolean(boolean i, StructuredGraph graph) {
361         return unique(graph, createPrimitive(JavaConstant.forInt(i ? 1 : 0)));
362     }
363 
364     /**
365      * Returns a node for a boolean constant.
366      *
367      * @param i the boolean value for which to create the instruction
368      * @return a node representing the boolean
369      */
forBoolean(boolean i)370     public static ConstantNode forBoolean(boolean i) {
371         return createPrimitive(JavaConstant.forInt(i ? 1 : 0));
372     }
373 
374     /**
375      * Returns a node for a byte constant.
376      *
377      * @param i the byte value for which to create the instruction
378      * @return a node representing the byte
379      */
forByte(byte i, StructuredGraph graph)380     public static ConstantNode forByte(byte i, StructuredGraph graph) {
381         return unique(graph, createPrimitive(JavaConstant.forInt(i)));
382     }
383 
384     /**
385      * Returns a node for a char constant.
386      *
387      * @param i the char value for which to create the instruction
388      * @return a node representing the char
389      */
forChar(char i, StructuredGraph graph)390     public static ConstantNode forChar(char i, StructuredGraph graph) {
391         return unique(graph, createPrimitive(JavaConstant.forInt(i)));
392     }
393 
394     /**
395      * Returns a node for a short constant.
396      *
397      * @param i the short value for which to create the instruction
398      * @return a node representing the short
399      */
forShort(short i, StructuredGraph graph)400     public static ConstantNode forShort(short i, StructuredGraph graph) {
401         return unique(graph, createPrimitive(JavaConstant.forInt(i)));
402     }
403 
unique(StructuredGraph graph, ConstantNode node)404     private static ConstantNode unique(StructuredGraph graph, ConstantNode node) {
405         return graph.unique(node);
406     }
407 
forIntegerBits(int bits, JavaConstant constant, StructuredGraph graph)408     private static ConstantNode forIntegerBits(int bits, JavaConstant constant, StructuredGraph graph) {
409         long value = constant.asLong();
410         long bounds = CodeUtil.signExtend(value, bits);
411         return unique(graph, new ConstantNode(constant, StampFactory.forInteger(bits, bounds, bounds)));
412     }
413 
414     /**
415      * Returns a node for a constant integer that's not directly representable as Java primitive
416      * (e.g. short).
417      */
forIntegerBits(int bits, long value, StructuredGraph graph)418     public static ConstantNode forIntegerBits(int bits, long value, StructuredGraph graph) {
419         return forIntegerBits(bits, JavaConstant.forPrimitiveInt(bits, value), graph);
420     }
421 
forIntegerBits(int bits, JavaConstant constant)422     private static ConstantNode forIntegerBits(int bits, JavaConstant constant) {
423         long value = constant.asLong();
424         long bounds = CodeUtil.signExtend(value, bits);
425         return new ConstantNode(constant, StampFactory.forInteger(bits, bounds, bounds));
426     }
427 
428     /**
429      * Returns a node for a constant integer that's not directly representable as Java primitive
430      * (e.g. short).
431      */
forIntegerBits(int bits, long value)432     public static ConstantNode forIntegerBits(int bits, long value) {
433         return forIntegerBits(bits, JavaConstant.forPrimitiveInt(bits, value));
434     }
435 
436     /**
437      * Returns a node for a constant integer that's compatible to a given stamp.
438      */
forIntegerStamp(Stamp stamp, long value, StructuredGraph graph)439     public static ConstantNode forIntegerStamp(Stamp stamp, long value, StructuredGraph graph) {
440         if (stamp instanceof IntegerStamp) {
441             IntegerStamp intStamp = (IntegerStamp) stamp;
442             return forIntegerBits(intStamp.getBits(), value, graph);
443         } else {
444             return forIntegerKind(stamp.getStackKind(), value, graph);
445         }
446     }
447 
448     /**
449      * Returns a node for a constant integer that's compatible to a given stamp.
450      */
forIntegerStamp(Stamp stamp, long value)451     public static ConstantNode forIntegerStamp(Stamp stamp, long value) {
452         if (stamp instanceof IntegerStamp) {
453             IntegerStamp intStamp = (IntegerStamp) stamp;
454             return forIntegerBits(intStamp.getBits(), value);
455         } else {
456             return forIntegerKind(stamp.getStackKind(), value);
457         }
458     }
459 
forIntegerKind(JavaKind kind, long value, StructuredGraph graph)460     public static ConstantNode forIntegerKind(JavaKind kind, long value, StructuredGraph graph) {
461         switch (kind) {
462             case Byte:
463             case Short:
464             case Int:
465                 return ConstantNode.forInt((int) value, graph);
466             case Long:
467                 return ConstantNode.forLong(value, graph);
468             default:
469                 throw GraalError.shouldNotReachHere("unknown kind " + kind);
470         }
471     }
472 
forIntegerKind(JavaKind kind, long value)473     public static ConstantNode forIntegerKind(JavaKind kind, long value) {
474         switch (kind) {
475             case Byte:
476             case Short:
477             case Int:
478                 return createPrimitive(JavaConstant.forInt((int) value));
479             case Long:
480                 return createPrimitive(JavaConstant.forLong(value));
481             default:
482                 throw GraalError.shouldNotReachHere("unknown kind " + kind);
483         }
484     }
485 
forFloatingKind(JavaKind kind, double value, StructuredGraph graph)486     public static ConstantNode forFloatingKind(JavaKind kind, double value, StructuredGraph graph) {
487         switch (kind) {
488             case Float:
489                 return ConstantNode.forFloat((float) value, graph);
490             case Double:
491                 return ConstantNode.forDouble(value, graph);
492             default:
493                 throw GraalError.shouldNotReachHere("unknown kind " + kind);
494         }
495     }
496 
forFloatingKind(JavaKind kind, double value)497     public static ConstantNode forFloatingKind(JavaKind kind, double value) {
498         switch (kind) {
499             case Float:
500                 return ConstantNode.forFloat((float) value);
501             case Double:
502                 return ConstantNode.forDouble(value);
503             default:
504                 throw GraalError.shouldNotReachHere("unknown kind " + kind);
505         }
506     }
507 
508     /**
509      * Returns a node for a constant double that's compatible to a given stamp.
510      */
forFloatingStamp(Stamp stamp, double value, StructuredGraph graph)511     public static ConstantNode forFloatingStamp(Stamp stamp, double value, StructuredGraph graph) {
512         return forFloatingKind(stamp.getStackKind(), value, graph);
513     }
514 
515     /**
516      * Returns a node for a constant double that's compatible to a given stamp.
517      */
forFloatingStamp(Stamp stamp, double value)518     public static ConstantNode forFloatingStamp(Stamp stamp, double value) {
519         return forFloatingKind(stamp.getStackKind(), value);
520     }
521 
defaultForKind(JavaKind kind, StructuredGraph graph)522     public static ConstantNode defaultForKind(JavaKind kind, StructuredGraph graph) {
523         return unique(graph, defaultForKind(kind));
524     }
525 
defaultForKind(JavaKind kind)526     public static ConstantNode defaultForKind(JavaKind kind) {
527         switch (kind) {
528             case Boolean:
529             case Byte:
530             case Char:
531             case Short:
532             case Int:
533                 return ConstantNode.forInt(0);
534             case Double:
535                 return ConstantNode.forDouble(0.0);
536             case Float:
537                 return ConstantNode.forFloat(0.0f);
538             case Long:
539                 return ConstantNode.forLong(0L);
540             case Object:
541                 return ConstantNode.forConstant(JavaConstant.NULL_POINTER, null);
542             default:
543                 return null;
544         }
545     }
546 
547     @Override
getDebugProperties(Map<Object, Object> map)548     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
549         Map<Object, Object> properties = super.getDebugProperties(map);
550         properties.put("rawvalue", value.toValueString());
551         properties.put("stampKind", stamp.unrestricted().toString());
552         return properties;
553     }
554 
555     @Override
toString(Verbosity verbosity)556     public String toString(Verbosity verbosity) {
557         if (verbosity == Verbosity.Name) {
558             return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp(NodeView.DEFAULT).unrestricted().toString() + ")";
559         } else {
560             return super.toString(verbosity);
561         }
562     }
563 
564     @Override
findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection)565     public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) {
566         if (constantReflection == null || !(value instanceof JavaConstant) || ((JavaConstant) value).isNull()) {
567             return null;
568         }
569         Integer length = constantReflection.readArrayLength((JavaConstant) value);
570         if (length == null) {
571             return null;
572         }
573         return ConstantNode.forInt(length);
574     }
575 
576     @NodeIntrinsic
forClass(@onstantNodeParameter ResolvedJavaType type)577     public static native Class<?> forClass(@ConstantNodeParameter ResolvedJavaType type);
578 }
579