use of jdk.vm.ci.meta.ConstantPool in project graal by oracle.
the class CEntryPointCallStubMethod method create.
static CEntryPointCallStubMethod create(AnalysisMethod targetMethod, CEntryPointData entryPointData, AnalysisMetaAccess metaAccess) {
ResolvedJavaMethod unwrappedMethod = targetMethod.getWrapped();
MetaAccessProvider unwrappedMetaAccess = metaAccess.getWrapped();
ResolvedJavaType declaringClass = unwrappedMetaAccess.lookupJavaType(CEntryPointCallStubs.class);
ConstantPool constantPool = CEntryPointCallStubs.getConstantPool(unwrappedMetaAccess);
return new CEntryPointCallStubMethod(entryPointData, unwrappedMethod, declaringClass, constantPool);
}
use of jdk.vm.ci.meta.ConstantPool in project graal by oracle.
the class CompileTheWorld method compile.
/**
* Compiles all methods in all classes in a given class path.
*
* @param classPath class path denoting classes to compile
* @throws IOException
*/
@SuppressWarnings("try")
private void compile(String classPath) throws IOException {
final String[] entries = classPath.split(File.pathSeparator);
long start = System.currentTimeMillis();
Map<Thread, StackTraceElement[]> initialThreads = Thread.getAllStackTraces();
try {
// compile dummy method to get compiler initialized outside of the
// config debug override.
HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod(CompileTheWorld.class.getDeclaredMethod("dummy"));
int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
boolean useProfilingInfo = false;
boolean installAsDefault = false;
CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), useProfilingInfo, installAsDefault, currentOptions);
task.runCompilation();
} catch (NoSuchMethodException | SecurityException e1) {
printStackTrace(e1);
}
/*
* Always use a thread pool, even for single threaded mode since it simplifies the use of
* DebugValueThreadFilter to filter on the thread names.
*/
int threadCount = 1;
if (Options.MultiThreaded.getValue(currentOptions)) {
threadCount = Options.Threads.getValue(currentOptions);
if (threadCount == 0) {
threadCount = Runtime.getRuntime().availableProcessors();
}
} else {
running = true;
}
OptionValues savedOptions = currentOptions;
currentOptions = new OptionValues(compilationOptions);
threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new CompilerThreadFactory("CompileTheWorld"));
try {
for (int i = 0; i < entries.length; i++) {
final String entry = entries[i];
ClassPathEntry cpe;
if (entry.endsWith(".zip") || entry.endsWith(".jar")) {
cpe = new JarClassPathEntry(entry);
} else if (entry.equals(JRT_CLASS_PATH_ENTRY)) {
cpe = new JRTClassPathEntry(entry, Options.LimitModules.getValue(currentOptions));
} else {
if (!new File(entry).isDirectory()) {
println("CompileTheWorld : Skipped classes in " + entry);
println();
continue;
}
cpe = new DirClassPathEntry(entry);
}
if (methodFilters == null || methodFilters.length == 0) {
println("CompileTheWorld : Compiling all classes in " + entry);
} else {
String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", "));
println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include);
}
if (excludeMethodFilters != null && excludeMethodFilters.length > 0) {
String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", "));
println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude);
}
println();
ClassLoader loader = cpe.createClassLoader();
for (String className : cpe.getClassNames()) {
// Are we done?
if (classFileCounter >= stopAt) {
break;
}
classFileCounter++;
if (className.startsWith("jdk.management.") || className.startsWith("jdk.internal.cmm.*") || // These threads tend to cause deadlock at VM exit
className.startsWith("sun.tools.jconsole.")) {
continue;
}
if (!isClassIncluded(className)) {
continue;
}
try {
// Load and initialize class
Class<?> javaClass = Class.forName(className, true, loader);
// Pre-load all classes in the constant pool.
try {
HotSpotResolvedObjectType objectType = HotSpotResolvedObjectType.fromObjectClass(javaClass);
ConstantPool constantPool = objectType.getConstantPool();
for (int cpi = 1; cpi < constantPool.length(); cpi++) {
constantPool.loadReferencedType(cpi, Bytecodes.LDC);
}
} catch (Throwable t) {
// If something went wrong during pre-loading we just ignore it.
if (isClassIncluded(className)) {
println("Preloading failed for (%d) %s: %s", classFileCounter, className, t);
}
continue;
}
// Are we compiling this class?
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
if (classFileCounter >= startAt) {
println("CompileTheWorld (%d) : %s", classFileCounter, className);
// Compile each constructor/method in the class.
for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor);
if (canBeCompiled(javaMethod, constructor.getModifiers())) {
compileMethod(javaMethod);
}
}
for (Method method : javaClass.getDeclaredMethods()) {
HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
if (canBeCompiled(javaMethod, method.getModifiers())) {
compileMethod(javaMethod);
}
}
// Also compile the class initializer if it exists
HotSpotResolvedJavaMethod clinit = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaType(javaClass).getClassInitializer();
if (clinit != null && canBeCompiled(clinit, clinit.getModifiers())) {
compileMethod(clinit);
}
}
} catch (Throwable t) {
if (isClassIncluded(className)) {
println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString());
printStackTrace(t);
}
}
}
cpe.close();
}
} finally {
currentOptions = savedOptions;
}
if (!running) {
startThreads();
}
int wakeups = 0;
while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) {
if (wakeups % 15 == 0) {
TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles");
}
try {
threadPool.awaitTermination(1, TimeUnit.SECONDS);
wakeups++;
} catch (InterruptedException e) {
}
}
threadPool = null;
long elapsedTime = System.currentTimeMillis() - start;
println();
if (Options.MultiThreaded.getValue(currentOptions)) {
TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, compileTime.get(), memoryUsed.get());
} else {
TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get());
}
// Apart from the main thread, there should be only be daemon threads
// alive now. If not, then a class initializer has probably started
// a thread that could cause a deadlock while trying to exit the VM.
// One known example of this is sun.tools.jconsole.OutputViewer which
// spawns threads to redirect sysout and syserr. To help debug such
// scenarios, the stacks of potentially problematic threads are dumped.
Map<Thread, StackTraceElement[]> suspiciousThreads = new HashMap<>();
for (Map.Entry<Thread, StackTraceElement[]> e : Thread.getAllStackTraces().entrySet()) {
Thread thread = e.getKey();
if (thread != Thread.currentThread() && !initialThreads.containsKey(thread) && !thread.isDaemon() && thread.isAlive()) {
suspiciousThreads.put(thread, e.getValue());
}
}
if (!suspiciousThreads.isEmpty()) {
TTY.println("--- Non-daemon threads started during CTW ---");
for (Map.Entry<Thread, StackTraceElement[]> e : suspiciousThreads.entrySet()) {
Thread thread = e.getKey();
if (thread.isAlive()) {
TTY.println(thread.toString() + " " + thread.getState());
for (StackTraceElement ste : e.getValue()) {
TTY.println("\tat " + ste);
}
}
}
TTY.println("---------------------------------------------");
}
}
use of jdk.vm.ci.meta.ConstantPool in project graal by oracle.
the class JNIFunctionTablesFeature method beforeAnalysis.
@Override
public void beforeAnalysis(BeforeAnalysisAccess arg) {
BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) arg;
AnalysisMetaAccess metaAccess = access.getMetaAccess();
JNIFunctionTables.create();
NativeLibraries nativeLibraries = access.getNativeLibraries();
AnalysisType invokeInterface = metaAccess.lookupJavaType(JNIInvokeInterface.class);
invokeInterfaceMetadata = (StructInfo) nativeLibraries.findElementInfo(invokeInterface);
AnalysisType functionTable = metaAccess.lookupJavaType(JNINativeInterface.class);
functionTableMetadata = (StructInfo) nativeLibraries.findElementInfo(functionTable);
// Manually add functions as entry points so this is only done when JNI features are enabled
AnalysisType invokes = metaAccess.lookupJavaType(JNIInvocationInterface.class);
AnalysisType exports = metaAccess.lookupJavaType(JNIInvocationInterface.Exports.class);
AnalysisType functions = metaAccess.lookupJavaType(JNIFunctions.class);
Stream<AnalysisMethod> analysisMethods = Stream.of(invokes, functions, exports).flatMap(t -> Stream.of(t.getDeclaredMethods()));
Stream<AnalysisMethod> unimplementedMethods = Stream.of((AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJNIEnvArgument.class), (AnalysisMethod) getSingleMethod(metaAccess, UnimplementedWithJavaVMArgument.class));
Stream.concat(analysisMethods, unimplementedMethods).forEach(method -> {
CEntryPoint annotation = method.getAnnotation(CEntryPoint.class);
assert annotation != null : "only entry points allowed in class";
CEntryPointCallStubSupport.singleton().registerStubForMethod(method, () -> CEntryPointData.create(method));
});
ArrayList<ResolvedJavaMethod> generated = new ArrayList<>();
MetaAccessProvider wrappedMetaAccess = metaAccess.getWrapped();
ResolvedJavaType generatedMethodClass = wrappedMetaAccess.lookupJavaType(JNIFunctions.class);
ConstantPool constantPool = generatedMethodClass.getDeclaredMethods()[0].getConstantPool();
// Generate JNI field accessors
EnumSet<JavaKind> fldKinds = jniKinds.clone();
fldKinds.remove(JavaKind.Void);
for (JavaKind kind : fldKinds) {
boolean[] trueFalse = { true, false };
for (boolean isSetter : trueFalse) {
for (boolean isStatic : trueFalse) {
JNIFieldAccessorMethod method = new JNIFieldAccessorMethod(kind, isSetter, isStatic, generatedMethodClass, constantPool, wrappedMetaAccess);
AnalysisMethod analysisMethod = access.getUniverse().lookup(method);
access.getBigBang().addRootMethod(analysisMethod).registerAsEntryPoint(method.createEntryPointData());
generated.add(method);
}
}
}
// Generate JNI primitive array operations
EnumSet<JavaKind> primitiveArrayKinds = jniKinds.clone();
primitiveArrayKinds.remove(JavaKind.Void);
primitiveArrayKinds.remove(JavaKind.Object);
for (JavaKind kind : primitiveArrayKinds) {
for (Operation op : Operation.values()) {
JNIPrimitiveArrayOperationMethod method = new JNIPrimitiveArrayOperationMethod(kind, op, generatedMethodClass, constantPool, wrappedMetaAccess);
AnalysisMethod analysisMethod = access.getUniverse().lookup(method);
access.getBigBang().addRootMethod(analysisMethod).registerAsEntryPoint(method.createEntryPointData());
generated.add(method);
}
}
generatedMethods = generated.toArray(new ResolvedJavaMethod[0]);
}
use of jdk.vm.ci.meta.ConstantPool in project graal by oracle.
the class BridgeMethodUtils method getBridgedMethod.
/**
* Gets the method bridged to by a {@linkplain ResolvedJavaMethod#isBridge() bridge} method. The
* value returned is the method called by {@code method} that has the same name as
* {@code bridge}.
*
* @param bridge a bridge method
* @return the method called by {@code bridge} whose name is the same as
* {@code bridge.getName()}
*/
public static ResolvedJavaMethod getBridgedMethod(ResolvedJavaMethod bridge) {
assert bridge.isBridge();
Bytecode code = new ResolvedJavaMethodBytecode(bridge);
BytecodeStream stream = new BytecodeStream(code.getCode());
int opcode = stream.currentBC();
ResolvedJavaMethod bridged = null;
boolean calledAbstractMethodErrorConstructor = false;
while (opcode != Bytecodes.END) {
switch(opcode) {
case INVOKEVIRTUAL:
case INVOKESPECIAL:
case INVOKESTATIC:
case INVOKEINTERFACE:
{
int cpi = stream.readCPI();
ConstantPool cp = code.getConstantPool();
cp.loadReferencedType(cpi, opcode);
ResolvedJavaMethod method = (ResolvedJavaMethod) cp.lookupMethod(cpi, opcode);
if (method.getName().equals(bridge.getName())) {
if (!assertionsEnabled()) {
return method;
}
assert bridged == null || bridged.equals(method) : String.format("Found calls to different methods named %s in bridge method %s%n callee 1: %s%n callee 2: %s", bridge.getName(), bridge.format("%R %H.%n(%P)"), bridged.format("%R %H.%n(%P)"), method.format("%R %H.%n(%P)"));
bridged = method;
} else if (method.getName().equals("<init>") && method.getDeclaringClass().getName().equals("Ljava/lang/AbstractMethodError;")) {
calledAbstractMethodErrorConstructor = true;
}
break;
}
case ATHROW:
{
if (calledAbstractMethodErrorConstructor) {
// This is a miranda method
return null;
}
}
}
stream.next();
opcode = stream.currentBC();
}
if (bridged == null) {
String dis = new BytecodeDisassembler().disassemble(bridge);
throw new InternalError(String.format("Couldn't find method bridged by %s:%n%s", bridge.format("%R %H.%n(%P)"), dis));
}
return bridged;
}
use of jdk.vm.ci.meta.ConstantPool in project graal by oracle.
the class BytecodeDisassembler method getInvokedMethodAt.
public static JavaMethod getInvokedMethodAt(ResolvedJavaMethod method, int invokeBci) {
if (method.getCode() == null) {
return null;
}
ConstantPool cp = method.getConstantPool();
BytecodeStream stream = new BytecodeStream(method.getCode());
int opcode = stream.currentBC();
while (opcode != Bytecodes.END) {
int bci = stream.currentBCI();
if (bci == invokeBci) {
if (stream.nextBCI() > bci + 1) {
switch(opcode) {
case INVOKEVIRTUAL:
case INVOKESPECIAL:
case INVOKESTATIC:
{
int cpi = stream.readCPI();
JavaMethod callee = cp.lookupMethod(cpi, opcode);
return callee;
}
case INVOKEINTERFACE:
{
int cpi = stream.readCPI();
JavaMethod callee = cp.lookupMethod(cpi, opcode);
return callee;
}
case INVOKEDYNAMIC:
{
int cpi = stream.readCPI4();
JavaMethod callee = cp.lookupMethod(cpi, opcode);
return callee;
}
default:
throw new InternalError(BytecodeDisassembler.disassembleOne(method, invokeBci));
}
}
}
stream.next();
opcode = stream.currentBC();
}
return null;
}
Aggregations