aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
diff options
context:
space:
mode:
Diffstat (limited to 'sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala18
1 files changed, 13 insertions, 5 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
index cb808e375a..574943d3d2 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
@@ -178,7 +178,10 @@ class CodegenContext {
def initMutableStates(): String = {
// It's possible that we add same mutable state twice, e.g. the `mergeExpressions` in
// `TypedAggregateExpression`, we should call `distinct` here to remove the duplicated ones.
- mutableStates.distinct.map(_._3).mkString("\n")
+ val initCodes = mutableStates.distinct.map(_._3 + "\n")
+ // The generated initialization code may exceed 64kb function size limit in JVM if there are too
+ // many mutable states, so split it into multiple functions.
+ splitExpressions(initCodes, "init", Nil)
}
/**
@@ -604,6 +607,11 @@ class CodegenContext {
// Cannot split these expressions because they are not created from a row object.
return expressions.mkString("\n")
}
+ splitExpressions(expressions, "apply", ("InternalRow", row) :: Nil)
+ }
+
+ private def splitExpressions(
+ expressions: Seq[String], funcName: String, arguments: Seq[(String, String)]): String = {
val blocks = new ArrayBuffer[String]()
val blockBuilder = new StringBuilder()
for (code <- expressions) {
@@ -623,11 +631,11 @@ class CodegenContext {
// inline execution if only one block
blocks.head
} else {
- val apply = freshName("apply")
+ val func = freshName(funcName)
val functions = blocks.zipWithIndex.map { case (body, i) =>
- val name = s"${apply}_$i"
+ val name = s"${func}_$i"
val code = s"""
- |private void $name(InternalRow $row) {
+ |private void $name(${arguments.map { case (t, name) => s"$t $name" }.mkString(", ")}) {
| $body
|}
""".stripMargin
@@ -635,7 +643,7 @@ class CodegenContext {
name
}
- functions.map(name => s"$name($row);").mkString("\n")
+ functions.map(name => s"$name(${arguments.map(_._2).mkString(", ")});").mkString("\n")
}
}