001/*
002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023
024package jdk.internal.jvmci.hotspot;
025
026import jdk.internal.jvmci.code.*;
027import jdk.internal.jvmci.hotspotvmconfig.*;
028import jdk.internal.jvmci.meta.*;
029import sun.misc.*;
030
031/**
032 * Calls from Java into HotSpot.
033 */
034public interface CompilerToVM {
035
036    /**
037     * Copies the original bytecode of a given method into a new byte array and returns it.
038     *
039     * @param metaspaceMethod the metaspace Method object
040     * @return a new byte array containing the original bytecode
041     */
042    byte[] getBytecode(long metaspaceMethod);
043
044    int exceptionTableLength(long metaspaceMethod);
045
046    long exceptionTableStart(long metaspaceMethod);
047
048    /**
049     * Determines if a given metaspace Method object has balanced monitors.
050     *
051     * @param metaspaceMethod the metaspace Method object to query
052     * @return true if the method has balanced monitors
053     */
054    boolean hasBalancedMonitors(long metaspaceMethod);
055
056    /**
057     * Determines if a given metaspace Method can be inlined. A method may not be inlinable for a
058     * number of reasons such as:
059     * <ul>
060     * <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
061     * <li>the method may have a bytecode breakpoint set</li>
062     * <li>the method may have other bytecode features that require special handling by the VM</li>
063     * </ul>
064     *
065     * @param metaspaceMethod the metaspace Method object to query
066     * @return true if the method can be inlined
067     */
068    boolean canInlineMethod(long metaspaceMethod);
069
070    /**
071     * Determines if a given metaspace Method should be inlined at any cost. This could be because:
072     * <ul>
073     * <li>a CompileOracle directive may forces inlining of this methods</li>
074     * <li>an annotation forces inlining of this method</li>
075     * </ul>
076     *
077     * @param metaspaceMethod the metaspace Method object to query
078     * @return true if the method should be inlined
079     */
080    boolean shouldInlineMethod(long metaspaceMethod);
081
082    /**
083     * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
084     *
085     * @param metaspaceMethod the metaspace Method on which to based the search
086     * @param actualHolderMetaspaceKlass the best known type of receiver
087     * @return the metaspace Method result or 0 is there is no unique concrete method for
088     *         {@code metaspaceMethod}
089     */
090    long findUniqueConcreteMethod(long actualHolderMetaspaceKlass, long metaspaceMethod);
091
092    /**
093     * Returns the implementor for the given interface class, if there is a single implementor.
094     *
095     * @param metaspaceKlass the metaspace klass to get the implementor for
096     * @return the implementor as metaspace klass pointer if there is a single implementor, null if
097     *         there is no implementor, or the input metaspace klass pointer ({@code metaspaceKlass}
098     *         ) itself if there is more than one implementor.
099     */
100    long getKlassImplementor(long metaspaceKlass);
101
102    /**
103     * Determines if a given metaspace method is ignored by security stack walks.
104     *
105     * @param metaspaceMethod the metaspace Method object
106     * @return true if the method is ignored
107     */
108    boolean methodIsIgnoredBySecurityStackWalk(long metaspaceMethod);
109
110    /**
111     * Converts a name to a metaspace klass.
112     *
113     * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
114     * @param accessingClass the context of resolution (must not be null)
115     * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
116     *            either return a {@link ResolvedJavaType} or throw an exception
117     * @return a metaspace klass for {@code name}
118     * @throws LinkageError if {@code resolve == true} and the resolution failed
119     */
120    long lookupType(String name, Class<?> accessingClass, boolean resolve);
121
122    Object resolveConstantInPool(long metaspaceConstantPool, int cpi);
123
124    Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi);
125
126    int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi);
127
128    String lookupNameRefInPool(long metaspaceConstantPool, int cpi);
129
130    String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
131
132    int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi);
133
134    long constantPoolKlassAt(long metaspaceConstantPool, int cpi);
135
136    /**
137     * Looks up a class entry in a constant pool.
138     *
139     * @param metaspaceConstantPool metaspace constant pool pointer
140     * @param cpi constant pool index
141     * @return a metaspace Klass for a resolved method entry, a metaspace Symbol otherwise (with
142     *         tagging)
143     */
144    long lookupKlassInPool(long metaspaceConstantPool, int cpi);
145
146    /**
147     * Looks up a method entry in a constant pool.
148     *
149     * @param metaspaceConstantPool metaspace constant pool pointer
150     * @param cpi constant pool index
151     * @return a metaspace Method for a resolved method entry, 0 otherwise
152     */
153    long lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
154
155    /**
156     * Looks up a field entry in a constant pool and attempts to resolve it. The values returned in
157     * {@code info} are:
158     *
159     * <pre>
160     *     [(int) flags,   // only valid if field is resolved
161     *      (int) offset]  // only valid if field is resolved
162     * </pre>
163     *
164     * @param metaspaceConstantPool metaspace constant pool pointer
165     * @param cpi constant pool index
166     * @param info an array in which the details of the field are returned
167     * @return true if the field is resolved
168     */
169    long resolveField(long metaspaceConstantPool, int cpi, byte opcode, long[] info);
170
171    int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi);
172
173    Object lookupAppendixInPool(long metaspaceConstantPool, int cpi);
174
175    /**
176     * Installs the result of a compilation into the code cache.
177     *
178     * @param compiledCode the result of a compilation
179     * @param code the details of the installed CodeBlob are written to this object
180     * @return the outcome of the installation which will be one of
181     *         {@link HotSpotVMConfig#codeInstallResultOk},
182     *         {@link HotSpotVMConfig#codeInstallResultCacheFull},
183     *         {@link HotSpotVMConfig#codeInstallResultCodeTooLarge},
184     *         {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
185     *         {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
186     */
187    int installCode(HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
188
189    /**
190     * Notifies the VM of statistics for a completed compilation.
191     *
192     * @param id the identifier of the compilation
193     * @param method the method compiled
194     * @param osr specifies if the compilation was for on-stack-replacement
195     * @param processedBytecodes the number of bytecodes processed during the compilation, including
196     *            the bytecodes of all inlined methods
197     * @param time the amount time spent compiling {@code method}
198     * @param timeUnitsPerSecond the granularity of the units for the {@code time} value
199     * @param installedCode the nmethod installed as a result of the compilation
200     */
201    void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode);
202
203    void resetCompilationStatistics();
204
205    void initializeConfiguration(HotSpotVMConfig config);
206
207    long resolveMethod(long metaspaceKlassExactReceiver, long metaspaceMethod, long metaspaceKlassCaller);
208
209    long getClassInitializer(long metaspaceKlass);
210
211    boolean hasFinalizableSubclass(long metaspaceKlass);
212
213    /**
214     * Gets the metaspace Method object corresponding to a given {@link Class} object and slot
215     * number.
216     *
217     * @param holder method holder
218     * @param slot slot number of the method
219     * @return the metaspace Method
220     */
221    long getMetaspaceMethod(Class<?> holder, int slot);
222
223    long getMaxCallTargetOffset(long address);
224
225    String disassembleCodeBlob(long codeBlob);
226
227    StackTraceElement getStackTraceElement(long metaspaceMethod, int bci);
228
229    Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, InstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
230
231    Object executeCompiledMethodVarargs(Object[] args, InstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
232
233    long[] getLineNumberTable(long metaspaceMethod);
234
235    long getLocalVariableTableStart(long metaspaceMethod);
236
237    int getLocalVariableTableLength(long metaspaceMethod);
238
239    String getFileName(HotSpotResolvedJavaType method);
240
241    Class<?> getJavaMirror(long metaspaceKlass);
242
243    long readUnsafeKlassPointer(Object o);
244
245    /**
246     * Reads an object pointer within a VM data structure. That is, any {@link HotSpotVMField} whose
247     * {@link HotSpotVMField#type() type} is {@code "oop"} (e.g.,
248     * {@code ArrayKlass::_component_mirror}, {@code Klass::_java_mirror},
249     * {@code JavaThread::_threadObj}).
250     *
251     * Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
252     * {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
253     * structures are (currently) always uncompressed.
254     *
255     * @param address address of an oop field within a VM data structure
256     */
257    Object readUncompressedOop(long address);
258
259    void doNotInlineOrCompile(long metaspaceMethod);
260
261    /**
262     * Invalidates the profiling information and restarts profiling upon the next invocation.
263     *
264     * @param metaspaceMethod the metaspace Method object
265     */
266    void reprofile(long metaspaceMethod);
267
268    void invalidateInstalledCode(InstalledCode hotspotInstalledCode);
269
270    /**
271     * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
272     */
273    long[] collectCounters();
274
275    boolean isMature(long metaspaceMethodData);
276
277    /**
278     * Generate a unique id to identify the result of the compile.
279     */
280    int allocateCompileId(long metaspaceMethod, int entryBCI);
281
282    /**
283     * Gets the names of the supported GPU architectures.
284     *
285     * @return a comma separated list of names
286     */
287    String getGPUs();
288
289    /**
290     *
291     * @param metaspaceMethod the method to check
292     * @param entryBCI
293     * @param level the compilation level
294     * @return true if the {@code metaspaceMethod} has code for {@code level}
295     */
296    boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level);
297
298    /**
299     * Fetch the time stamp used for printing inside hotspot. It's relative to VM start to that all
300     * events can be ordered.
301     *
302     * @return milliseconds since VM start
303     */
304    long getTimeStamp();
305
306    /**
307     * Gets the value of a metaspace {@code Symbol} as a String.
308     *
309     * @param metaspaceSymbol
310     */
311    String getSymbol(long metaspaceSymbol);
312
313    /**
314     * Looks for the next Java stack frame with the given method.
315     *
316     * @param frame the starting point of the search, where {@code null} refers to the topmost frame
317     * @param methods the metaspace methods to look for, where {@code null} means that any frame is
318     *            returned
319     * @return the frame, or {@code null} if the end of the stack was reached during the search
320     */
321    HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods, int initialSkip);
322
323    /**
324     * Materialized all virtual objects within the given stack frame and update the locals within
325     * the given stackFrame object.
326     *
327     * @param invalidate if {@code true}, the compiled method for the stack frame will be
328     *            invalidated.
329     */
330    void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
331
332    void resolveInvokeDynamic(long metaspaceConstantPool, int index);
333
334    void resolveInvokeHandle(long metaspaceConstantPool, int index);
335
336    int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod);
337
338    boolean shouldDebugNonSafepoints();
339
340    void writeDebugOutput(byte[] bytes, int offset, int length);
341
342    void flushDebugOutput();
343}