author | dnsimon |
Tue, 10 May 2016 11:48:06 +0200 | |
changeset 38666 | 5ff19807abd5 |
parent 38663 | 03fe0752bb2f |
child 38674 | eacc567feae8 |
permissions | -rw-r--r-- |
33160 | 1 |
/* |
35582
c32a0cc19877
8147599: [JVMCI] simplify code installation interface
rschatz
parents:
35570
diff
changeset
|
2 |
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. |
33160 | 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 |
||
33632 | 25 |
import static jdk.vm.ci.inittimer.InitTimer.timer; |
33160 | 26 |
|
33632 | 27 |
import java.io.IOException; |
28 |
import java.io.OutputStream; |
|
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
29 |
import java.io.PrintStream; |
33632 | 30 |
import java.lang.reflect.Array; |
31 |
import java.lang.reflect.Field; |
|
32 |
import java.lang.reflect.Method; |
|
33 |
import java.lang.reflect.Modifier; |
|
34 |
import java.util.Collections; |
|
35 |
import java.util.HashMap; |
|
36 |
import java.util.Map; |
|
37 |
import java.util.Objects; |
|
38 |
import java.util.TreeMap; |
|
33160 | 39 |
|
33632 | 40 |
import jdk.vm.ci.code.Architecture; |
35592
5814f874d736
8147432: JVMCI should report bailouts in PrintCompilation output
never
parents:
35582
diff
changeset
|
41 |
import jdk.vm.ci.code.CompilationRequestResult; |
35582
c32a0cc19877
8147599: [JVMCI] simplify code installation interface
rschatz
parents:
35570
diff
changeset
|
42 |
import jdk.vm.ci.code.CompiledCode; |
33632 | 43 |
import jdk.vm.ci.code.InstalledCode; |
44 |
import jdk.vm.ci.common.JVMCIError; |
|
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
45 |
import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory; |
38663
03fe0752bb2f
8155023: jdk.vm.ci needs to securely export services
dnsimon
parents:
36594
diff
changeset
|
46 |
import jdk.vm.ci.hotspot.services.HotSpotVMEventListener; |
33632 | 47 |
import jdk.vm.ci.inittimer.InitTimer; |
35837 | 48 |
import jdk.vm.ci.inittimer.SuppressFBWarnings; |
33632 | 49 |
import jdk.vm.ci.meta.JVMCIMetaAccessContext; |
50 |
import jdk.vm.ci.meta.JavaKind; |
|
51 |
import jdk.vm.ci.meta.JavaType; |
|
52 |
import jdk.vm.ci.meta.ResolvedJavaType; |
|
53 |
import jdk.vm.ci.runtime.JVMCI; |
|
54 |
import jdk.vm.ci.runtime.JVMCIBackend; |
|
55 |
import jdk.vm.ci.runtime.JVMCICompiler; |
|
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
56 |
import jdk.vm.ci.runtime.services.JVMCICompilerFactory; |
35564
3485bf43b924
8146364: Remove @ServiceProvider mechanism from JVMCI
dnsimon
parents:
35160
diff
changeset
|
57 |
import jdk.vm.ci.services.Services; |
35234
854fc566323e
8146660: Resolve merge issue in resulting from sun.misc.VM move to jdk.internal.misc
amurillo
parents:
35160
diff
changeset
|
58 |
import jdk.internal.misc.VM; |
33160 | 59 |
|
60 |
//JaCoCo Exclude |
|
61 |
||
33632 | 62 |
/** |
63 |
* HotSpot implementation of a JVMCI runtime. |
|
64 |
* |
|
65 |
* The initialization of this class is very fragile since it's initialized both through |
|
66 |
* {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and |
|
67 |
* {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class |
|
68 |
* can't have a static initializer and any required initialization must be done as part of |
|
69 |
* {@link #runtime()}. This allows the initialization to funnel back through |
|
70 |
* {@link JVMCI#initialize()} without deadlocking. |
|
71 |
*/ |
|
33160 | 72 |
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified { |
73 |
||
74 |
@SuppressWarnings("try") |
|
75 |
static class DelayedInit { |
|
76 |
private static final HotSpotJVMCIRuntime instance; |
|
77 |
||
78 |
static { |
|
33632 | 79 |
try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) { |
80 |
instance = new HotSpotJVMCIRuntime(); |
|
33160 | 81 |
} |
82 |
} |
|
83 |
} |
|
84 |
||
85 |
/** |
|
86 |
* Gets the singleton {@link HotSpotJVMCIRuntime} object. |
|
87 |
*/ |
|
88 |
public static HotSpotJVMCIRuntime runtime() { |
|
33632 | 89 |
JVMCI.initialize(); |
33160 | 90 |
return DelayedInit.instance; |
91 |
} |
|
92 |
||
35160
acae4975b367
8146001: Remove support for command line options from JVMCI
dnsimon
parents:
33632
diff
changeset
|
93 |
/** |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
94 |
* A list of all supported JVMCI options. |
35160
acae4975b367
8146001: Remove support for command line options from JVMCI
dnsimon
parents:
33632
diff
changeset
|
95 |
*/ |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
96 |
public enum Option { |
36594
5a2cfca38c3d
8151470: [JVMCI] remove up-call to HotSpotJVMCICompilerConfig.selectCompiler
twisti
parents:
35837
diff
changeset
|
97 |
Compiler(String.class, null, "Selects the system compiler."), |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
98 |
ImplicitStableValues(boolean.class, true, "Mark well-known stable fields as such."), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
99 |
// Note: The following one is not used (see InitTimer.ENABLED). |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
100 |
InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
101 |
PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
102 |
PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
103 |
ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
104 |
TraceMethodDataFilter(String.class, null, ""), |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
105 |
TrustFinalDefaultFields(boolean.class, true, "Determines whether to treat final fields with default values as constant."); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
106 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
107 |
/** |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
108 |
* The prefix for system properties that are JVMCI options. |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
109 |
*/ |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
110 |
private static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci."; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
111 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
112 |
/** |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
113 |
* Marker for uninitialized flags. |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
114 |
*/ |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
115 |
private static final String UNINITIALIZED = "UNINITIALIZED"; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
116 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
117 |
private final Class<?> type; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
118 |
private Object value; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
119 |
private final Object defaultValue; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
120 |
private boolean isDefault; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
121 |
private final String help; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
122 |
|
35837 | 123 |
Option(Class<?> type, Object defaultValue, String help) { |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
124 |
assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
125 |
this.type = type; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
126 |
this.value = UNINITIALIZED; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
127 |
this.defaultValue = defaultValue; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
128 |
this.help = help; |
35160
acae4975b367
8146001: Remove support for command line options from JVMCI
dnsimon
parents:
33632
diff
changeset
|
129 |
} |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
130 |
|
35837 | 131 |
@SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "sentinel must be String since it's a static final in an enum") |
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
132 |
private Object getValue() { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
133 |
if (value == UNINITIALIZED) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
134 |
String propertyValue = VM.getSavedProperty(JVMCI_OPTION_PROPERTY_PREFIX + name()); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
135 |
if (propertyValue == null) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
136 |
this.value = defaultValue; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
137 |
this.isDefault = true; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
138 |
} else { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
139 |
if (type == boolean.class) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
140 |
this.value = Boolean.parseBoolean(propertyValue); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
141 |
} else if (type == String.class) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
142 |
this.value = propertyValue; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
143 |
} else { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
144 |
throw new JVMCIError("Unexpected option type " + type); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
145 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
146 |
this.isDefault = false; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
147 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
148 |
// Saved properties should not be interned - let's be sure |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
149 |
assert value != UNINITIALIZED; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
150 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
151 |
return value; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
152 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
153 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
154 |
/** |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
155 |
* Returns the option's value as boolean. |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
156 |
* |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
157 |
* @return option's value |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
158 |
*/ |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
159 |
public boolean getBoolean() { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
160 |
return (boolean) getValue(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
161 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
162 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
163 |
/** |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
164 |
* Returns the option's value as String. |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
165 |
* |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
166 |
* @return option's value |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
167 |
*/ |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
168 |
public String getString() { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
169 |
return (String) getValue(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
170 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
171 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
172 |
/** |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
173 |
* Prints all option flags to {@code out}. |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
174 |
* |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
175 |
* @param out stream to print to |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
176 |
*/ |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
177 |
public static void printFlags(PrintStream out) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
178 |
out.println("[List of JVMCI options]"); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
179 |
for (Option option : values()) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
180 |
Object value = option.getValue(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
181 |
String assign = option.isDefault ? ":=" : " ="; |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
182 |
out.printf("%9s %-40s %s %-14s %s%n", option.type.getSimpleName(), option, assign, value, option.help); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
183 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
184 |
} |
35160
acae4975b367
8146001: Remove support for command line options from JVMCI
dnsimon
parents:
33632
diff
changeset
|
185 |
} |
acae4975b367
8146001: Remove support for command line options from JVMCI
dnsimon
parents:
33632
diff
changeset
|
186 |
|
33160 | 187 |
public static HotSpotJVMCIBackendFactory findFactory(String architecture) { |
188 |
for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) { |
|
189 |
if (factory.getArchitecture().equalsIgnoreCase(architecture)) { |
|
190 |
return factory; |
|
191 |
} |
|
192 |
} |
|
193 |
||
194 |
throw new JVMCIError("No JVMCI runtime available for the %s architecture", architecture); |
|
195 |
} |
|
196 |
||
197 |
/** |
|
198 |
* Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend. |
|
199 |
*/ |
|
200 |
public static JavaKind getHostWordKind() { |
|
33632 | 201 |
return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind; |
33160 | 202 |
} |
203 |
||
204 |
protected final CompilerToVM compilerToVm; |
|
205 |
||
206 |
protected final HotSpotVMConfig config; |
|
207 |
private final JVMCIBackend hostBackend; |
|
208 |
||
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
209 |
private final JVMCICompilerFactory compilerFactory; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
210 |
private final HotSpotJVMCICompilerFactory hsCompilerFactory; |
33632 | 211 |
private volatile JVMCICompiler compiler; |
33160 | 212 |
protected final JVMCIMetaAccessContext metaAccessContext; |
213 |
||
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
214 |
/** |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
215 |
* Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
216 |
* that it can be read from the VM. |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
217 |
*/ |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
218 |
@SuppressWarnings("unused") private final int compilationLevelAdjustment; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
219 |
|
33160 | 220 |
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>(); |
221 |
||
222 |
private final Iterable<HotSpotVMEventListener> vmEventListeners; |
|
223 |
||
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
224 |
/** |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
225 |
* Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
226 |
* be read from the VM. |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
227 |
*/ |
33632 | 228 |
@SuppressWarnings("unused") private final String[] trivialPrefixes; |
229 |
||
33160 | 230 |
@SuppressWarnings("try") |
231 |
private HotSpotJVMCIRuntime() { |
|
232 |
compilerToVm = new CompilerToVM(); |
|
33632 | 233 |
|
33160 | 234 |
try (InitTimer t = timer("HotSpotVMConfig<init>")) { |
235 |
config = new HotSpotVMConfig(compilerToVm); |
|
236 |
} |
|
237 |
||
238 |
String hostArchitecture = config.getHostArchitectureName(); |
|
239 |
||
240 |
HotSpotJVMCIBackendFactory factory; |
|
241 |
try (InitTimer t = timer("find factory:", hostArchitecture)) { |
|
242 |
factory = findFactory(hostArchitecture); |
|
243 |
} |
|
244 |
||
245 |
try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) { |
|
33632 | 246 |
hostBackend = registerBackend(factory.createJVMCIBackend(this, null)); |
33160 | 247 |
} |
248 |
||
249 |
vmEventListeners = Services.load(HotSpotVMEventListener.class); |
|
250 |
||
251 |
JVMCIMetaAccessContext context = null; |
|
252 |
for (HotSpotVMEventListener vmEventListener : vmEventListeners) { |
|
253 |
context = vmEventListener.createMetaAccessContext(this); |
|
254 |
if (context != null) { |
|
255 |
break; |
|
256 |
} |
|
257 |
} |
|
258 |
if (context == null) { |
|
259 |
context = new HotSpotJVMCIMetaAccessContext(); |
|
260 |
} |
|
261 |
metaAccessContext = context; |
|
33632 | 262 |
|
35570
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
263 |
boolean printFlags = Option.PrintFlags.getBoolean(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
264 |
boolean showFlags = Option.ShowFlags.getBoolean(); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
265 |
if (printFlags || showFlags) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
266 |
Option.printFlags(System.out); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
267 |
if (printFlags) { |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
268 |
System.exit(0); |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
269 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
270 |
} |
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
271 |
|
584ae5cfe100
8146820: JVMCI options should not use System.getProperty directly
twisti
parents:
35565
diff
changeset
|
272 |
if (Option.PrintConfig.getBoolean()) { |
33632 | 273 |
printConfig(config, compilerToVm); |
274 |
} |
|
275 |
||
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
276 |
compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(); |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
277 |
if (compilerFactory instanceof HotSpotJVMCICompilerFactory) { |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
278 |
hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
279 |
trivialPrefixes = hsCompilerFactory.getTrivialPrefixes(); |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
280 |
compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config); |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
281 |
} else { |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
282 |
hsCompilerFactory = null; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
283 |
trivialPrefixes = null; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
284 |
compilationLevelAdjustment = 0; |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
285 |
} |
33160 | 286 |
} |
287 |
||
288 |
private JVMCIBackend registerBackend(JVMCIBackend backend) { |
|
289 |
Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass(); |
|
290 |
JVMCIBackend oldValue = backends.put(arch, backend); |
|
291 |
assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName(); |
|
292 |
return backend; |
|
293 |
} |
|
294 |
||
295 |
public ResolvedJavaType fromClass(Class<?> javaClass) { |
|
296 |
return metaAccessContext.fromClass(javaClass); |
|
297 |
} |
|
298 |
||
299 |
public HotSpotVMConfig getConfig() { |
|
300 |
return config; |
|
301 |
} |
|
302 |
||
303 |
public CompilerToVM getCompilerToVM() { |
|
304 |
return compilerToVm; |
|
305 |
} |
|
306 |
||
307 |
public JVMCIMetaAccessContext getMetaAccessContext() { |
|
308 |
return metaAccessContext; |
|
309 |
} |
|
310 |
||
33632 | 311 |
public JVMCICompiler getCompiler() { |
312 |
if (compiler == null) { |
|
313 |
synchronized (this) { |
|
314 |
if (compiler == null) { |
|
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
315 |
compiler = compilerFactory.createCompiler(this); |
33632 | 316 |
} |
317 |
} |
|
318 |
} |
|
33160 | 319 |
return compiler; |
320 |
} |
|
321 |
||
322 |
public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { |
|
323 |
Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class"); |
|
324 |
// If the name represents a primitive type we can short-circuit the lookup. |
|
325 |
if (name.length() == 1) { |
|
326 |
JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); |
|
327 |
return fromClass(kind.toJavaClass()); |
|
328 |
} |
|
329 |
||
330 |
// Resolve non-primitive types in the VM. |
|
331 |
HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType; |
|
332 |
final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve); |
|
333 |
||
334 |
if (klass == null) { |
|
335 |
assert resolve == false; |
|
336 |
return HotSpotUnresolvedJavaType.create(this, name); |
|
337 |
} |
|
338 |
return klass; |
|
339 |
} |
|
340 |
||
341 |
public JVMCIBackend getHostJVMCIBackend() { |
|
342 |
return hostBackend; |
|
343 |
} |
|
344 |
||
345 |
public <T extends Architecture> JVMCIBackend getJVMCIBackend(Class<T> arch) { |
|
346 |
assert arch != Architecture.class; |
|
347 |
return backends.get(arch); |
|
348 |
} |
|
349 |
||
33632 | 350 |
public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() { |
33160 | 351 |
return Collections.unmodifiableMap(backends); |
352 |
} |
|
353 |
||
354 |
/** |
|
355 |
* Called from the VM. |
|
356 |
*/ |
|
357 |
@SuppressWarnings({"unused"}) |
|
38666
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
358 |
private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) { |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
359 |
return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level); |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
360 |
} |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
361 |
|
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
362 |
/** |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
363 |
* Called from the VM. |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
364 |
*/ |
5ff19807abd5
8152311: [JVMCI] allow JVMCI compiler to change the compilation policy for a method
dnsimon
parents:
38663
diff
changeset
|
365 |
@SuppressWarnings({"unused"}) |
35592
5814f874d736
8147432: JVMCI should report bailouts in PrintCompilation output
never
parents:
35582
diff
changeset
|
366 |
private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) { |
5814f874d736
8147432: JVMCI should report bailouts in PrintCompilation output
never
parents:
35582
diff
changeset
|
367 |
CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id)); |
5814f874d736
8147432: JVMCI should report bailouts in PrintCompilation output
never
parents:
35582
diff
changeset
|
368 |
assert result != null : "compileMethod must always return something"; |
5814f874d736
8147432: JVMCI should report bailouts in PrintCompilation output
never
parents:
35582
diff
changeset
|
369 |
return result; |
33160 | 370 |
} |
371 |
||
372 |
/** |
|
373 |
* Shuts down the runtime. |
|
374 |
* |
|
375 |
* Called from the VM. |
|
376 |
*/ |
|
377 |
@SuppressWarnings({"unused"}) |
|
378 |
private void shutdown() throws Exception { |
|
379 |
for (HotSpotVMEventListener vmEventListener : vmEventListeners) { |
|
380 |
vmEventListener.notifyShutdown(); |
|
381 |
} |
|
382 |
} |
|
383 |
||
384 |
/** |
|
385 |
* Notify on successful install into the CodeCache. |
|
386 |
* |
|
387 |
* @param hotSpotCodeCacheProvider |
|
388 |
* @param installedCode |
|
35582
c32a0cc19877
8147599: [JVMCI] simplify code installation interface
rschatz
parents:
35570
diff
changeset
|
389 |
* @param compiledCode |
33160 | 390 |
*/ |
35582
c32a0cc19877
8147599: [JVMCI] simplify code installation interface
rschatz
parents:
35570
diff
changeset
|
391 |
void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) { |
33160 | 392 |
for (HotSpotVMEventListener vmEventListener : vmEventListeners) { |
35582
c32a0cc19877
8147599: [JVMCI] simplify code installation interface
rschatz
parents:
35570
diff
changeset
|
393 |
vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compiledCode); |
33160 | 394 |
} |
395 |
} |
|
33632 | 396 |
|
397 |
private static void printConfig(HotSpotVMConfig config, CompilerToVM vm) { |
|
398 |
Field[] fields = config.getClass().getDeclaredFields(); |
|
399 |
Map<String, Field> sortedFields = new TreeMap<>(); |
|
400 |
for (Field f : fields) { |
|
401 |
if (!f.isSynthetic() && !Modifier.isStatic(f.getModifiers())) { |
|
402 |
f.setAccessible(true); |
|
403 |
sortedFields.put(f.getName(), f); |
|
404 |
} |
|
405 |
} |
|
406 |
for (Field f : sortedFields.values()) { |
|
407 |
try { |
|
408 |
String line = String.format("%9s %-40s = %s%n", f.getType().getSimpleName(), f.getName(), pretty(f.get(config))); |
|
409 |
byte[] lineBytes = line.getBytes(); |
|
410 |
vm.writeDebugOutput(lineBytes, 0, lineBytes.length); |
|
411 |
vm.flushDebugOutput(); |
|
412 |
} catch (Exception e) { |
|
413 |
} |
|
414 |
} |
|
415 |
} |
|
416 |
||
417 |
private static String pretty(Object value) { |
|
418 |
if (value == null) { |
|
419 |
return "null"; |
|
420 |
} |
|
421 |
||
422 |
Class<?> klass = value.getClass(); |
|
423 |
if (value instanceof String) { |
|
424 |
return "\"" + value + "\""; |
|
425 |
} else if (value instanceof Method) { |
|
426 |
return "method \"" + ((Method) value).getName() + "\""; |
|
427 |
} else if (value instanceof Class<?>) { |
|
428 |
return "class \"" + ((Class<?>) value).getSimpleName() + "\""; |
|
429 |
} else if (value instanceof Integer) { |
|
430 |
if ((Integer) value < 10) { |
|
431 |
return value.toString(); |
|
432 |
} |
|
433 |
return value + " (0x" + Integer.toHexString((Integer) value) + ")"; |
|
434 |
} else if (value instanceof Long) { |
|
435 |
if ((Long) value < 10 && (Long) value > -10) { |
|
436 |
return value + "l"; |
|
437 |
} |
|
438 |
return value + "l (0x" + Long.toHexString((Long) value) + "l)"; |
|
439 |
} else if (klass.isArray()) { |
|
440 |
StringBuilder str = new StringBuilder(); |
|
441 |
int dimensions = 0; |
|
442 |
while (klass.isArray()) { |
|
443 |
dimensions++; |
|
444 |
klass = klass.getComponentType(); |
|
445 |
} |
|
446 |
int length = Array.getLength(value); |
|
447 |
str.append(klass.getSimpleName()).append('[').append(length).append(']'); |
|
448 |
for (int i = 1; i < dimensions; i++) { |
|
449 |
str.append("[]"); |
|
450 |
} |
|
451 |
str.append(" {"); |
|
452 |
for (int i = 0; i < length; i++) { |
|
453 |
str.append(pretty(Array.get(value, i))); |
|
454 |
if (i < length - 1) { |
|
455 |
str.append(", "); |
|
456 |
} |
|
457 |
} |
|
458 |
str.append('}'); |
|
459 |
return str.toString(); |
|
460 |
} |
|
461 |
return value.toString(); |
|
462 |
} |
|
463 |
||
464 |
public OutputStream getLogStream() { |
|
465 |
return new OutputStream() { |
|
466 |
||
467 |
@Override |
|
468 |
public void write(byte[] b, int off, int len) throws IOException { |
|
469 |
if (b == null) { |
|
470 |
throw new NullPointerException(); |
|
471 |
} else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) { |
|
472 |
throw new IndexOutOfBoundsException(); |
|
473 |
} else if (len == 0) { |
|
474 |
return; |
|
475 |
} |
|
476 |
compilerToVm.writeDebugOutput(b, off, len); |
|
477 |
} |
|
478 |
||
479 |
@Override |
|
480 |
public void write(int b) throws IOException { |
|
481 |
write(new byte[]{(byte) b}, 0, 1); |
|
482 |
} |
|
483 |
||
484 |
@Override |
|
485 |
public void flush() throws IOException { |
|
486 |
compilerToVm.flushDebugOutput(); |
|
487 |
} |
|
488 |
}; |
|
489 |
} |
|
490 |
||
491 |
/** |
|
492 |
* Collects the current values of all JVMCI benchmark counters, summed up over all threads. |
|
493 |
*/ |
|
494 |
public long[] collectCounters() { |
|
495 |
return compilerToVm.collectCounters(); |
|
496 |
} |
|
33160 | 497 |
} |