LuciferYang opened a new pull request, #57294:
URL: https://github.com/apache/spark/pull/57294

   ### What changes were proposed in this pull request?
   
   `BroadcastHashJoinExec` takes a read-only copy of the broadcast 
`HashedRelation`
   and records its size as the task's peak execution memory in three places 
using
   identical logic:
   
   - the interpreted path in `doExecute`, both the null-aware anti-join branch 
and
     the regular branch, and
   - the generated code in `prepareBroadcast`, which re-emits the two statements
     into every `BroadcastHashJoinExec` whole-stage-codegen stage.
   
   This PR extracts that type-independent setup into a shared helper
   `BroadcastHashJoinExec.buildReadOnlyRelation(broadcast): HashedRelation` and
   calls it from all three paths. The generated relation initializer shrinks 
from
   two statements to a single static call.
   
   Before (generated code, per `BroadcastHashJoinExec` stage):
   ```java
   relation = ((org.apache.spark.sql.execution.joins.LongHashedRelation) 
references[N] /* broadcast */
     .value()).asReadOnlyCopy();
   incPeakExecutionMemory(relation.estimatedSize());
   ```
   
   After:
   ```java
   relation = (org.apache.spark.sql.execution.joins.LongHashedRelation)
     
org.apache.spark.sql.execution.joins.BroadcastHashJoinExec.buildReadOnlyRelation(
       references[N] /* broadcast */);
   ```
   
   The helper returns the `HashedRelation` supertype, so the generated code 
casts
   the result back to the concrete relation class; the mutable-state field keeps
   its precise static type for the hot-path `getValue`/`get` dispatch, exactly 
as
   before.
   
   This follows the same "extract type-independent generated machinery into a
   compiled helper" pattern as SPARK-57909 (`ColumnarToRowExec.advanceBatch`), 
and
   additionally de-duplicates the two interpreted `doExecute` copies.
   
   Measured with `WholeStageCodegenSizeBenchmark` (added under SPARK-57915; 
plans
   all 135 TPC-DS queries over empty tables), current `master` vs. this change:
   
   | metric | master | this PR | delta |
   | --- | --- | --- | --- |
   | constant pool, summed over stages | 432,881 | 430,503 | -0.55% |
   | max method bytecode, summed over stages | 841,185 | 841,161 | ~unchanged |
   | source code size (chars) | 21,846,001 | 21,846,031 | ~unchanged |
   | inner classes | 258 | 258 | unchanged |
   | codegen fallbacks | 0 | 0 | unchanged |
   
   The reduction shows up in the constant pool, since the `asReadOnlyCopy` /
   `estimatedSize` / `incPeakExecutionMemory` method references are now emitted 
once
   instead of per stage. `max method bytecode` is unchanged because the relation
   initializer is not a stage's largest method, and the source-char count is 
flat
   because the fully-qualified helper call is about as long as the two inline
   statements it replaces -- the win is in the compiled constant pool, which is
   what gates the 64KB method / constant-pool limits.
   
   ### Why are the changes needed?
   
   This is part of the umbrella SPARK-56908 (reduce the size of code generated 
by
   whole-stage codegen). The relation setup is real bytecode and constant-pool
   method-references that Janino cannot fold away; collapsing it to a single 
helper
   call compiles it once per JVM instead of re-emitting it into every
   `BroadcastHashJoinExec` stage. It also removes two copies of the 
interpreted-path
   logic, so the paths can no longer drift.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. The helper performs the same `asReadOnlyCopy` and peak-memory 
bookkeeping in
   the same order as the previous code; this is a pure code-organization change
   with no behavioral difference.
   
   ### How was this patch tested?
   
   Existing tests, run with whole-stage codegen both on and off:
   - `OuterJoinSuite`, `InnerJoinSuite`, `ExistenceJoinSuite` (the join 
operators'
     correctness across build sides and codegen on/off), and
   - `BroadcastJoinSuite` (broadcast build path, null-aware anti join, and 
metrics).
   
   No behavior changes, so no new tests are added; the extracted setup is 
covered by
   the existing broadcast-join suites on both the interpreted and generated 
paths.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Claude Code (Opus 4.8)
   


-- 
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