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 package jdk.vm.ci.hotspot;
24
25 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
26
27 import jdk.vm.ci.code.TargetDescription;
28 import jdk.vm.ci.common.JVMCIError;
29 import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
30 import jdk.vm.ci.meta.Constant;
31 import jdk.vm.ci.meta.JavaConstant;
32 import jdk.vm.ci.meta.JavaKind;
33 import jdk.vm.ci.meta.MemoryAccessProvider;
34 import jdk.vm.ci.meta.PrimitiveConstant;
35
36 /**
37 * HotSpot implementation of {@link MemoryAccessProvider}.
38 */
39 public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
40
41 protected final HotSpotJVMCIRuntimeProvider runtime;
42
43 public HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
44 this.runtime = runtime;
45 }
46
47 private static Object asObject(Constant base) {
48 if (base instanceof HotSpotObjectConstantImpl) {
49 return ((HotSpotObjectConstantImpl) base).object();
50 } else {
51 return null;
52 }
53 }
54
55 private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
56 if (base instanceof HotSpotMetaspaceConstant) {
57 Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
58 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
59 if (displacement == runtime.getConfig().classMirrorOffset) {
60 // Klass::_java_mirror is valid for all Klass* values
61 return true;
62 }
63 } else {
64 throw new JVMCIError("%s", metaspaceObject);
65 }
66 }
67 return false;
68 }
69
70 private static long asRawPointer(Constant base) {
71 if (base instanceof HotSpotMetaspaceConstant) {
72 return ((HotSpotMetaspaceConstant) base).rawValue();
73 } else if (base instanceof PrimitiveConstant) {
74 PrimitiveConstant prim = (PrimitiveConstant) base;
75 if (prim.getJavaKind().isNumericInteger()) {
76 return prim.asLong();
77 }
78 }
79 throw new JVMCIError("%s", base);
80 }
81
82 private static long readRawValue(Constant baseConstant, long displacement, int bits) {
83 Object base = asObject(baseConstant);
84 if (base != null) {
85 switch (bits) {
86 case 8:
87 return UNSAFE.getByte(base, displacement);
88 case 16:
89 return UNSAFE.getShort(base, displacement);
90 case 32:
91 return UNSAFE.getInt(base, displacement);
92 case 64:
102 case 16:
103 return UNSAFE.getShort(pointer + displacement);
104 case 32:
105 return UNSAFE.getInt(pointer + displacement);
106 case 64:
107 return UNSAFE.getLong(pointer + displacement);
108 default:
109 throw new JVMCIError("%d", bits);
110 }
111 }
112 }
113
114 private boolean verifyReadRawObject(Object expected, Constant base, long displacement, boolean compressed) {
115 if (compressed == runtime.getConfig().useCompressedOops) {
116 Object obj = asObject(base);
117 if (obj != null) {
118 assert expected == UNSAFE.getObject(obj, displacement) : "readUnsafeOop doesn't agree with unsafe.getObject";
119 }
120 }
121 if (base instanceof HotSpotMetaspaceConstant) {
122 Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
123 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
124 if (displacement == runtime.getConfig().classMirrorOffset) {
125 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
126 }
127 }
128 }
129 return true;
130 }
131
132 private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
133 long displacement = initialDisplacement;
134
135 Object ret;
136 Object base = asObject(baseConstant);
137 if (base == null) {
138 assert !compressed;
139 displacement += asRawPointer(baseConstant);
140 ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
141 } else {
142 assert runtime.getConfig().useCompressedOops == compressed;
194 }
195
196 @Override
197 public JavaConstant readNarrowOopConstant(Constant base, long displacement, CompressEncoding encoding) {
198 assert encoding.equals(runtime.getConfig().getOopEncoding()) : "unexpected oop encoding: " + encoding + " != " + runtime.getConfig().getOopEncoding();
199 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
200 }
201
202 private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
203 assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
204 Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
205 return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
206 }
207
208 @Override
209 public Constant readKlassPointerConstant(Constant base, long displacement) {
210 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
211 if (klass == null) {
212 return JavaConstant.NULL_POINTER;
213 }
214 TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
215 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass.getMetaspaceKlass(), klass, false);
216 }
217
218 @Override
219 public Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding) {
220 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true);
221 if (klass == null) {
222 return HotSpotCompressedNullConstant.COMPRESSED_NULL;
223 }
224 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(klass.getMetaspaceKlass()), klass, true);
225 }
226
227 @Override
228 public Constant readMethodPointerConstant(Constant base, long displacement) {
229 TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
230 assert (base instanceof HotSpotObjectConstantImpl);
231 Object baseObject = ((HotSpotObjectConstantImpl) base).object();
232 HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
233 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method.getMetaspaceMethod(), method, false);
234 }
235 }
|
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 package jdk.vm.ci.hotspot;
24
25 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
26 import jdk.vm.ci.common.JVMCIError;
27 import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
28 import jdk.vm.ci.meta.Constant;
29 import jdk.vm.ci.meta.JavaConstant;
30 import jdk.vm.ci.meta.JavaKind;
31 import jdk.vm.ci.meta.MemoryAccessProvider;
32 import jdk.vm.ci.meta.PrimitiveConstant;
33
34 /**
35 * HotSpot implementation of {@link MemoryAccessProvider}.
36 */
37 class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
38
39 protected final HotSpotJVMCIRuntimeProvider runtime;
40
41 public HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
42 this.runtime = runtime;
43 }
44
45 private static Object asObject(Constant base) {
46 if (base instanceof HotSpotObjectConstantImpl) {
47 return ((HotSpotObjectConstantImpl) base).object();
48 } else {
49 return null;
50 }
51 }
52
53 private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
54 if (base instanceof HotSpotMetaspaceConstant) {
55 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
56 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
57 if (displacement == runtime.getConfig().classMirrorOffset) {
58 // Klass::_java_mirror is valid for all Klass* values
59 return true;
60 }
61 } else {
62 throw new JVMCIError("%s", metaspaceObject);
63 }
64 }
65 return false;
66 }
67
68 private static long asRawPointer(Constant base) {
69 if (base instanceof HotSpotMetaspaceConstantImpl) {
70 MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
71 return meta.getMetaspacePointer();
72 } else if (base instanceof PrimitiveConstant) {
73 PrimitiveConstant prim = (PrimitiveConstant) base;
74 if (prim.getJavaKind().isNumericInteger()) {
75 return prim.asLong();
76 }
77 }
78 throw new JVMCIError("%s", base);
79 }
80
81 private static long readRawValue(Constant baseConstant, long displacement, int bits) {
82 Object base = asObject(baseConstant);
83 if (base != null) {
84 switch (bits) {
85 case 8:
86 return UNSAFE.getByte(base, displacement);
87 case 16:
88 return UNSAFE.getShort(base, displacement);
89 case 32:
90 return UNSAFE.getInt(base, displacement);
91 case 64:
101 case 16:
102 return UNSAFE.getShort(pointer + displacement);
103 case 32:
104 return UNSAFE.getInt(pointer + displacement);
105 case 64:
106 return UNSAFE.getLong(pointer + displacement);
107 default:
108 throw new JVMCIError("%d", bits);
109 }
110 }
111 }
112
113 private boolean verifyReadRawObject(Object expected, Constant base, long displacement, boolean compressed) {
114 if (compressed == runtime.getConfig().useCompressedOops) {
115 Object obj = asObject(base);
116 if (obj != null) {
117 assert expected == UNSAFE.getObject(obj, displacement) : "readUnsafeOop doesn't agree with unsafe.getObject";
118 }
119 }
120 if (base instanceof HotSpotMetaspaceConstant) {
121 MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
122 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
123 if (displacement == runtime.getConfig().classMirrorOffset) {
124 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
125 }
126 }
127 }
128 return true;
129 }
130
131 private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
132 long displacement = initialDisplacement;
133
134 Object ret;
135 Object base = asObject(baseConstant);
136 if (base == null) {
137 assert !compressed;
138 displacement += asRawPointer(baseConstant);
139 ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
140 } else {
141 assert runtime.getConfig().useCompressedOops == compressed;
193 }
194
195 @Override
196 public JavaConstant readNarrowOopConstant(Constant base, long displacement, CompressEncoding encoding) {
197 assert encoding.equals(runtime.getConfig().getOopEncoding()) : "unexpected oop encoding: " + encoding + " != " + runtime.getConfig().getOopEncoding();
198 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
199 }
200
201 private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
202 assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
203 Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
204 return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
205 }
206
207 @Override
208 public Constant readKlassPointerConstant(Constant base, long displacement) {
209 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
210 if (klass == null) {
211 return JavaConstant.NULL_POINTER;
212 }
213 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false);
214 }
215
216 @Override
217 public Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding) {
218 HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true);
219 if (klass == null) {
220 return HotSpotCompressedNullConstant.COMPRESSED_NULL;
221 }
222 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, true);
223 }
224
225 @Override
226 public Constant readMethodPointerConstant(Constant base, long displacement) {
227 assert (base instanceof HotSpotObjectConstantImpl);
228 Object baseObject = ((HotSpotObjectConstantImpl) base).object();
229 HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
230 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
231 }
232 }
|