# HG changeset patch # User Doug Simon # Date 1365709394 -7200 # Node ID 23762f2438b65d576b60259aaec7f7ad6b164fc4 # Parent 08a16c26907f211e934dbde10d3ad4d423c3822a support for compiling LambdaForm invocations (invokevirtual instructions that were rewritten to invokehandle instructions) diff -r 08a16c26907f -r 23762f2438b6 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Thu Apr 11 21:40:52 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java Thu Apr 11 21:43:14 2013 +0200 @@ -98,7 +98,9 @@ * Looks up the appendix at the specified index. * * @param cpi the constant pool index - * @return the appendix if resolved or {@code null}. + * @param opcode the opcode of the instruction for which the lookup is being performed or + * {@code -1} + * @return the appendix if it exists and is resolved or {@code null} */ - Object lookupAppendix(int cpi); + Object lookupAppendix(int cpi, int opcode); } diff -r 08a16c26907f -r 23762f2438b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Apr 11 21:40:52 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Apr 11 21:43:14 2013 +0200 @@ -138,6 +138,8 @@ void lookupReferencedTypeInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); + Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); + // Must be kept in sync with enum in graalEnv.hpp public enum CodeInstallResult { OK, DEPENDENCIES_FAILED, CACHE_FULL @@ -221,6 +223,4 @@ * @param metaspaceMethod the metaspace Method object */ void reprofile(long metaspaceMethod); - - Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi); } diff -r 08a16c26907f -r 23762f2438b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Apr 11 21:40:52 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Apr 11 21:43:14 2013 +0200 @@ -160,5 +160,5 @@ public native void reprofile(long metaspaceMethod); @Override - public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi); + public native Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); } diff -r 08a16c26907f -r 23762f2438b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Thu Apr 11 21:40:52 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Thu Apr 11 21:43:14 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; +import com.oracle.graal.bytecode.*; import com.oracle.graal.hotspot.*; /** @@ -51,10 +52,9 @@ } @Override - public Object lookupAppendix(int cpi) { - assert cpi != 0; - Object constant = HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupAppendixInPool(type, cpi); - return constant; + public Object lookupAppendix(int cpi, int opcode) { + assert Bytecodes.isInvoke(opcode); + return HotSpotGraalRuntime.getInstance().getCompilerToVM().lookupAppendixInPool(type, cpi, (byte) opcode); } @Override diff -r 08a16c26907f -r 23762f2438b6 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Apr 11 21:40:52 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Apr 11 21:43:14 2013 +0200 @@ -1071,7 +1071,7 @@ private void genInvokeDynamic(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { - Object appendix = constantPool.lookupAppendix(stream.readCPI4()); + Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC); if (appendix != null) { frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph)); } @@ -1084,8 +1084,20 @@ private void genInvokeVirtual(JavaMethod target) { if (target instanceof ResolvedJavaMethod) { - ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true)); - genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); + // Special handling for runtimes that rewrite an invocation of MethodHandle.invoke(...) + // or MethodHandle.invokeExact(...) to a static adapter. HotSpot does this - see + // https://wikis.oracle.com/display/HotSpotInternals/Method+handles+and+invokedynamic + boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers()); + Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL); + if (appendix != null) { + frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph)); + } + ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver)); + if (hasReceiver) { + genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args); + } else { + appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args); + } } else { handleUnresolvedInvoke(target, InvokeKind.Virtual); } diff -r 08a16c26907f -r 23762f2438b6 src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Thu Apr 11 21:40:52 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.hpp Thu Apr 11 21:43:14 2013 +0200 @@ -98,6 +98,21 @@ return ((index & 0xFF) << 24) | ((index & 0xFF00) << 8) | ((index & 0xFF0000) >> 8) | ((index & 0xFF000000) >> 24); } + static int to_cp_index(int raw_index, Bytecodes::Code bc) { + int cp_index; + if (bc == Bytecodes::_invokedynamic) { + cp_index = to_index_u4(raw_index); + assert(ConstantPool::is_invokedynamic_index(raw_index), "not an invokedynamic constant pool index"); + } else { + assert(bc == Bytecodes::_getfield || bc == Bytecodes::_putfield || + bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic || + bc == Bytecodes::_invokeinterface || bc == Bytecodes::_invokevirtual || + bc == Bytecodes::_invokespecial || bc == Bytecodes::_invokestatic, err_msg("unexpected invoke opcode: %d %s", bc, Bytecodes::name(bc))); + cp_index = to_cp_index_u2(raw_index); + } + return cp_index; + } + static void initialize_buffer_blob(); }; diff -r 08a16c26907f -r 23762f2438b6 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Apr 11 21:40:52 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Apr 11 21:43:14 2013 +0200 @@ -416,10 +416,11 @@ return JNIHandles::make_local(THREAD, result); C2V_END -C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jobject type, jint index)) - assert(GraalCompiler::to_index_u4(index) < 0, "not an invokedynamic constant pool index"); +C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte opcode)) + Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); + index = GraalCompiler::to_cp_index(index, bc); constantPoolHandle cpool(InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants()); - oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, GraalCompiler::to_index_u4(index)); + oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, index); return JNIHandles::make_local(THREAD, appendix_oop); C2V_END @@ -429,7 +430,7 @@ instanceKlassHandle pool_holder(cp->pool_holder()); Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); - index = (bc == Bytecodes::_invokedynamic) ? GraalCompiler::to_index_u4(index) : GraalCompiler::to_cp_index_u2(index); + index = GraalCompiler::to_cp_index(index, bc); methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder); if (!method.is_null()) { @@ -459,11 +460,11 @@ C2V_VMENTRY(void, lookupReferencedTypeInPool, (JNIEnv *env, jobject, jobject type, jint index, jbyte op)) ConstantPool* cp = InstanceKlass::cast(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type)))->constants(); - int opcode = (op & 0xFF); - if (opcode != Bytecodes::_checkcast && opcode != Bytecodes::_instanceof && opcode != Bytecodes::_new && opcode != Bytecodes::_anewarray - && opcode != Bytecodes::_multianewarray && opcode != Bytecodes::_ldc && opcode != Bytecodes::_ldc_w && opcode != Bytecodes::_ldc2_w) + Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF); + if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray + && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w) { - index = cp->remap_instruction_operand_from_cache((opcode == Bytecodes::_invokedynamic) ? GraalCompiler::to_index_u4(index) : GraalCompiler::to_cp_index_u2(index)); + index = cp->remap_instruction_operand_from_cache(GraalCompiler::to_cp_index(index, bc)); } constantTag tag = cp->tag_at(index); if (tag.is_field_or_method()) { @@ -1120,7 +1121,7 @@ {CC"getVtableEntryOffset", CC"("METASPACE_METHOD")I", FN_PTR(getVtableEntryOffset)}, {CC"lookupType", CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE, FN_PTR(lookupType)}, {CC"lookupConstantInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupConstantInPool)}, - {CC"lookupAppendixInPool", CC"("HS_RESOLVED_TYPE"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, + {CC"lookupAppendixInPool", CC"("HS_RESOLVED_TYPE"IB)"OBJECT, FN_PTR(lookupAppendixInPool)}, {CC"lookupMethodInPool", CC"("HS_RESOLVED_TYPE"IB)"METHOD, FN_PTR(lookupMethodInPool)}, {CC"lookupTypeInPool", CC"("HS_RESOLVED_TYPE"I)"TYPE, FN_PTR(lookupTypeInPool)}, {CC"lookupReferencedTypeInPool", CC"("HS_RESOLVED_TYPE"IB)V", FN_PTR(lookupReferencedTypeInPool)}, diff -r 08a16c26907f -r 23762f2438b6 src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Thu Apr 11 21:40:52 2013 +0200 +++ b/src/share/vm/graal/graalEnv.cpp Thu Apr 11 21:43:14 2013 +0200 @@ -340,6 +340,27 @@ Symbol* name_sym = cpool->name_ref_at(index); Symbol* sig_sym = cpool->signature_ref_at(index); + if (cpool->has_preresolution() + || (holder() == SystemDictionary::MethodHandle_klass() && + MethodHandles::is_signature_polymorphic_name(holder(), name_sym))) { + // Short-circuit lookups for JSR 292-related call sites. + // That is, do not rely only on name-based lookups, because they may fail + // if the names are not resolvable in the boot class loader (7056328). + switch (bc) { + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + { + Method* m = ConstantPool::method_at_if_loaded(cpool, index); + if (m != NULL) { + return m; + } + } + break; + } + } + if (holder_is_accessible) { // Our declared holder is loaded. instanceKlassHandle lookup = get_instance_klass_for_declared_method_holder(holder); methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc);