[
https://issues.apache.org/jira/browse/GROOVY-12642?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18136267#comment-18136267
]
ASF GitHub Bot commented on GROOVY-12642:
-----------------------------------------
codecov-commenter commented on PR #3163:
URL: https://github.com/apache/groovy/pull/3163#issuecomment-6568090573
##
[Codecov](https://app.codecov.io/gh/apache/groovy/pull/3163?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 74.1500%. Comparing base
([`4603713`](https://app.codecov.io/gh/apache/groovy/commit/46037138d7dad29fc51d2cdd6a828f7b7ad6bf38?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache))
to head
([`dd5eb94`](https://app.codecov.io/gh/apache/groovy/commit/dd5eb949a703f3e2dd63c4cc55a8e2cc92b77061?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
:warning: Report is 1 commits behind head on master.
<details><summary>Additional details and impacted files</summary>
[](https://app.codecov.io/gh/apache/groovy/pull/3163?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
```diff
@@ Coverage Diff @@
## master #3163 +/- ##
==================================================
- Coverage 74.1568% 74.1500% -0.0068%
+ Complexity 43757 43748 -9
==================================================
Files 1692 1692
Lines 149517 149520 +3
Branches 28366 28366
==================================================
- Hits 110877 110869 -8
- Misses 28446 28450 +4
- Partials 10194 10201 +7
```
| [Files with missing
lines](https://app.codecov.io/gh/apache/groovy/pull/3163?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
| Coverage Δ | |
|---|---|---|
|
[...groovy/classgen/asm/sc/StaticInvocationWriter.java](https://app.codecov.io/gh/apache/groovy/pull/3163?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Forg%2Fcodehaus%2Fgroovy%2Fclassgen%2Fasm%2Fsc%2FStaticInvocationWriter.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9vcmcvY29kZWhhdXMvZ3Jvb3Z5L2NsYXNzZ2VuL2FzbS9zYy9TdGF0aWNJbnZvY2F0aW9uV3JpdGVyLmphdmE=)
| `77.3157% <100.0000%> (+0.1294%)` | :arrow_up: |
... and [7 files with indirect coverage
changes](https://app.codecov.io/gh/apache/groovy/pull/3163/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
</details>
<details><summary> :rocket: New features to boost your workflow: </summary>
- :snowflake: [Test
Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests,
report on failures, and find test suite problems.
- :package: [JS Bundle
Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save
yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
> Statically compiled spread-dot loops keep the result list on the operand
> stack, which blocks HotSpot on-stack replacement
> -------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12642
> URL: https://issues.apache.org/jira/browse/GROOVY-12642
> Project: Groovy
> Issue Type: Improvement
> Components: Static compilation
> Affects Versions: 6.0.0
> Reporter: Paul King
> Priority: Major
>
> Description:
> Under @CompileStatic, a spread-dot expression such as `ps*.x` or `ps*.twice()`
> is compiled inline as a for-in loop that adds each value to a new ArrayList.
> The generated code keeps a copy of that ArrayList on the JVM operand stack for
> the whole loop (it is the value of the expression), and the loop's back edge
> therefore carries a non-empty stack:
> {code}
> 8: new ArrayList / dup / invokespecial <init>
> 15: dup
> 16: astore_1 // list stored in a slot, a second copy left on the
> stack
> ...
> 42: iterator.hasNext() ... aload_1, element.length(), ArrayList.add, pop
> 89: goto 42 // back edge with the list still on the stack
> {code}
> HotSpot cannot compile a running loop on-stack (OSR) when the operand stack at
> the loop is not empty. With -XX:+PrintCompilation on JDK 17 both tiers refuse:
> {code}
> Bench::spread @ 42 (97 bytes) COMPILE SKIPPED: stack not empty at OSR entry
> point (retry at different tier)
> Bench::spread @ 42 (97 bytes) COMPILE SKIPPED: OSR starts with non-empty
> stack (retry at different tier)
> {code}
> A method that is called often is unaffected, since it is compiled as a whole
> on a later call, but a method that runs once over a large collection (a script
> body, main(), batch or pipeline setup, a benchmark) runs the whole traversal
> in the interpreter. Over 3 million elements, a one-shot `def r = ps*.x` took
> 464 ms against 30 ms for the equivalent hand-written loop (6.0.0-beta-2,
> JDK 17).
> This was first reported in a blog post on Groovy with Flink on TornadoVM,
> where `batch*.f1` over a million elements took around 400 ms and a plain loop
> was around ten times faster.
> Dynamic code, including @TypeChecked, is not affected: it calls the
> ScriptBytecodeAdapter *SpreadSafe helpers, whose loops are ordinary Java
> loops.
> Proposed fix:
> In StaticInvocationWriter.makeCall, keep the result list only in its temporary
> slot while looping and load it from the slot after the loop. The operand stack
> is then empty at the back edge whenever the spread is evaluated with nothing
> else pending on the stack, which covers the usual forms:
> `def r = xs*.f`, `r = xs*.f`, `return xs*.f`, and a spread used as a receiver
> (`xs*.f.sum()`). Evaluation order, null handling and the result are unchanged.
> Not covered: a spread evaluated while other operands are already on the stack,
> for example an argument after another argument (`foo(a, xs*.f)`) or the right
> operand of a binary expression (`n + xs*.f.size()`). Those would need the
> pending stack spilled to locals or the loop moved out of line, and are left
> for a follow-up if worthwhile.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)