comparison graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotMemoryAccessProviderImpl.java @ 21551:5324104ac4f3

moved com.oracle.graal.hotspot.jvmci classes to com.oracle.jvmci.hotspot module (JBS:GRAAL-53)
author Doug Simon <doug.simon@oracle.com>
date Tue, 26 May 2015 17:13:37 +0200
parents
children
comparison
equal deleted inserted replaced
21550:f48a6cea31eb 21551:5324104ac4f3
1 /*
2 * Copyright (c) 2011, 2015, 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 package com.oracle.jvmci.hotspot;
24
25 import static com.oracle.jvmci.common.UnsafeAccess.*;
26
27 import com.oracle.graal.api.code.*;
28 import com.oracle.graal.api.meta.*;
29 import com.oracle.jvmci.common.*;
30 import com.oracle.jvmci.hotspot.HotSpotVMConfig.*;
31
32 /**
33 * HotSpot implementation of {@link MemoryAccessProvider}.
34 */
35 public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
36
37 protected final HotSpotJVMCIRuntimeProvider runtime;
38
39 public HotSpotMemoryAccessProviderImpl(HotSpotJVMCIRuntimeProvider runtime) {
40 this.runtime = runtime;
41 }
42
43 private static Object asObject(Constant base) {
44 if (base instanceof HotSpotObjectConstantImpl) {
45 return ((HotSpotObjectConstantImpl) base).object();
46 } else {
47 return null;
48 }
49 }
50
51 private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
52 if (base instanceof HotSpotMetaspaceConstant) {
53 Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
54 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
55 if (displacement == runtime.getConfig().classMirrorOffset) {
56 // Klass::_java_mirror is valid for all Klass* values
57 return true;
58 } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
59 // ArrayKlass::_component_mirror is only valid for all ArrayKlass* values
60 return ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().isArray();
61 }
62 } else {
63 throw new JVMCIError("%s", metaspaceObject);
64 }
65 }
66 return false;
67 }
68
69 private static long asRawPointer(Constant base) {
70 if (base instanceof HotSpotMetaspaceConstant) {
71 return ((HotSpotMetaspaceConstant) base).rawValue();
72 } else if (base instanceof PrimitiveConstant) {
73 PrimitiveConstant prim = (PrimitiveConstant) base;
74 if (prim.getKind().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:
92 return unsafe.getLong(base, displacement);
93 default:
94 throw new JVMCIError("%d", bits);
95 }
96 } else {
97 long pointer = asRawPointer(baseConstant);
98 switch (bits) {
99 case 8:
100 return unsafe.getByte(pointer + displacement);
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 Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
122 if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
123 if (displacement == runtime.getConfig().classMirrorOffset) {
124 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
125 } else if (displacement == runtime.getConfig().arrayKlassComponentMirrorOffset) {
126 assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror().getComponentType();
127 }
128 }
129 }
130 return true;
131 }
132
133 private Object readRawObject(Constant baseConstant, long initialDisplacement, boolean compressed) {
134 long displacement = initialDisplacement;
135
136 Object ret;
137 Object base = asObject(baseConstant);
138 if (base == null) {
139 assert !compressed;
140 displacement += asRawPointer(baseConstant);
141 ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
142 } else {
143 assert runtime.getConfig().useCompressedOops == compressed;
144 ret = unsafe.getObject(base, displacement);
145 }
146 assert verifyReadRawObject(ret, baseConstant, initialDisplacement, compressed);
147 return ret;
148 }
149
150 @Override
151 public JavaConstant readUnsafeConstant(Kind kind, JavaConstant baseConstant, long displacement) {
152 if (kind == Kind.Object) {
153 Object o = readRawObject(baseConstant, displacement, runtime.getConfig().useCompressedOops);
154 return HotSpotObjectConstantImpl.forObject(o);
155 } else {
156 return readPrimitiveConstant(kind, baseConstant, displacement, kind.getByteCount() * 8);
157 }
158 }
159
160 @Override
161 public JavaConstant readPrimitiveConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) {
162 try {
163 long rawValue = readRawValue(baseConstant, initialDisplacement, bits);
164 switch (kind) {
165 case Boolean:
166 return JavaConstant.forBoolean(rawValue != 0);
167 case Byte:
168 return JavaConstant.forByte((byte) rawValue);
169 case Char:
170 return JavaConstant.forChar((char) rawValue);
171 case Short:
172 return JavaConstant.forShort((short) rawValue);
173 case Int:
174 return JavaConstant.forInt((int) rawValue);
175 case Long:
176 return JavaConstant.forLong(rawValue);
177 case Float:
178 return JavaConstant.forFloat(Float.intBitsToFloat((int) rawValue));
179 case Double:
180 return JavaConstant.forDouble(Double.longBitsToDouble(rawValue));
181 default:
182 throw new JVMCIError("Unsupported kind: %s", kind);
183 }
184 } catch (NullPointerException e) {
185 return null;
186 }
187 }
188
189 @Override
190 public JavaConstant readObjectConstant(Constant base, long displacement) {
191 if (!isValidObjectFieldDisplacement(base, displacement)) {
192 return null;
193 }
194 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, false));
195 }
196
197 @Override
198 public JavaConstant readNarrowOopConstant(Constant base, long displacement, CompressEncoding encoding) {
199 assert encoding.equals(runtime.getConfig().getOopEncoding()) : "unexpected oop encoding: " + encoding + " != " + runtime.getConfig().getOopEncoding();
200 return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
201 }
202
203 @Override
204 public Constant readKlassPointerConstant(Constant base, long displacement) {
205 TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
206 long klass = readRawValue(base, displacement, target.wordSize * 8);
207 if (klass == 0) {
208 return JavaConstant.NULL_POINTER;
209 }
210 HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
211 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass, metaKlass, false);
212 }
213
214 @Override
215 public Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding) {
216 int compressed = (int) readRawValue(base, displacement, 32);
217 long klass = encoding.uncompress(compressed);
218 if (klass == 0) {
219 return HotSpotCompressedNullConstant.COMPRESSED_NULL;
220 }
221 HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
222 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, compressed, metaKlass, true);
223 }
224
225 @Override
226 public Constant readMethodPointerConstant(Constant base, long displacement) {
227 TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
228 long method = readRawValue(base, displacement, target.wordSize * 8);
229 HotSpotResolvedJavaMethod metaMethod = HotSpotResolvedJavaMethodImpl.fromMetaspace(method);
230 return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method, metaMethod, false);
231 }
232 }