3737import org .graalvm .word .WordBase ;
3838
3939import com .oracle .graal .pointsto .constraints .UnsupportedFeatureException ;
40+ import com .oracle .graal .pointsto .heap .ImageHeapArray ;
41+ import com .oracle .graal .pointsto .heap .ImageHeapConstant ;
4042import com .oracle .graal .pointsto .meta .AnalysisField ;
4143import com .oracle .graal .pointsto .meta .AnalysisMethod ;
4244import 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 }
0 commit comments