67 assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong 68 member = m; 69 } 70 } 71 72 this.member = member; 73 } 74 75 // Factory methods: 76 static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) { 77 MethodType mtype = member.getMethodOrFieldType(); 78 if (!member.isStatic()) { 79 if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor()) 80 throw new InternalError(member.toString()); 81 mtype = mtype.insertParameterTypes(0, refc); 82 } 83 if (!member.isField()) { 84 switch (refKind) { 85 case REF_invokeSpecial: { 86 member = member.asSpecial(); 87 LambdaForm lform = preparedLambdaForm(member, callerClass); 88 Class<?> checkClass = refc; // Class to use for receiver type check 89 if (callerClass != null) { 90 checkClass = callerClass; // potentially strengthen to caller class 91 } 92 return new Special(mtype, lform, member, checkClass); 93 } 94 case REF_invokeInterface: { 95 LambdaForm lform = preparedLambdaForm(member, callerClass); 96 return new Interface(mtype, lform, member, refc); 97 } 98 default: { 99 LambdaForm lform = preparedLambdaForm(member, callerClass); 100 return new DirectMethodHandle(mtype, lform, member); 101 } 102 } 103 } else { 104 LambdaForm lform = preparedFieldLambdaForm(member); 105 if (member.isStatic()) { 106 long offset = MethodHandleNatives.staticFieldOffset(member); 107 Object base = MethodHandleNatives.staticFieldBase(member); 108 return new StaticAccessor(mtype, lform, member, base, offset); 109 } else { 110 long offset = MethodHandleNatives.objectFieldOffset(member); 111 assert(offset == (int)offset); 112 return new Accessor(mtype, lform, member, (int)offset); 113 } 114 } 115 } 116 static DirectMethodHandle make(Class<?> refc, MemberName member) { 117 byte refKind = member.getReferenceKind(); 118 if (refKind == REF_invokeSpecial) 119 refKind = REF_invokeVirtual; 149 150 @Override 151 String internalProperties() { 152 return "\n& DMH.MN="+internalMemberName(); 153 } 154 155 //// Implementation methods. 156 @Override 157 @ForceInline 158 MemberName internalMemberName() { 159 return member; 160 } 161 162 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); 163 164 /** 165 * Create a LF which can invoke the given method. 166 * Cache and share this structure among all methods with 167 * the same basicType and refKind. 168 */ 169 private static LambdaForm preparedLambdaForm(MemberName m, Class<?> callerClass) { 170 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead 171 MethodType mtype = m.getInvocationType().basicType(); 172 assert(!m.isMethodHandleInvoke()) : m; 173 int which; 174 switch (m.getReferenceKind()) { 175 case REF_invokeVirtual: which = LF_INVVIRTUAL; break; 176 case REF_invokeStatic: which = LF_INVSTATIC; break; 177 case REF_invokeSpecial: which = LF_INVSPECIAL; break; 178 case REF_invokeInterface: which = LF_INVINTERFACE; break; 179 case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break; 180 default: throw new InternalError(m.toString()); 181 } 182 if (which == LF_INVSTATIC && shouldBeInitialized(m)) { 183 // precompute the barrier-free version: 184 preparedLambdaForm(mtype, which); 185 which = LF_INVSTATIC_INIT; 186 } 187 if (which == LF_INVSPECIAL && callerClass != null && callerClass.isInterface()) { 188 which = LF_INVSPECIAL_IFC; 189 } 190 LambdaForm lform = preparedLambdaForm(mtype, which); 191 maybeCompile(lform, m); 192 assert(lform.methodType().dropParameterTypes(0, 1) 193 .equals(m.getInvocationType().basicType())) 194 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType()); 195 return lform; 196 } 197 198 private static LambdaForm preparedLambdaForm(MemberName m) { 199 return preparedLambdaForm(m, null); 200 } 201 202 private static LambdaForm preparedLambdaForm(MethodType mtype, int which) { 203 LambdaForm lform = mtype.form().cachedLambdaForm(which); 204 if (lform != null) return lform; 205 lform = makePreparedLambdaForm(mtype, which); 206 return mtype.form().setCachedLambdaForm(which, lform); 207 } 208 209 static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { 210 boolean needsInit = (which == LF_INVSTATIC_INIT); 211 boolean doesAlloc = (which == LF_NEWINVSPECIAL); 212 boolean needsReceiverCheck = (which == LF_INVINTERFACE || 213 which == LF_INVSPECIAL_IFC); 214 215 String linkerName; 216 LambdaForm.Kind kind; 217 switch (which) { 218 case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; 219 case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; | 67 assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong 68 member = m; 69 } 70 } 71 72 this.member = member; 73 } 74 75 // Factory methods: 76 static DirectMethodHandle make(byte refKind, Class<?> refc, MemberName member, Class<?> callerClass) { 77 MethodType mtype = member.getMethodOrFieldType(); 78 if (!member.isStatic()) { 79 if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor()) 80 throw new InternalError(member.toString()); 81 mtype = mtype.insertParameterTypes(0, refc); 82 } 83 if (!member.isField()) { 84 switch (refKind) { 85 case REF_invokeSpecial: { 86 member = member.asSpecial(); 87 // if caller is an interface we need to adapt to get the 88 // receiver check inserted 89 LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface()); 90 Class<?> checkClass = refc; // Class to use for receiver type check 91 if (callerClass != null) { 92 checkClass = callerClass; // potentially strengthen to caller class 93 } 94 return new Special(mtype, lform, member, checkClass); 95 } 96 case REF_invokeInterface: { 97 // we always adapt 'special' when dealing with interfaces 98 LambdaForm lform = preparedLambdaForm(member, true); 99 return new Interface(mtype, lform, member, refc); 100 } 101 default: { 102 LambdaForm lform = preparedLambdaForm(member); 103 return new DirectMethodHandle(mtype, lform, member); 104 } 105 } 106 } else { 107 LambdaForm lform = preparedFieldLambdaForm(member); 108 if (member.isStatic()) { 109 long offset = MethodHandleNatives.staticFieldOffset(member); 110 Object base = MethodHandleNatives.staticFieldBase(member); 111 return new StaticAccessor(mtype, lform, member, base, offset); 112 } else { 113 long offset = MethodHandleNatives.objectFieldOffset(member); 114 assert(offset == (int)offset); 115 return new Accessor(mtype, lform, member, (int)offset); 116 } 117 } 118 } 119 static DirectMethodHandle make(Class<?> refc, MemberName member) { 120 byte refKind = member.getReferenceKind(); 121 if (refKind == REF_invokeSpecial) 122 refKind = REF_invokeVirtual; 152 153 @Override 154 String internalProperties() { 155 return "\n& DMH.MN="+internalMemberName(); 156 } 157 158 //// Implementation methods. 159 @Override 160 @ForceInline 161 MemberName internalMemberName() { 162 return member; 163 } 164 165 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); 166 167 /** 168 * Create a LF which can invoke the given method. 169 * Cache and share this structure among all methods with 170 * the same basicType and refKind. 171 */ 172 private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecialIfc) { 173 assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead 174 MethodType mtype = m.getInvocationType().basicType(); 175 assert(!m.isMethodHandleInvoke()) : m; 176 int which; 177 // MemberName.getReferenceKind may be different from the 'kind' passed to 178 // DMH.make. Specifically private/final methods that use a direct call 179 // have been adapted to REF_invokeSpecial, even though the actual 180 // invocation mode may be invokevirtual or invokeinterface. 181 switch (m.getReferenceKind()) { 182 case REF_invokeVirtual: which = LF_INVVIRTUAL; break; 183 case REF_invokeStatic: which = LF_INVSTATIC; break; 184 case REF_invokeSpecial: which = LF_INVSPECIAL; break; 185 case REF_invokeInterface: which = LF_INVINTERFACE; break; 186 case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break; 187 default: throw new InternalError(m.toString()); 188 } 189 if (which == LF_INVSTATIC && shouldBeInitialized(m)) { 190 // precompute the barrier-free version: 191 preparedLambdaForm(mtype, which); 192 which = LF_INVSTATIC_INIT; 193 } 194 if (which == LF_INVSPECIAL && adaptToSpecialIfc) { 195 which = LF_INVSPECIAL_IFC; 196 } 197 LambdaForm lform = preparedLambdaForm(mtype, which); 198 maybeCompile(lform, m); 199 assert(lform.methodType().dropParameterTypes(0, 1) 200 .equals(m.getInvocationType().basicType())) 201 : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType()); 202 return lform; 203 } 204 205 private static LambdaForm preparedLambdaForm(MemberName m) { 206 return preparedLambdaForm(m, false); 207 } 208 209 private static LambdaForm preparedLambdaForm(MethodType mtype, int which) { 210 LambdaForm lform = mtype.form().cachedLambdaForm(which); 211 if (lform != null) return lform; 212 lform = makePreparedLambdaForm(mtype, which); 213 return mtype.form().setCachedLambdaForm(which, lform); 214 } 215 216 static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { 217 boolean needsInit = (which == LF_INVSTATIC_INIT); 218 boolean doesAlloc = (which == LF_NEWINVSPECIAL); 219 boolean needsReceiverCheck = (which == LF_INVINTERFACE || 220 which == LF_INVSPECIAL_IFC); 221 222 String linkerName; 223 LambdaForm.Kind kind; 224 switch (which) { 225 case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; 226 case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; |