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