comparison jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java @ 22672:1bbd4a7c274b

Rename jdk.internal.jvmci to jdk.vm.ci
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Oct 2015 17:28:41 -0700
parents jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java@61bb5fa12458
children 023981d7f257
comparison
equal deleted inserted replaced
22671:97f30e4d0e95 22672:1bbd4a7c274b
1 /*
2 * Copyright (c) 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 jdk.vm.ci.hotspot;
24
25 import static jdk.vm.ci.inittimer.InitTimer.timer;
26
27 import java.io.IOException;
28 import java.io.OutputStream;
29 import java.lang.reflect.Array;
30 import java.lang.reflect.Field;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Modifier;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Map;
36 import java.util.Objects;
37 import java.util.TreeMap;
38
39 import jdk.vm.ci.code.Architecture;
40 import jdk.vm.ci.code.CompilationResult;
41 import jdk.vm.ci.code.InstalledCode;
42 import jdk.vm.ci.common.JVMCIError;
43 import jdk.vm.ci.compiler.Compiler;
44 import jdk.vm.ci.inittimer.InitTimer;
45 import jdk.vm.ci.meta.JVMCIMetaAccessContext;
46 import jdk.vm.ci.meta.JavaKind;
47 import jdk.vm.ci.meta.JavaType;
48 import jdk.vm.ci.meta.ResolvedJavaType;
49 import jdk.vm.ci.runtime.JVMCI;
50 import jdk.vm.ci.runtime.JVMCIBackend;
51 import jdk.vm.ci.service.Services;
52
53 //JaCoCo Exclude
54
55 /**
56 * HotSpot implementation of a JVMCI runtime.
57 */
58 public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
59
60 /**
61 * The proper initialization of this class is complex because it's tangled up with the
62 * initialization of the JVMCI and really should only ever be triggered through
63 * {@link JVMCI#getRuntime}. However since {@link #runtime} can also be called directly it
64 * should also trigger proper initialization. To ensure proper ordering, the static initializer
65 * of this class initializes {@link JVMCI} and then access to
66 * {@link HotSpotJVMCIRuntime.DelayedInit#instance} triggers the final initialization of the
67 * {@link HotSpotJVMCIRuntime}.
68 */
69 private static void initializeJVMCI() {
70 JVMCI.initialize();
71 }
72
73 static {
74 initializeJVMCI();
75 }
76
77 @SuppressWarnings("try")
78 static class DelayedInit {
79 private static final HotSpotJVMCIRuntime instance;
80
81 static {
82 try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
83 instance = new HotSpotJVMCIRuntime();
84 }
85 }
86 }
87
88 /**
89 * Gets the singleton {@link HotSpotJVMCIRuntime} object.
90 */
91 public static HotSpotJVMCIRuntime runtime() {
92 return DelayedInit.instance;
93 }
94
95 public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
96 for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) {
97 if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
98 return factory;
99 }
100 }
101
102 throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture);
103 }
104
105 /**
106 * Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
107 */
108 public static JavaKind getHostWordKind() {
109 return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind;
110 }
111
112 protected final CompilerToVM compilerToVm;
113
114 protected final HotSpotVMConfig config;
115 private final JVMCIBackend hostBackend;
116
117 private volatile Compiler compiler;
118 protected final JVMCIMetaAccessContext metaAccessContext;
119
120 private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
121
122 private final Iterable<HotSpotVMEventListener> vmEventListeners;
123
124 @SuppressWarnings("unused") private final String[] trivialPrefixes;
125
126 @SuppressWarnings("try")
127 private HotSpotJVMCIRuntime() {
128 compilerToVm = new CompilerToVM();
129
130 try (InitTimer t = timer("HotSpotVMConfig<init>")) {
131 config = new HotSpotVMConfig(compilerToVm);
132 }
133
134 String hostArchitecture = config.getHostArchitectureName();
135
136 HotSpotJVMCIBackendFactory factory;
137 try (InitTimer t = timer("find factory:", hostArchitecture)) {
138 factory = findFactory(hostArchitecture);
139 }
140
141 try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
142 hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
143 }
144
145 vmEventListeners = Services.load(HotSpotVMEventListener.class);
146
147 JVMCIMetaAccessContext context = null;
148 for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
149 context = vmEventListener.createMetaAccessContext(this);
150 if (context != null) {
151 break;
152 }
153 }
154 if (context == null) {
155 context = new HotSpotJVMCIMetaAccessContext();
156 }
157 metaAccessContext = context;
158
159 if (Boolean.valueOf(System.getProperty("jvmci.printconfig"))) {
160 printConfig(config, compilerToVm);
161 }
162
163 trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();
164 }
165
166 private JVMCIBackend registerBackend(JVMCIBackend backend) {
167 Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
168 JVMCIBackend oldValue = backends.put(arch, backend);
169 assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName();
170 return backend;
171 }
172
173 public ResolvedJavaType fromClass(Class<?> javaClass) {
174 return metaAccessContext.fromClass(javaClass);
175 }
176
177 public HotSpotVMConfig getConfig() {
178 return config;
179 }
180
181 public CompilerToVM getCompilerToVM() {
182 return compilerToVm;
183 }
184
185 public JVMCIMetaAccessContext getMetaAccessContext() {
186 return metaAccessContext;
187 }
188
189 public Compiler getCompiler() {
190 if (compiler == null) {
191 synchronized (this) {
192 if (compiler == null) {
193 compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
194 }
195 }
196 }
197 return compiler;
198 }
199
200 public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) {
201 Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class");
202 // If the name represents a primitive type we can short-circuit the lookup.
203 if (name.length() == 1) {
204 JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
205 return fromClass(kind.toJavaClass());
206 }
207
208 // Resolve non-primitive types in the VM.
209 HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
210 final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
211
212 if (klass == null) {
213 assert resolve == false;
214 return HotSpotUnresolvedJavaType.create(this, name);
215 }
216 return klass;
217 }
218
219 public JVMCIBackend getHostJVMCIBackend() {
220 return hostBackend;
221 }
222
223 public <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch) {
224 assert arch != Architecture.class;
225 return backends.get(arch);
226 }
227
228 public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
229 return Collections.unmodifiableMap(backends);
230 }
231
232 /**
233 * Called from the VM.
234 */
235 @SuppressWarnings({"unused"})
236 private void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
237 getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
238 }
239
240 /**
241 * Shuts down the runtime.
242 *
243 * Called from the VM.
244 */
245 @SuppressWarnings({"unused"})
246 private void shutdown() throws Exception {
247 for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
248 vmEventListener.notifyShutdown();
249 }
250 }
251
252 /**
253 * Notify on successful install into the CodeCache.
254 *
255 * @param hotSpotCodeCacheProvider
256 * @param installedCode
257 * @param compResult
258 */
259 void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) {
260 for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
261 vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compResult);
262 }
263 }
264
265 private static void printConfig(HotSpotVMConfig config, CompilerToVM vm) {
266 Field[] fields = config.getClass().getDeclaredFields();
267 Map<String, Field> sortedFields = new TreeMap<>();
268 for (Field f : fields) {
269 if (!f.isSynthetic() && !Modifier.isStatic(f.getModifiers())) {
270 f.setAccessible(true);
271 sortedFields.put(f.getName(), f);
272 }
273 }
274 for (Field f : sortedFields.values()) {
275 try {
276 String line = String.format("%9s %-40s = %s%n", f.getType().getSimpleName(), f.getName(), pretty(f.get(config)));
277 byte[] lineBytes = line.getBytes();
278 vm.writeDebugOutput(lineBytes, 0, lineBytes.length);
279 vm.flushDebugOutput();
280 } catch (Exception e) {
281 }
282 }
283 }
284
285 private static String pretty(Object value) {
286 if (value == null) {
287 return "null";
288 }
289
290 Class<?> klass = value.getClass();
291 if (value instanceof String) {
292 return "\"" + value + "\"";
293 } else if (value instanceof Method) {
294 return "method \"" + ((Method) value).getName() + "\"";
295 } else if (value instanceof Class<?>) {
296 return "class \"" + ((Class<?>) value).getSimpleName() + "\"";
297 } else if (value instanceof Integer) {
298 if ((Integer) value < 10) {
299 return value.toString();
300 }
301 return value + " (0x" + Integer.toHexString((Integer) value) + ")";
302 } else if (value instanceof Long) {
303 if ((Long) value < 10 && (Long) value > -10) {
304 return value + "l";
305 }
306 return value + "l (0x" + Long.toHexString((Long) value) + "l)";
307 } else if (klass.isArray()) {
308 StringBuilder str = new StringBuilder();
309 int dimensions = 0;
310 while (klass.isArray()) {
311 dimensions++;
312 klass = klass.getComponentType();
313 }
314 int length = Array.getLength(value);
315 str.append(klass.getSimpleName()).append('[').append(length).append(']');
316 for (int i = 1; i < dimensions; i++) {
317 str.append("[]");
318 }
319 str.append(" {");
320 for (int i = 0; i < length; i++) {
321 str.append(pretty(Array.get(value, i)));
322 if (i < length - 1) {
323 str.append(", ");
324 }
325 }
326 str.append('}');
327 return str.toString();
328 }
329 return value.toString();
330 }
331
332 public OutputStream getLogStream() {
333 return new OutputStream() {
334
335 @Override
336 public void write(byte[] b, int off, int len) throws IOException {
337 if (b == null) {
338 throw new NullPointerException();
339 } else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) {
340 throw new IndexOutOfBoundsException();
341 } else if (len == 0) {
342 return;
343 }
344 compilerToVm.writeDebugOutput(b, off, len);
345 }
346
347 @Override
348 public void write(int b) throws IOException {
349 write(new byte[]{(byte) b}, 0, 1);
350 }
351
352 @Override
353 public void flush() throws IOException {
354 compilerToVm.flushDebugOutput();
355 }
356 };
357 }
358
359 /**
360 * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
361 */
362 public long[] collectCounters() {
363 return compilerToVm.collectCounters();
364 }
365 }