Daniel Sun created GROOVY-12065:
-----------------------------------
Summary: Implement peephole optimization for constant loading in
bytecode generation
Key: GROOVY-12065
URL: https://issues.apache.org/jira/browse/GROOVY-12065
Project: Groovy
Issue Type: Improvement
Reporter: Daniel Sun
h3. Background
Groovy's bytecode generator relied on ad-hoc, per-type conditional branches
scattered across {{OperandStack}} and {{BytecodeHelper}} to select compact
constant-loading instructions ({{{}ICONST_x{}}}, {{{}LCONST_x{}}},
{{{}FCONST_x{}}}, {{{}DCONST_x{}}}, {{{}BIPUSH{}}}, {{{}SIPUSH{}}}) over the
generic {{LDC}} instruction. This logic was fragile, inconsistent, and
incomplete — for instance, {{BytecodeHelper.pushConstant()}} was missing the
{{ICONST_M1}} case for the integer constant {{{}-1{}}}.
h3. Change
A new {{PeepholeOptimizingMethodVisitor}} — a {{MethodVisitor}} decorator — is
introduced and inserted into the per-method visitor chain in
{{{}AsmClassGenerator{}}}. It intercepts every {{visitLdcInsn}} and
{{visitIntInsn(BIPUSH/SIPUSH, ...)}} call and rewrites each to the shortest
valid equivalent opcode:
||Value||Emitted instruction||
|{{int}} −1|{{ICONST_M1}}|
|{{int}} 0–5|{{ICONST_0}} – {{ICONST_5}}|
|{{int}} in [−128, 127]|{{BIPUSH}}|
|{{int}} in [−32768, 32767]|{{SIPUSH}}|
|{{long}} 0 / 1|{{LCONST_0}} / {{LCONST_1}}|
|{{float}} 0 / 1 / 2|{{FCONST_0}} / {{FCONST_1}} / {{FCONST_2}}|
|{{double}} 0 / 1|{{DCONST_0}} / {{DCONST_1}}|
Signed-zero {{float}} and {{double}} values are handled correctly by comparing
raw bit patterns (via {{Float.floatToRawIntBits}} /
{{{}Double.doubleToRawLongBits{}}}) rather than {{{}=={}}}, preserving the
{{-0.0}} / {{+0.0}} distinction that a straight equality check would collapse.
All per-type branches previously inlined in {{OperandStack}} are replaced with
plain {{visitLdcInsn(value)}} calls; the peephole visitor centralizes the
selection uniformly for every generated method.
{{BytecodeHelper.pushConstant()}} also gains the previously missing
{{ICONST_M1}} branch.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)