# HG changeset patch # User Gilles Duboscq # Date 1434643759 -7200 # Node ID 3904e33db5b3192d528e2c7f762311e26f514e4c # Parent 53b4acee50f15a0b3596577bf9f22f7a43382b08 Make sure HotSpotConstantPool.loadReferencedType resolves invokehandle call sites properly. Fixes eager resolution problems at those call sites. diff -r 53b4acee50f1 -r 3904e33db5b3 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MethodHandleEagerResolution.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MethodHandleEagerResolution.java Thu Jun 18 18:09:19 2015 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.test; + +import java.lang.invoke.*; +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.*; + +public final class MethodHandleEagerResolution extends GraalCompilerTest { + private static final MethodHandle FIELD_HANDLE; + + static { + Field field; + try { + field = String.class.getDeclaredField("value"); + } catch (NoSuchFieldException ex) { + throw new RuntimeException(ex.getMessage(), ex); + } + field.setAccessible(true); + + try { + FIELD_HANDLE = MethodHandles.lookup().unreflectGetter(field); + } catch (IllegalAccessException e) { + throw new RuntimeException("unable to initialize field handle", e); + } + } + + public static char[] getBackingCharArray(String str) { + try { + return (char[]) FIELD_HANDLE.invokeExact(str); + } catch (Throwable e) { + throw new IllegalStateException(); + } + } + + @Test + public void testFieldInvokeExact() { + StructuredGraph graph = parseEager("getBackingCharArray", AllowAssumptions.NO); + assertTrue(graph.getNodes().filter(DeoptimizeNode.class).isEmpty()); + } + +} diff -r 53b4acee50f1 -r 3904e33db5b3 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVM.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVM.java Thu Jun 18 17:44:47 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVM.java Thu Jun 18 18:09:19 2015 +0200 @@ -332,6 +332,8 @@ void resolveInvokeDynamic(long metaspaceConstantPool, int index); + void resolveInvokeHandle(long metaspaceConstantPool, int index); + int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod); boolean shouldDebugNonSafepoints(); diff -r 53b4acee50f1 -r 3904e33db5b3 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVMImpl.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVMImpl.java Thu Jun 18 17:44:47 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilerToVMImpl.java Thu Jun 18 18:09:19 2015 +0200 @@ -196,6 +196,8 @@ public native void resolveInvokeDynamic(long metaspaceConstantPool, int index); + public native void resolveInvokeHandle(long metaspaceConstantPool, int index); + public native int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod); public native boolean shouldDebugNonSafepoints(); diff -r 53b4acee50f1 -r 3904e33db5b3 jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java Thu Jun 18 17:44:47 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java Thu Jun 18 18:09:19 2015 +0200 @@ -118,6 +118,7 @@ */ static class TagValueMap { private static final JVM_CONSTANT[] table = new JVM_CONSTANT[ExternalMax + 1 + (InternalMax - InternalMin) + 1]; + static { assert InternalMin > ExternalMax; for (JVM_CONSTANT e : values()) { @@ -616,9 +617,12 @@ assert getTagAt(index - 1) == JVM_CONSTANT.Double || getTagAt(index - 1) == JVM_CONSTANT.Long; return; } + int methodRefCacheIndex = -1; switch (tag) { + case MethodRef: + methodRefCacheIndex = toConstantPoolIndex(cpi, opcode); + // fall through case Fieldref: - case MethodRef: case InterfaceMethodref: index = getUncachedKlassRefIndexAt(index); tag = getTagAt(index); @@ -633,6 +637,9 @@ if (!klass.isPrimitive() && !klass.isArray()) { unsafe.ensureClassInitialized(klass); } + if (methodRefCacheIndex != -1 && isInvokeHandle(methodRefCacheIndex, type)) { + runtime().getCompilerToVM().resolveInvokeHandle(metaspaceConstantPool, methodRefCacheIndex); + } break; case InvokeDynamic: if (isInvokedynamicIndex(cpi)) { @@ -645,6 +652,11 @@ } } + private boolean isInvokeHandle(int methodRefCpi, HotSpotResolvedObjectTypeImpl klass) { + assert getTagAt(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, methodRefCpi)) == JVM_CONSTANT.MethodRef; + return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameRefAt(methodRefCpi), runtime().getHostJVMCIBackend().getMetaAccess()); + } + @Override public String toString() { HotSpotResolvedObjectType holder = getHolder(); diff -r 53b4acee50f1 -r 3904e33db5b3 src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Jun 18 17:44:47 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Jun 18 18:09:19 2015 +0200 @@ -916,6 +916,14 @@ cp_cache_entry->set_dynamic_call(cp, callInfo); C2V_END +C2V_VMENTRY(void, resolveInvokeHandle, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index)) + ConstantPool* cp = (ConstantPool*)metaspace_constant_pool; + CallInfo callInfo; + LinkResolver::resolve_invokehandle(callInfo, cp, index, CHECK); + ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index)); + cp_cache_entry->set_method_handle(cp, callInfo); +C2V_END + C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject)) //see compute_recording_non_safepoints in debugInfroRec.cpp if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) { @@ -1076,6 +1084,7 @@ {CC"constantPoolRemapInstructionOperandFromCache", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, {CC"resolveField", CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS, FN_PTR(resolveField)}, {CC"resolveInvokeDynamic", CC"("METASPACE_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeDynamic)}, + {CC"resolveInvokeHandle", CC"("METASPACE_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeHandle)}, {CC"resolveMethod", CC"("METASPACE_KLASS METASPACE_METHOD METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(resolveMethod)}, {CC"getVtableIndexForInterface", CC"("METASPACE_KLASS METASPACE_METHOD")I", FN_PTR(getVtableIndexForInterface)}, {CC"getClassInitializer", CC"("METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(getClassInitializer)},