summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Bothner <per@bothner.com>2023-02-26 12:47:43 -0800
committerPer Bothner <per@bothner.com>2023-02-26 12:47:43 -0800
commite16282def659ed29a68cb0e61b69422af654bf1d (patch)
tree78cde3f9e6ee0f88a3aa43219bdca8d3079edbd7
parentaa5d5399eb78787104c30cdae94a9b354f162e18 (diff)
ExitableBlock.java (endLabel): Allocate lazily.
This avoids need to use not-quite-appropriate needsStackMapEntry field.
-rw-r--r--gnu/bytecode/ChangeLog3
-rw-r--r--gnu/bytecode/CodeAttr.java2
-rw-r--r--gnu/bytecode/ExitableBlock.java48
3 files changed, 24 insertions, 29 deletions
diff --git a/gnu/bytecode/ChangeLog b/gnu/bytecode/ChangeLog
index be2ee0c62..23d73042c 100644
--- a/gnu/bytecode/ChangeLog
+++ b/gnu/bytecode/ChangeLog
@@ -1,5 +1,8 @@
2023-02-26 Per Bothner <per@bothner.com>
+ * ExitableBlock.java (endLabel): Allocate lazily.
+ This avoids need to use not-quite-appropriate needsStackMapEntry field.
+
* PrimType.java (numberHierarchy): Fix typo.
2022-10-16 Per Bothner <per@bothner.com>
diff --git a/gnu/bytecode/CodeAttr.java b/gnu/bytecode/CodeAttr.java
index f0c5a2fc4..d3dce1cfe 100644
--- a/gnu/bytecode/CodeAttr.java
+++ b/gnu/bytecode/CodeAttr.java
@@ -2440,6 +2440,8 @@ public class CodeAttr extends Attribute implements AttrContainer
exit.initialTryState);
if (nextTry == exit.initialTryState) // Optimization
{
+ if (exit.endLabel == null)
+ exit.endLabel = new Label(this);
sw.addCaseGoto(exit.switchCase, this, exit.endLabel);
}
else
diff --git a/gnu/bytecode/ExitableBlock.java b/gnu/bytecode/ExitableBlock.java
index 34ecc6c7a..08e000900 100644
--- a/gnu/bytecode/ExitableBlock.java
+++ b/gnu/bytecode/ExitableBlock.java
@@ -34,7 +34,7 @@ public class ExitableBlock
CodeAttr code;
Type resultType;
TryState initialTryState;
- Label endLabel;
+ Label endLabel; // allocated lazily
ExitableBlock outer;
// The innermost current TryState which contains an exit to the block.
TryState currentTryState;
@@ -58,25 +58,24 @@ public class ExitableBlock
code.emitStoreDefaultValue(var);
switchCase = ++code.exitableBlockLevel;
}
- endLabel = new Label(code);
}
- void finish ()
- {
- boolean reachable = code.reachableHere();
- if (resultVariable != null && reachable)
- code.emitStore(resultVariable);
- endLabel.define(code);
- if (! reachable && ! endLabel.needsStackMapEntry)
- code.setUnreachable();
- else if (resultVariable != null)
- code.emitLoad(resultVariable);
- if (resultVariable != null)
- {
- code.popScope();
- --code.exitableBlockLevel;
- }
- }
+ void finish ()
+ {
+ boolean reachable = code.reachableHere();
+ if (resultVariable != null && reachable)
+ code.emitStore(resultVariable);
+ if (endLabel != null) {
+ endLabel.define(code);
+ if (resultVariable != null)
+ code.emitLoad(resultVariable);
+ }
+ if (resultVariable != null)
+ {
+ code.popScope();
+ --code.exitableBlockLevel;
+ }
+ }
/** Exit this surrounding block, executing finally blocks as needed.
* Return a value as the result of this ExitableBlock. */
@@ -87,17 +86,6 @@ public class ExitableBlock
exit(TryState.outerHandler(code.try_stack, initialTryState));
}
- /** If an exit is simple, return the label for block end.
- * The exit is simple if there is no intervening finally blocks.
- */
- public Label exitIsGoto ()
- {
- if (TryState.outerHandler(code.try_stack, initialTryState) == initialTryState)
- return endLabel;
- else
- return null;
- }
-
private void popStack(CodeAttr code) {
int retSize = resultVariable != null || resultType == null ? 0
: resultType.size > 4 ? 2 : 1;
@@ -124,6 +112,8 @@ public class ExitableBlock
if (! code.reachableHere())
return;
popStack(code);
+ if (endLabel == null)
+ endLabel = new Label(code);
if (activeTry == initialTryState)
code.emitGoto(endLabel);
else if (code.useJsr())