| java.lang.Object org.apache.derby.impl.services.bytecode.Conditional
Conditional | class Conditional (Code) | | A Conditional represents an if/then/else block.
When this is created the code will already have
the conditional check code. The code is optimized for branch
offsets that fit in 2 bytes, though will handle 4 byte offsets.
if condition
then code
else code
what actually gets built is
if !condition branch to eb:
then code
goto end: // skip else
eb:
else code
end:
If no else condition was provided then the code is:
if !condition branch to end:
then code
end:
Note all branches here are using relative offsets, not absolute program counters.
If the then code leads to the conditional branch offset being too big (>32k)
because the then code is larger than 32767 bytes then this is built:
// when else code is present
if condition branch to tb: (relative offset +8)
goto_w eb: // indirect for else block (5 bytes)
tb:
then code (> 32767 bytes)
goto end:
eb:
else code
end:
// when only then code is present
if condition branch to tb: (relative offset +8)
goto_w end: // indirect for else block (5 bytes)
tb:
then code (> 32767 bytes)
end:
If there is an else branch and only it is larger than 32767 bytes then
the code is:
if !condition branch to eb: (offset increased by two over previous value)
then code
goto_w end: // skip else
eb:
else code (> 32767 bytes)
end:
This has one special case where the size of conditional branch to eb:
now must change from a 16bit value to a 32 bit value. The generated code
for this is the same as when both the then code and the else code require
32bit offsets for the branches. This code is:
if condition branch to tb: (relative offset +8)
goto_w eb: // indirect for else block (5 bytes)
tb:
then code (> 32767 bytes)
goto_w end:
eb:
else code (> 32767 bytes)
end:
In theory, at the moment this should not happen as this would mean a total
code size that exceeds the limit on the code size for a method (64k). This
code handles this case as it does occur if the limit for a branch is lowered
for testing purposes, to ensure the complete set of branch re-write code works.
This lowering of the limit can be done by changing the constant BRANCH16LIMIT.
|
Method Summary | |
Conditional | end(BCMethod mb, CodeChunk chunk, Type[] elseStack, int stackNumber) Complete the conditional and patch up any jump instructions. | Type[] | startElse(BCMethod mb, CodeChunk chunk, Type[] thenStack) Complete the 'then' block and start the 'else' block for this conditional
Parameters: chunk - CodeChunk this conditional lives in Parameters: thenStack - Type stack on completing the conditional then block. |
Conditional | Conditional(Conditional parent, CodeChunk chunk, short ifOpcode, Type[] entryStack)(Code) | | Start a conditional block.
Parameters: parent - Current conditional block, null if no nesting is going on. Parameters: chunk - CodeChunk this conditional lives in Parameters: ifOpcode - Opcode for the if check. Parameters: entryStack - Type stack on entering the conditional then block. |
end | Conditional end(BCMethod mb, CodeChunk chunk, Type[] elseStack, int stackNumber)(Code) | | Complete the conditional and patch up any jump instructions.
Parameters: chunk - CodeChunk this conditional lives in Parameters: elseStack - Current stack, which is the stack at the end of the else Parameters: stackNumber - Current number of valid elements in elseStack The conditional this conditional was nested in, if any. |
startElse | Type[] startElse(BCMethod mb, CodeChunk chunk, Type[] thenStack)(Code) | | Complete the 'then' block and start the 'else' block for this conditional
Parameters: chunk - CodeChunk this conditional lives in Parameters: thenStack - Type stack on completing the conditional then block. the type stack on entering the then block |
|
|