sarutak commented on code in PR #57710:
URL: https://github.com/apache/spark/pull/57710#discussion_r3703492548


##########
common/utils/src/main/scala/org/apache/spark/util/ClosureCleaner.scala:
##########
@@ -34,6 +35,39 @@ import org.apache.spark.internal.Logging
  * A cleaner that renders closures serializable if they can be done so safely.
  */
 private[spark] object ClosureCleaner extends Logging {
+  /**
+   * Per-class memo of which closure methods contain a non-local return, i.e. 
allocate a
+   * `scala/runtime/NonLocalReturnControl`. The verdict is a pure function of 
the class's
+   * immutable bytecode, so one ASM parse per class answers for every 
`clean()` call.
+   */
+  private val methodsWithNonLocalReturn = new 
ClassValue[immutable.Set[String]] {
+    override def computeValue(cls: Class[_]): immutable.Set[String] = {
+      val collector = new ReturnStatementCollector
+      val reader = getClassReader(cls)
+      if (reader != null) {
+        reader.accept(collector, 0)
+      } else {
+        logDebug(s"Cannot get class bytes for ${cls.getName}; skipping 
return-statement check")
+      }
+      collector.found.toSet
+    }
+  }
+
+  /** Whether `implMethodName` (any closure method, if `None`) of `cls` has a 
non-local return. */
+  private[util] def hasReturnStatement(cls: Class[_], implMethodName: 
Option[String]): Boolean = {
+    val found = methodsWithNonLocalReturn.get(cls)
+    implMethodName match {
+      case None => found.nonEmpty
+      case Some(target) =>
+        // A method with suffix "$adapted" will be generated in cases like
+        // { _:Int => return; Seq()} but not { _:Int => return; true}
+        // closure passed is $anonfun$t$1$adapted while actual code resides in 
$anonfun$s$1
+        // the class file only contains $anonfun$s$1, so we remove the suffix, 
see

Review Comment:
   I understand this comment was carried over from the existing code, but the 
statement "the class file only contains `$anonfun$s$1"` appears inaccurate. 
Given `TestAdapter` as follows, `javap` shows that both `$anonfun$main$1` and 
`$anonfun$main$1$adapted` exist in the class file.
   
   ```scala
   object TestAdapted {
     def main(args: Array[String]): Unit = {
       // This should produce $anonfun$main$1 and possibly 
$anonfun$main$1$adapted
       val f: Int => Seq[Int] = { _: Int => return; Seq() }
       f(1)
     }
   }
   ```
   ```
   $ javap -c TestAdapted$
   ...
     public static final scala.collection.immutable.Seq 
$anonfun$main$1(java.lang.Object, int);
       Code:
          0: new           #77                 // class 
scala/runtime/NonLocalReturnControl$mcV$sp
          3: dup
          4: aload_0
          5: getstatic     #83                 // Field 
scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
          8: invokespecial #86                 // Method 
scala/runtime/NonLocalReturnControl$mcV$sp."<init>":(Ljava/lang/Object;Lscala/runtime/BoxedUnit;)V
         11: athrow
   
     public static final scala.collection.immutable.Seq 
$anonfun$main$1$adapted(java.lang.Object, java.lang.Object);
       Code:
          0: aload_0
          1: aload_1
          2: invokestatic  #92                 // Method 
scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
          5: invokestatic  #94                 // Method 
$anonfun$main$1:(Ljava/lang/Object;I)Lscala/collection/immutable/Seq;
          8: areturn
   ```
   
   The actual reason for stripping the `$adapted` suffix is that the `NEW 
NonLocalReturnControl` bytecode only appears in the non-adapted method body 
(the adapted variant is a boxing bridge that delegates to it). Might be worth 
fixing the comment while you're here.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to