Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Testcase included:yes
-
Patch Submitted:Yes
-
Number of attachments :
Description
Methods that compile to more than 32 KB of bytecode cannot be compiled.
The attached patch both implements and tests this behavior. The strategy is as follows:
When a branch requires >32K jump, it expands performing a negated jump as follows:
[if cond offset]
expands to
[if !cond skip_goto]
[GOTO_W offset]
As a concrete example,
IFGT offset
becomes
IFLE 8 GOTO_W offset
This requires that branches be allowed to change the size of bytecode when relocate() is called. To account for this, in CodeContext the methods fixup() and relocate() are made private, and a public method fixUpAndRelocate() is added.
The fixUpAndRelocate() method handles check calling fixUpAndRelocate() in a loop while the branches stabilize. A loop is required because it is theoretically possible for the expansion of a later branch to push an earlier branch over the 32K limit and cause it to switch modes, which would then require it to grow, which could trigger an earlier branch to need to expand... In practice, the loop will almost always run 1 or 2 iterations (depending on whether anything needed to grow at all).
Cool stuff! Will merge it in the next days.
Why do you change Offset.offset from SHORT to INT? We can't go beyond 64K, do we?
CU
Arno