@@ -552,13 +552,20 @@ private[spark] object IndylambdaScalaClosures extends Logging {
552
552
// produces the following trace-level logs:
553
553
// (slightly simplified:
554
554
// - omitting the "ignoring ..." lines;
555
- // - "$iw" is actually "$line16 .$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw";
555
+ // - "$iw" is actually "$line14 .$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw";
556
556
// - "invokedynamic" lines are simplified to just show the name+desc, omitting the bsm info)
557
557
// Cleaning indylambda closure: $anonfun$closure$1$adapted
558
558
// scanning $iw.$anonfun$closure$1$adapted(L$iw;Ljava/lang/Object;)Lscala/collection/immutable/IndexedSeq;
559
559
// found intra class call to $iw.$anonfun$closure$1(L$iw;I)Lscala/collection/immutable/IndexedSeq;
560
560
// scanning $iw.$anonfun$closure$1(L$iw;I)Lscala/collection/immutable/IndexedSeq;
561
561
// found inner class $iw$InnerFoo$1
562
+ // found method innerClosure()Lscala/Function1;
563
+ // found method $anonfun$innerClosure$2(L$iw$InnerFoo$1;I)Ljava/lang/String;
564
+ // found method $anonfun$innerClosure$1(L$iw$InnerFoo$1;I)Lscala/collection/immutable/IndexedSeq;
565
+ // found method <init>(L$iw;)V
566
+ // found method $anonfun$innerClosure$2$adapted(L$iw$InnerFoo$1;Ljava/lang/Object;)Ljava/lang/String;
567
+ // found method $anonfun$innerClosure$1$adapted(L$iw$InnerFoo$1;Ljava/lang/Object;)Lscala/collection/immutable/IndexedSeq;
568
+ // found method $deserializeLambda$(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
562
569
// found call to outer $iw$InnerFoo$1.innerClosure()Lscala/Function1;
563
570
// scanning $iw$InnerFoo$1.innerClosure()Lscala/Function1;
564
571
// scanning $iw$InnerFoo$1.$deserializeLambda$(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;
@@ -627,10 +634,18 @@ private[spark] object IndylambdaScalaClosures extends Logging {
627
634
val implMethodId = MethodIdentifier (
628
635
implClass, lambdaProxy.getImplMethodName, lambdaProxy.getImplMethodSignature)
629
636
630
- // The set of classes that we would consider following the calls into.
637
+ // The set internal names of classes that we would consider following the calls into.
631
638
// Candidates are: known outer class which happens to be the starting closure's impl class,
632
639
// and all inner classes discovered below.
633
- val trackedClassesByInternalName = Map [String , Class [_]](implClassInternalName -> implClass)
640
+ // Note that code in an inner class can make calls to methods in any of its enclosing classes,
641
+ // e.g.
642
+ // starting closure (in class T)
643
+ // inner class A
644
+ // inner class B
645
+ // inner closure
646
+ // we need to track calls from "inner closure" to outer classes relative to it (class T, A, B)
647
+ // to better find and track field accesses.
648
+ val trackedClassInternalNames = Set [String ](implClassInternalName)
634
649
635
650
// Depth-first search for inner closures and track the fields that were accessed in them.
636
651
// Start from the lambda body's implementation method, follow method invocations
@@ -677,16 +692,17 @@ private[spark] object IndylambdaScalaClosures extends Logging {
677
692
// Discover inner classes.
678
693
// This this the InnerClassFinder equivalent for inner classes, which still use the
679
694
// `$outer` chain. So this is NOT controlled by the `findTransitively` flag.
680
- logTrace (s " found inner class $ownerExternalName" )
695
+ logDebug (s " found inner class $ownerExternalName" )
681
696
val innerClassInfo = getOrUpdateClassInfo(owner)
682
697
val innerClass = innerClassInfo._1
683
698
val innerClassNode = innerClassInfo._2
684
- trackedClassesByInternalName(owner) = innerClass
699
+ trackedClassInternalNames += owner
685
700
// We need to visit all methods on the inner class so that we don't missing anything.
686
701
for (m <- innerClassNode.methods.asScala) {
702
+ logTrace(s " found method ${m.name}${m.desc}" )
687
703
pushIfNotVisited(MethodIdentifier (innerClass, m.name, m.desc))
688
704
}
689
- } else if (findTransitively && trackedClassesByInternalName .contains(owner)) {
705
+ } else if (findTransitively && trackedClassInternalNames .contains(owner)) {
690
706
logTrace(s " found call to outer $ownerExternalName. $name$desc" )
691
707
val (calleeClass, _) = getOrUpdateClassInfo(owner) // make sure MethodNodes are cached
692
708
pushIfNotVisited(MethodIdentifier (calleeClass, name, desc))
0 commit comments