Mercurial > hg > truffle
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 } |