Skip to content

Commit 8eca77b

Browse files
committed
[GR-39433] Allow instances of simulated classes in the image heap.
PullRequest: graal/12288
2 parents 6ce58a6 + dfe7b7b commit 8eca77b

File tree

56 files changed

+1197
-468
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1197
-468
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/CompressibleConstant.java renamed to compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/CompressibleConstant.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,15 +22,15 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package com.oracle.svm.core.meta;
25+
package org.graalvm.compiler.core.common.type;
2626

27-
import jdk.vm.ci.meta.Constant;
27+
import jdk.vm.ci.meta.JavaConstant;
2828

2929
// Subject to unification with HotspotConstant
30-
public interface CompressibleConstant extends Constant {
30+
public interface CompressibleConstant extends JavaConstant {
3131
boolean isCompressed();
3232

33-
Constant compress();
33+
JavaConstant compress();
3434

35-
Constant uncompress();
35+
JavaConstant uncompress();
3636
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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.core.common.type;
26+
27+
import jdk.vm.ci.meta.JavaConstant;
28+
import jdk.vm.ci.meta.MetaAccessProvider;
29+
import jdk.vm.ci.meta.ResolvedJavaType;
30+
31+
public interface TypedConstant extends JavaConstant {
32+
ResolvedJavaType getType(MetaAccessProvider provider);
33+
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/AnalysisObjectScanningObserver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public boolean forNullFieldValue(JavaConstant receiver, AnalysisField field, Sca
6363
@Override
6464
public boolean forNonNullFieldValue(JavaConstant receiver, AnalysisField field, JavaConstant fieldValue, ScanReason reason) {
6565
PointsToAnalysis analysis = getAnalysis();
66-
AnalysisType fieldType = analysis.getMetaAccess().lookupJavaType(analysis.getSnippetReflectionProvider().asObject(Object.class, fieldValue).getClass());
66+
AnalysisType fieldType = analysis.getMetaAccess().lookupJavaType(fieldValue);
6767

6868
/* Add the constant value object to the field's type flow. */
6969
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
@@ -87,7 +87,7 @@ private FieldTypeFlow getFieldTypeFlow(AnalysisField field, JavaConstant receive
8787
* constant object.
8888
*/
8989
PointsToAnalysis analysis = getAnalysis();
90-
AnalysisType receiverType = analysis.getMetaAccess().lookupJavaType(analysis.getSnippetReflectionProvider().asObject(Object.class, receiver).getClass());
90+
AnalysisType receiverType = analysis.getMetaAccess().lookupJavaType(receiver);
9191
AnalysisObject constantReceiverObj = analysis.analysisPolicy().createConstantObject(analysis, receiver, receiverType);
9292
return constantReceiverObj.getInstanceFieldFlow(analysis, field, true);
9393
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/ObjectScanner.java

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import org.graalvm.word.WordBase;
3838

3939
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
40+
import com.oracle.graal.pointsto.heap.ImageHeapArray;
41+
import com.oracle.graal.pointsto.heap.ImageHeapConstant;
4042
import com.oracle.graal.pointsto.meta.AnalysisField;
4143
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4244
import com.oracle.graal.pointsto.meta.AnalysisType;
@@ -164,7 +166,7 @@ protected final void scanField(AnalysisField field, JavaConstant receiver, ScanR
164166
System.lineSeparator() + backtrace);
165167
}
166168

167-
if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(constantAsObject(bb, fieldValue))) {
169+
if (fieldValue.getJavaKind() == JavaKind.Object && bb.getHostVM().isRelocatedPointer(bb.getMetaAccess(), fieldValue)) {
168170
scanningObserver.forRelocatedPointerFieldValue(receiver, field, fieldValue, reason);
169171
} else if (fieldValue.isNull()) {
170172
scanningObserver.forNullFieldValue(receiver, field, reason);
@@ -191,45 +193,60 @@ protected final void scanField(AnalysisField field, JavaConstant receiver, ScanR
191193
*/
192194
protected final void scanArray(JavaConstant array, ScanReason prevReason) {
193195

194-
Object valueObj = constantAsObject(bb, array);
195-
AnalysisType arrayType = analysisType(bb, valueObj);
196-
assert valueObj instanceof Object[];
197-
196+
AnalysisType arrayType = bb.getMetaAccess().lookupJavaType(array);
198197
ScanReason reason = new ArrayScan(arrayType, array, prevReason);
199-
Object[] arrayObject = (Object[]) valueObj;
200-
for (int idx = 0; idx < arrayObject.length; idx++) {
201-
Object e = arrayObject[idx];
202-
if (e == null) {
203-
scanningObserver.forNullArrayElement(array, arrayType, idx, reason);
204-
} else {
205-
try {
206-
Object element = bb.getUniverse().replaceObject(e);
207-
JavaConstant elementConstant = bb.getSnippetReflectionProvider().forObject(element);
208-
AnalysisType elementType = analysisType(bb, element);
209-
/* First notify the observer about the array element value... */
210-
scanningObserver.forNonNullArrayElement(array, arrayType, elementConstant, elementType, idx, reason);
211-
/*
212-
* ... and only then scan the new value, i.e., follow its references. The order
213-
* is important for observers that expect to see the receiver before any of its
214-
* referenced elements are being scanned.
215-
*/
216-
scanConstant(elementConstant, reason);
217-
} catch (UnsupportedFeatureException ex) {
218-
unsupportedFeatureDuringConstantScan(bb, bb.getSnippetReflectionProvider().forObject(e), ex, reason);
198+
199+
if (array instanceof ImageHeapConstant) {
200+
if (!arrayType.getComponentType().isPrimitive()) {
201+
ImageHeapArray heapArray = (ImageHeapArray) array;
202+
for (int idx = 0; idx < heapArray.getLength(); idx++) {
203+
final JavaConstant element = heapArray.getElement(idx);
204+
if (element.isNull()) {
205+
scanningObserver.forNullArrayElement(array, arrayType, idx, reason);
206+
} else {
207+
scanArrayElement(array, arrayType, reason, idx, element);
208+
}
209+
}
210+
}
211+
} else {
212+
Object[] arrayObject = (Object[]) constantAsObject(bb, array);
213+
for (int idx = 0; idx < arrayObject.length; idx++) {
214+
Object e = arrayObject[idx];
215+
if (e == null) {
216+
scanningObserver.forNullArrayElement(array, arrayType, idx, reason);
217+
} else {
218+
try {
219+
JavaConstant element = bb.getSnippetReflectionProvider().forObject(bb.getUniverse().replaceObject(e));
220+
scanArrayElement(array, arrayType, reason, idx, element);
221+
} catch (UnsupportedFeatureException ex) { /* Object replacement can throw. */
222+
unsupportedFeatureDuringConstantScan(bb, bb.getSnippetReflectionProvider().forObject(e), ex, reason);
223+
}
219224
}
220225
}
221226
}
222227
}
223228

229+
private void scanArrayElement(JavaConstant array, AnalysisType arrayType, ScanReason reason, int idx, JavaConstant elementConstant) {
230+
AnalysisType elementType = bb.getMetaAccess().lookupJavaType(elementConstant);
231+
/* First notify the observer about the array element value... */
232+
scanningObserver.forNonNullArrayElement(array, arrayType, elementConstant, elementType, idx, reason);
233+
/*
234+
* ... and only then scan the new value, i.e., follow its references. The order is important
235+
* for observers that expect to see the receiver before any of its referenced elements are
236+
* being scanned.
237+
*/
238+
scanConstant(elementConstant, reason);
239+
}
240+
224241
public final void scanConstant(JavaConstant value, ScanReason reason) {
225-
Object valueObj = constantAsObject(bb, value);
226-
if (valueObj == null || valueObj instanceof WordBase) {
242+
if (value.isNull() || bb.getMetaAccess().isInstanceOf(value, WordBase.class)) {
227243
return;
228244
}
229245
if (!bb.scanningPolicy().scanConstant(bb, value)) {
230-
bb.markTypeInHeap(analysisType(bb, valueObj));
246+
bb.markTypeInHeap(bb.getMetaAccess().lookupJavaType(value));
231247
return;
232248
}
249+
Object valueObj = (value instanceof ImageHeapConstant) ? value : constantAsObject(bb, value);
233250
if (scannedObjects.putAndAcquire(valueObj) == null) {
234251
try {
235252
scanningObserver.forScannedConstant(value, reason);
@@ -316,14 +333,17 @@ public static String asString(BigBang bb, JavaConstant constant) {
316333
}
317334

318335
public static String asString(BigBang bb, JavaConstant constant, boolean appendToString) {
319-
if (constant == null) {
336+
if (constant == null || constant.isNull()) {
320337
return "null";
321338
}
322-
Object obj = constantAsObject(bb, constant);
323-
if (obj == null) {
324-
return "null";
339+
AnalysisType type = bb.getMetaAccess().lookupJavaType(constant);
340+
if (constant instanceof ImageHeapConstant) {
341+
// Checkstyle: allow Class.getSimpleName
342+
return constant.getClass().getSimpleName() + "<" + type.toJavaName() + ">";
343+
// Checkstyle: disallow Class.getSimpleName
325344
}
326-
String str = analysisType(bb, obj).toJavaName() + '@' + Integer.toHexString(System.identityHashCode(obj));
345+
Object obj = constantAsObject(bb, constant);
346+
String str = type.toJavaName() + '@' + Integer.toHexString(System.identityHashCode(obj));
327347
if (appendToString) {
328348
try {
329349
str += ": " + limit(obj.toString(), 80).replace(System.lineSeparator(), "");
@@ -351,10 +371,8 @@ public static String limit(String value, int length) {
351371
* element constants.
352372
*/
353373
private void doScan(WorklistEntry entry) {
354-
Object valueObj = constantAsObject(bb, entry.constant);
355-
356374
try {
357-
AnalysisType type = analysisType(bb, valueObj);
375+
AnalysisType type = bb.getMetaAccess().lookupJavaType(entry.constant);
358376
type.registerAsReachable();
359377

360378
if (type.isInstanceClass()) {
@@ -392,10 +410,6 @@ protected void finish() {
392410
}
393411
}
394412

395-
protected static AnalysisType analysisType(BigBang bb, Object constant) {
396-
return bb.getMetaAccess().lookupJavaType(constant.getClass());
397-
}
398-
399413
public static AnalysisType constantType(BigBang bb, JavaConstant constant) {
400414
return bb.getMetaAccess().lookupJavaType(constant);
401415
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/api/HostVM.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@
4545
import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess;
4646

4747
import com.oracle.graal.pointsto.BigBang;
48+
import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess;
4849
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4950
import com.oracle.graal.pointsto.meta.AnalysisType;
5051
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
5152
import com.oracle.graal.pointsto.meta.HostedProviders;
5253
import com.oracle.graal.pointsto.phases.InlineBeforeAnalysisPolicy;
5354

55+
import jdk.vm.ci.meta.JavaConstant;
5456
import jdk.vm.ci.meta.ResolvedJavaMethod;
5557
import jdk.vm.ci.meta.ResolvedJavaType;
5658

@@ -78,9 +80,10 @@ public OptionValues options() {
7880
/**
7981
* Check if the provided object is a relocated pointer.
8082
*
81-
* @param originalObject the object to check
83+
* @param metaAccess the meta-access provider
84+
* @param constant the constant to check
8285
*/
83-
public boolean isRelocatedPointer(Object originalObject) {
86+
public boolean isRelocatedPointer(UniverseMetaAccess metaAccess, JavaConstant constant) {
8487
return false;
8588
}
8689

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ protected void apply() {
430430
AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
431431
assert type.isInstantiated();
432432
TypeFlowBuilder<ConstantTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, ConstantTypeFlow.class, () -> {
433-
ConstantTypeFlow constantSource = new ConstantTypeFlow(sourcePosition(node), type, TypeState.forConstant(this.bb, node.asJavaConstant(), type));
433+
JavaConstant heapConstant = bb.getUniverse().getHeapScanner().toImageHeapObject(node.asJavaConstant());
434+
ConstantTypeFlow constantSource = new ConstantTypeFlow(sourcePosition(node), type, TypeState.forConstant(this.bb, heapConstant, type));
434435
flowsGraph.addMiscEntryFlow(constantSource);
435436
return constantSource;
436437
});

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/context/object/AnalysisObject.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,8 @@ public boolean isObjectArray() {
289289
*/
290290
public static boolean isEmptyObjectArrayConstant(PointsToAnalysis bb, JavaConstant constant) {
291291
assert constant.getJavaKind() == JavaKind.Object;
292-
Object valueObj = bb.getProviders().getSnippetReflection().asObject(Object.class, constant);
293-
if (valueObj instanceof Object[]) {
294-
Object[] arrayValueObj = (Object[]) valueObj;
295-
if (arrayValueObj.length == 0) {
296-
return true;
297-
}
298-
}
299-
return false;
292+
Integer length = bb.getConstantReflectionProvider().readArrayLength(constant);
293+
return length != null && length == 0;
300294
}
301295

302296
@Override

0 commit comments

Comments
 (0)