# HG changeset patch # User Roland Schatz # Date 1415727261 -3600 # Node ID a3a2359ac88e910a7ea0adb7046aa19bbdfd4828 # Parent 2dc0d4dcb7095494ed0ca0d57d34cea45806a378 Support constant folding of pointer reads. diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Tue Nov 11 18:34:21 2014 +0100 @@ -71,9 +71,19 @@ * @param base the base address from which the value is read * @param displacement the displacement within the object in bytes * @param bits the number of bits to read from memory - * @return the read value encapsulated in a {@link JavaConstant} object of {@link Kind} kind + * @return the read value encapsulated in a {@link Constant} object of {@link Kind} kind */ - JavaConstant readRawConstant(Kind kind, JavaConstant base, long displacement, int bits); + JavaConstant readRawConstant(Kind kind, Constant base, long displacement, int bits); + + /** + * Reads a pointer value using a base address and a displacement. + * + * @param type the {@link PointerType} of the returned {@link Constant} object + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @return the read value encapsulated in a {@link Constant} object + */ + Constant readPointerConstant(PointerType type, Constant base, long displacement); /** * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractPointerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractPointerStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractPointerStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -61,6 +61,11 @@ } @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + return provider.readPointerConstant(type, base, displacement); + } + + @Override public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { throw GraalInternalError.shouldNotReachHere(type + " pointer has no Java type"); } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -89,6 +89,11 @@ return false; } + @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + throw GraalInternalError.shouldNotReachHere("can't read values of illegal stamp"); + } + private static IllegalStamp instance = new IllegalStamp(); static IllegalStamp getInstance() { diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2014, 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 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.common.type; +import com.oracle.graal.api.meta.*; + /** * Type describing primitive values. */ @@ -50,6 +52,11 @@ } @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + return provider.readRawConstant(getStackKind(), base, displacement, getBits()); + } + + @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -116,10 +116,12 @@ return null; } + public abstract Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement); + /** * Tries to improve this stamp with the stamp given as parameter. If successful, returns the new * improved stamp. Otherwise, returns null. - * + * * @param other the stamp that should be used to improve this stamp * @return the newly improved stamp of null if an improvement was not possible */ diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -103,6 +103,11 @@ } @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + throw GraalInternalError.shouldNotReachHere("can't read values of void stamp"); + } + + @Override public Stamp constant(Constant c, MetaAccessProvider meta) { throw GraalInternalError.shouldNotReachHere("void stamp has no value"); } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Nov 11 18:34:21 2014 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.compiler.common.UnsafeAccess.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import java.lang.reflect.*; @@ -61,94 +60,22 @@ return Array.getLength(arrayObject); } - @Override - public JavaConstant readUnsafeConstant(Kind kind, JavaConstant baseConstant, long initialDisplacement) { + private static long readRawValue(Constant baseConstant, long initialDisplacement, int bits) { Object base; long displacement; - if (baseConstant.getKind() == Kind.Object) { - base = baseConstant.isNull() ? null : ((HotSpotObjectConstantImpl) baseConstant).object(); - displacement = initialDisplacement; - if (base == null) { - return null; - } - } else if (baseConstant.getKind().isNumericInteger()) { - long baseLong = baseConstant.asLong(); - if (baseLong == 0L) { - return null; + if (baseConstant instanceof JavaConstant) { + JavaConstant javaConstant = (JavaConstant) baseConstant; + if (javaConstant instanceof HotSpotObjectConstantImpl) { + base = ((HotSpotObjectConstantImpl) javaConstant).object(); + displacement = initialDisplacement; + } else if (javaConstant.getKind().isNumericInteger()) { + long baseLong = javaConstant.asLong(); + assert baseLong != 0; + displacement = initialDisplacement + baseLong; + base = null; + } else { + throw GraalInternalError.shouldNotReachHere(); } - displacement = initialDisplacement + baseLong; - base = null; - } else { - throw GraalInternalError.shouldNotReachHere(); - } - - switch (kind) { - case Boolean: - return JavaConstant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement)); - case Byte: - return JavaConstant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement)); - case Char: - return JavaConstant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement)); - case Short: - return JavaConstant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement)); - case Int: - return JavaConstant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement)); - case Long: - if (displacement == config().hubOffset && runtime.getConfig().useCompressedClassPointers) { - if (base == null) { - throw new GraalInternalError("Base of object must not be null"); - } else { - return JavaConstant.forLong(runtime.getCompilerToVM().readUnsafeKlassPointer(base)); - } - } else { - return JavaConstant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement)); - } - case Float: - return JavaConstant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement)); - case Double: - return JavaConstant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement)); - case Object: { - Object o = null; - if (baseConstant.getKind() == Kind.Object) { - o = unsafe.getObject(base, displacement); - } else if (baseConstant instanceof HotSpotMetaspaceConstant) { - Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(baseConstant); - if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl && initialDisplacement == runtime.getConfig().classMirrorOffset) { - o = ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror(); - } else if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl && initialDisplacement == runtime.getConfig().arrayKlassComponentMirrorOffset) { - o = ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType(); - } else if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl && initialDisplacement == runtime.getConfig().instanceKlassNodeClassOffset) { - o = NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror()); - } else { - throw GraalInternalError.shouldNotReachHere(); - } - } else { - throw GraalInternalError.shouldNotReachHere(); - } - return HotSpotObjectConstantImpl.forObject(o); - } - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - - @Override - public JavaConstant readRawConstant(Kind kind, JavaConstant baseConstant, long initialDisplacement, int bits) { - Object base; - long displacement; - if (baseConstant.getKind() == Kind.Object) { - base = baseConstant.isNull() ? null : ((HotSpotObjectConstantImpl) baseConstant).object(); - displacement = initialDisplacement; - if (base == null) { - return null; - } - } else if (baseConstant.getKind().isNumericInteger()) { - long baseLong = baseConstant.asLong(); - if (baseLong == 0L) { - return null; - } - displacement = initialDisplacement + baseLong; - base = null; } else { throw GraalInternalError.shouldNotReachHere(); } @@ -170,22 +97,54 @@ default: throw GraalInternalError.shouldNotReachHere(); } + return rawValue; + } - if (base != null && displacement == config().hubOffset) { - if (config().useCompressedClassPointers) { - assert bits == 32 && kind == Kind.Int; - long klassPointer = config().getKlassEncoding().uncompress((int) rawValue); - assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base); - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klassPointer), true); - } else { - assert bits == 64 && kind == Kind.Long; - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(rawValue), false); + private Object readRawObject(Constant baseConstant, long displacement, boolean compressed) { + if (baseConstant instanceof HotSpotObjectConstantImpl) { + assert compressed == runtime.getConfig().useCompressedOops; + return unsafe.getObject(((HotSpotObjectConstantImpl) baseConstant).object(), displacement); + } else if (baseConstant instanceof HotSpotMetaspaceConstant) { + Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(baseConstant); + if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) { + assert !compressed : "unexpected compressed read from Klass*"; + if (displacement == runtime.getConfig().classMirrorOffset) { + return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror(); + } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) { + return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType(); + } else if (displacement == runtime.getConfig().instanceKlassNodeClassOffset) { + return NodeClass.get(((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror()); + } } - } else if (displacement == config().klassOffset && base instanceof Class) { - long value = unsafe.getLong(base, displacement); - return HotSpotMetaspaceConstantImpl.forMetaspaceObject(kind, value, runtime.getHostProviders().getMetaAccess().lookupJavaType((Class) base), false); + throw GraalInternalError.shouldNotReachHere("read from unknown Klass* offset " + displacement); + } else { + throw GraalInternalError.shouldNotReachHere("unexpected base pointer: " + (baseConstant == null ? "null" : baseConstant.toString())); + } + } + + @Override + public JavaConstant readUnsafeConstant(Kind kind, JavaConstant baseConstant, long displacement) { + if (kind == Kind.Object) { + Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops); + return HotSpotObjectConstantImpl.forObject(o); } else { + return readRawConstant(kind, baseConstant, displacement, kind.getByteCount() * 8); + } + } + + @Override + public JavaConstant readRawConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) { + try { + long rawValue = readRawValue(baseConstant, initialDisplacement, bits); switch (kind) { + case Boolean: + return JavaConstant.forBoolean(rawValue != 0); + case Byte: + return JavaConstant.forByte((byte) rawValue); + case Char: + return JavaConstant.forChar((char) rawValue); + case Short: + return JavaConstant.forShort((short) rawValue); case Int: return JavaConstant.forInt((int) rawValue); case Long: @@ -195,8 +154,51 @@ case Double: return JavaConstant.forDouble(Double.longBitsToDouble(rawValue)); default: - throw GraalInternalError.shouldNotReachHere(); + throw GraalInternalError.shouldNotReachHere("unsupported kind: " + kind); } + } catch (NullPointerException e) { + return null; + } + } + + public Constant readPointerConstant(PointerType type, Constant base, long displacement) { + switch (type) { + case Object: + if (base instanceof PrimitiveConstant && !(base instanceof HotSpotMetaspaceConstant)) { + // FIXME: we lost a metaspace annotation somewhere + return null; + } + return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false)); + case Type: + long klass = readRawValue(base, displacement, runtime.getTarget().wordSize * 8); + HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass); + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, klass, metaKlass, false); + case Method: + long method = readRawValue(base, displacement, runtime.getTarget().wordSize * 8); + HotSpotResolvedJavaMethod metaMethod = HotSpotResolvedJavaMethodImpl.fromMetaspace(method); + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime.getTarget().wordKind, method, metaMethod, false); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + public Constant readNarrowPointerConstant(PointerType type, Constant base, long displacement) { + switch (type) { + case Object: + if (base instanceof PrimitiveConstant && !(base instanceof HotSpotMetaspaceConstant)) { + // FIXME: we lost a metaspace annotation somewhere + return null; + } + return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true); + case Type: + int compressed = (int) readRawValue(base, displacement, 32); + long klass = runtime.getConfig().getKlassEncoding().uncompress(compressed); + HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass); + return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, compressed, metaKlass, true); + case Method: + // there are no compressed method pointers + default: + throw GraalInternalError.shouldNotReachHere(); } } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java Tue Nov 11 18:34:21 2014 +0100 @@ -36,7 +36,7 @@ return new HotSpotMetaspaceConstantImpl(kind, primitive, metaspaceObject, compressed); } - static Object getMetaspaceObject(JavaConstant constant) { + static Object getMetaspaceObject(Constant constant) { return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject; } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Tue Nov 11 18:34:21 2014 +0100 @@ -40,10 +40,14 @@ private static final long serialVersionUID = 3592151693708093496L; public static JavaConstant forObject(Object object) { + return forObject(object, false); + } + + public static JavaConstant forObject(Object object, boolean compressed) { if (object == null) { - return JavaConstant.NULL_OBJECT; + return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_OBJECT; } else { - return new HotSpotObjectConstantImpl(object, false); + return new HotSpotObjectConstantImpl(object, compressed); } } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Tue Nov 11 18:34:21 2014 +0100 @@ -81,6 +81,9 @@ } else if (c instanceof HotSpotMetaspaceConstant) { assert ((HotSpotMetaspaceConstant) c).stamp().getStackKind() == Kind.Long; return ((HotSpotMetaspaceConstant) c).compress(encoding); + } else if (c instanceof PrimitiveConstant) { + assert ((PrimitiveConstant) c).getKind() == Kind.Long; + return JavaConstant.forInt(encoding.compress(((PrimitiveConstant) c).asLong())); } else { throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c); } @@ -94,6 +97,9 @@ } else if (c instanceof HotSpotMetaspaceConstant) { assert ((HotSpotMetaspaceConstant) c).stamp().getStackKind() == Kind.Int; return ((HotSpotMetaspaceConstant) c).uncompress(encoding); + } else if (c instanceof PrimitiveConstant) { + assert ((PrimitiveConstant) c).getKind() == Kind.Int; + return JavaConstant.forLong(encoding.uncompress(((PrimitiveConstant) c).asInt())); } else { throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c); } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -80,6 +80,11 @@ } @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + return ((HotSpotConstantReflectionProvider) provider).readNarrowPointerConstant(PointerType.Object, base, displacement); + } + + @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java Tue Nov 11 18:34:21 2014 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.HotSpotVMConfig.*; +import com.oracle.graal.hotspot.meta.*; public class NarrowPointerStamp extends AbstractPointerStamp { @@ -87,6 +88,11 @@ } @Override + public Constant readConstant(ConstantReflectionProvider provider, Constant base, long displacement) { + return ((HotSpotConstantReflectionProvider) provider).readNarrowPointerConstant(getType(), base, displacement); + } + + @Override public boolean isLegal() { return true; } diff -r 2dc0d4dcb709 -r a3a2359ac88e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Nov 11 15:03:10 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Nov 11 18:34:21 2014 +0100 @@ -119,22 +119,12 @@ public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) { MetaAccessProvider metaAccess = tool.getMetaAccess(); if (tool.canonicalizeReads()) { - if (metaAccess != null && object != null && object.isConstant()) { + if (metaAccess != null && object != null && object.isConstant() && !object.isNullConstant()) { if ((location.getLocationIdentity().isImmutable()) && location instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location).getDisplacement(); - JavaConstant base = object.asJavaConstant(); - if (base != null) { - JavaConstant constant; - if (read.stamp() instanceof PrimitiveStamp) { - PrimitiveStamp stamp = (PrimitiveStamp) read.stamp(); - constant = tool.getConstantReflection().readRawConstant(stamp.getStackKind(), base, displacement, stamp.getBits()); - } else { - assert read.stamp() instanceof ObjectStamp; - constant = tool.getConstantReflection().readUnsafeConstant(Kind.Object, base, displacement); - } - if (constant != null) { - return ConstantNode.forConstant(read.stamp(), constant, metaAccess); - } + Constant constant = read.stamp().readConstant(tool.getConstantReflection(), object.asConstant(), displacement); + if (constant != null) { + return ConstantNode.forConstant(read.stamp(), constant, metaAccess); } } }