@@ -132,7 +132,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
132
132
(declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either [OptimizerWarning , (ClassNode , Source )]
133
133
} yield {
134
134
val declarationClassBType = classBTypeFromClassNode(declarationClassNode)
135
- val CallsiteInfo (safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner , source)
135
+ val CallsiteInfo (safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call, source)
136
136
Callee (
137
137
callee = method,
138
138
calleeDeclarationClass = declarationClassBType,
@@ -264,7 +264,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
264
264
/**
265
265
* Analyze a callsite and gather meta-data that can be used for inlining decisions.
266
266
*/
267
- private def analyzeCallsite (calleeMethodNode : MethodNode , calleeDeclarationClassBType : ClassBType , receiverTypeInternalName : InternalName , calleeSource : Source ): CallsiteInfo = {
267
+ private def analyzeCallsite (calleeMethodNode : MethodNode , calleeDeclarationClassBType : ClassBType , call : MethodInsnNode , calleeSource : Source ): CallsiteInfo = {
268
268
val methodSignature = calleeMethodNode.name + calleeMethodNode.desc
269
269
270
270
try {
@@ -277,7 +277,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
277
277
278
278
val isAbstract = BytecodeUtils .isAbstractMethod(calleeMethodNode)
279
279
280
- val receiverType = classBTypeFromParsedClassfile(receiverTypeInternalName )
280
+ val receiverType = classBTypeFromParsedClassfile(call.owner )
281
281
// (1) A non-final method can be safe to inline if the receiver type is a final subclass. Example:
282
282
// class A { @inline def f = 1 }; object B extends A; B.f // can be inlined
283
283
//
@@ -295,6 +295,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
295
295
// TODO: type analysis can render more calls statically resolved. Example:
296
296
// new A.f // can be inlined, the receiver type is known to be exactly A.
297
297
val isStaticallyResolved : Boolean = {
298
+ isNonVirtualCall(call) || // SD-86: super calls (invokespecial) can be inlined
298
299
methodInlineInfo.effectivelyFinal ||
299
300
receiverType.info.orThrow.inlineInfo.isEffectivelyFinal // (1)
300
301
}
0 commit comments