|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object MethodGen org.apache.xalan.xsltc.compiler.util.MethodGenerator
public class MethodGenerator
Nested Class Summary | |
---|---|
private static class |
MethodGenerator.Chunk
Used to keep track of an outlineable chunk of instructions in the current method. |
protected class |
MethodGenerator.LocalVariableRegistry
Keeps track of all local variables used in the method. |
Field Summary | |
---|---|
private boolean |
_allocatorInit
|
private Instruction |
_aloadDom
|
private Instruction |
_aloadHandler
|
private Instruction |
_aloadIterator
|
private Instruction |
_astoreDom
|
private Instruction |
_astoreHandler
|
private Instruction |
_astoreIterator
|
private Instruction |
_attribute
|
private Instruction |
_endDocument
|
private Instruction |
_endElement
|
private Instruction |
_iloadCurrent
|
private Instruction |
_istoreCurrent
|
private MethodGenerator.LocalVariableRegistry |
_localVariableRegistry
|
private InstructionList |
_mapTypeSub
|
private Instruction |
_namespace
|
private Instruction |
_nextNode
|
private java.util.Hashtable |
_preCompiled
A mapping between patterns and instruction lists used by test sequences to avoid compiling the same pattern multiple times. |
private Instruction |
_reset
|
private Instruction |
_setStartNode
|
private SlotAllocator |
_slotAllocator
|
private Instruction |
_startDocument
|
private Instruction |
_startElement
|
private Instruction |
_uniqueAttribute
|
private static int |
DOM_INDEX
|
private static java.lang.String |
END_ELEMENT_SIG
|
private static int |
HANDLER_INDEX
|
protected static int |
INVALID_INDEX
|
private static int |
ITERATOR_INDEX
|
private int |
m_openChunks
Track the number of outlineable chunks started but not yet ended. |
private int |
m_totalChunks
Track the number of outlineable chunks seen. |
private static int |
MAX_BRANCH_TARGET_OFFSET
|
private static int |
MAX_METHOD_SIZE
|
private static int |
MIN_BRANCH_TARGET_OFFSET
|
private static int |
MINIMUM_OUTLINEABLE_CHUNK_SIZE
|
private static java.lang.String |
START_ELEMENT_SIG
|
private static int |
TARGET_METHOD_SIZE
|
Constructor Summary | |
---|---|
MethodGenerator(int access_flags,
Type return_type,
Type[] arg_types,
java.lang.String[] arg_names,
java.lang.String method_name,
java.lang.String class_name,
InstructionList il,
ConstantPoolGen cpg)
|
Method Summary | |
---|---|
void |
addInstructionList(Pattern pattern,
InstructionList ilist)
Add a pre-compiled pattern to this mode. |
LocalVariableGen |
addLocalVariable(java.lang.String name,
Type type,
InstructionHandle start,
InstructionHandle end)
Allocates a local variable. |
LocalVariableGen |
addLocalVariable2(java.lang.String name,
Type type,
InstructionHandle start)
|
Instruction |
attribute()
|
Instruction |
endDocument()
|
Instruction |
endElement()
|
private java.util.ArrayList |
getCandidateChunks(ClassGenerator classGen,
int totalMethodSize)
Find the outlineable chunks in this method that would be the best choices to outline, based on size and position in the method. |
(package private) Method[] |
getGeneratedMethods(ClassGenerator classGen)
Get all Method s generated by this MethodGenerator . |
InstructionList |
getInstructionList(Pattern pattern)
Get the instruction list for a pre-compiled pattern. |
int |
getLocalIndex(java.lang.String name)
|
LocalVariableGen |
getLocalVariable(java.lang.String name)
|
private MethodGenerator.LocalVariableRegistry |
getLocalVariableRegistry()
|
protected Method |
getThisMethod()
|
Instruction |
loadContextNode()
by default context node is the same as current node. |
Instruction |
loadCurrentNode()
|
Instruction |
loadDOM()
|
Instruction |
loadHandler()
|
Instruction |
loadIterator()
|
private static Instruction |
loadLocal(int index,
Type type)
Helper method to generate an instance of a subclass of LoadInstruction based on the specified Type that will
load the specified local variable |
void |
markChunkEnd()
Mark the end of an outlineable chunk of code. |
void |
markChunkStart()
Mark the end of the method's InstructionList as the start of an outlineable chunk of code. |
private java.util.ArrayList |
mergeAdjacentChunks(MethodGenerator.Chunk[] chunks)
Merge adjacent sibling chunks to produce larger candidate chunks for outlining |
Instruction |
namespace()
|
Instruction |
nextNode()
|
(package private) boolean |
offsetInLocalVariableGenRange(LocalVariableGen lvg,
int offset)
Determines whether a particular variable is in use at a particular offset in the byte code for this method. |
private Method |
outline(InstructionHandle first,
InstructionHandle last,
java.lang.String outlinedMethodName,
ClassGenerator classGen)
Given an outlineable chunk of code in the current MethodGenerator
move ("outline") the chunk to a new method, and replace the chunk in the
old method with a reference to that new method. |
Method[] |
outlineChunks(ClassGenerator classGen,
int originalMethodSize)
Breaks up the IL for this MethodGenerator into separate
outlined methods so that no method exceeds the 64KB limit on the length
of the byte code associated with a method. |
void |
removeLocalVariable(LocalVariableGen lvg)
|
Instruction |
reset()
|
void |
setMaxLocals()
|
Instruction |
setStartNode()
|
Instruction |
startDocument()
|
Instruction |
startElement()
|
Instruction |
storeContextNode()
|
Instruction |
storeCurrentNode()
|
Instruction |
storeDOM()
|
Instruction |
storeHandler()
|
Instruction |
storeIterator()
|
private static Instruction |
storeLocal(int index,
Type type)
Helper method to generate an instance of a subclass of StoreInstruction based on the specified Type that will
store a value in the specified local variable |
Instruction |
uniqueAttribute()
|
(package private) boolean |
widenConditionalBranchTargetOffsets()
Rewrites branches to avoid the JVM limits of relative branch offsets. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected static final int INVALID_INDEX
private static final java.lang.String START_ELEMENT_SIG
private static final java.lang.String END_ELEMENT_SIG
private InstructionList _mapTypeSub
private static final int DOM_INDEX
private static final int ITERATOR_INDEX
private static final int HANDLER_INDEX
private static final int MAX_METHOD_SIZE
private static final int MAX_BRANCH_TARGET_OFFSET
private static final int MIN_BRANCH_TARGET_OFFSET
private static final int TARGET_METHOD_SIZE
private static final int MINIMUM_OUTLINEABLE_CHUNK_SIZE
private Instruction _iloadCurrent
private Instruction _istoreCurrent
private final Instruction _astoreHandler
private final Instruction _aloadHandler
private final Instruction _astoreIterator
private final Instruction _aloadIterator
private final Instruction _aloadDom
private final Instruction _astoreDom
private final Instruction _startElement
private final Instruction _endElement
private final Instruction _startDocument
private final Instruction _endDocument
private final Instruction _attribute
private final Instruction _uniqueAttribute
private final Instruction _namespace
private final Instruction _setStartNode
private final Instruction _reset
private final Instruction _nextNode
private SlotAllocator _slotAllocator
private boolean _allocatorInit
private MethodGenerator.LocalVariableRegistry _localVariableRegistry
private java.util.Hashtable _preCompiled
private int m_totalChunks
private int m_openChunks
Constructor Detail |
---|
public MethodGenerator(int access_flags, Type return_type, Type[] arg_types, java.lang.String[] arg_names, java.lang.String method_name, java.lang.String class_name, InstructionList il, ConstantPoolGen cpg)
Method Detail |
---|
public LocalVariableGen addLocalVariable(java.lang.String name, Type type, InstructionHandle start, InstructionHandle end)
public LocalVariableGen addLocalVariable2(java.lang.String name, Type type, InstructionHandle start)
private MethodGenerator.LocalVariableRegistry getLocalVariableRegistry()
boolean offsetInLocalVariableGenRange(LocalVariableGen lvg, int offset)
Preconditions:
InstructionList#setPositions()
has been called for the
InstructionList
associated with this MethodGenerator
.
lvg
- the LocalVariableGen
for the variableoffset
- the position in the byte code
true
if and only if the specified variable is in
use at the particular byte code offset.public void removeLocalVariable(LocalVariableGen lvg)
public Instruction loadDOM()
public Instruction storeDOM()
public Instruction storeHandler()
public Instruction loadHandler()
public Instruction storeIterator()
public Instruction loadIterator()
public final Instruction setStartNode()
public final Instruction reset()
public final Instruction nextNode()
public final Instruction startElement()
public final Instruction endElement()
public final Instruction startDocument()
public final Instruction endDocument()
public final Instruction attribute()
public final Instruction uniqueAttribute()
public final Instruction namespace()
public Instruction loadCurrentNode()
public Instruction storeCurrentNode()
public Instruction loadContextNode()
public Instruction storeContextNode()
public int getLocalIndex(java.lang.String name)
public LocalVariableGen getLocalVariable(java.lang.String name)
public void setMaxLocals()
public void addInstructionList(Pattern pattern, InstructionList ilist)
public InstructionList getInstructionList(Pattern pattern)
private java.util.ArrayList getCandidateChunks(ClassGenerator classGen, int totalMethodSize)
classGen
- The ClassGen
with which the generated methods
will be associatedtotalMethodSize
- the size of the bytecode in the original method
java.util.ArrayList
containing the
MethodGenerator.Chunk
s that may be outlined from this methodprivate java.util.ArrayList mergeAdjacentChunks(MethodGenerator.Chunk[] chunks)
chunks
- array of sibling MethodGenerator.Chunk
s that are
under consideration for outlining. Chunks must be in
the order encountered in the InstructionList
java.util.ArrayList
of
MethodGenerator.Chunk
s maximally mergedpublic Method[] outlineChunks(ClassGenerator classGen, int originalMethodSize)
MethodGenerator
into separate
outlined methods so that no method exceeds the 64KB limit on the length
of the byte code associated with a method.
classGen
- The ClassGen
with which the generated methods
will be associatedoriginalMethodSize
- The number of bytes of bytecode represented by
the InstructionList
of this method
Method
s and the original
method itselfprivate Method outline(InstructionHandle first, InstructionHandle last, java.lang.String outlinedMethodName, ClassGenerator classGen)
MethodGenerator
move ("outline") the chunk to a new method, and replace the chunk in the
old method with a reference to that new method. No
OutlineableChunkStart
or OutlineableChunkEnd
instructions
are copied.
first
- The InstructionHandle
of the first instruction in
the chunk to outlinelast
- The InstructionHandle
of the last instruction in
the chunk to outlineoutlinedMethodName
- The name of the new methodclassGen
- The ClassGenerator
of which the original
and new methods will be members
Method
containing the outlined code.private static Instruction loadLocal(int index, Type type)
LoadInstruction
based on the specified Type
that will
load the specified local variable
index
- the JVM stack frame index of the variable that is to be
loadedtype
- the Type
of the variable
LoadInstruction
private static Instruction storeLocal(int index, Type type)
StoreInstruction
based on the specified Type
that will
store a value in the specified local variable
index
- the JVM stack frame index of the variable that is to be
storedtype
- the Type
of the variable
StoredInstruction
public void markChunkStart()
InstructionList
as the start of an outlineable chunk of code.
The outlineable chunk begins after the InstructionHandle
that is
at the end of the method's InstructionList
, or at the start of
the method if the InstructionList
is empty.
See OutlineableChunkStart
for more information.
public void markChunkEnd()
OutlineableChunkStart
for more information.
Method[] getGeneratedMethods(ClassGenerator classGen)
Get all Method
s generated by this MethodGenerator
.
The MethodGen#getMethod()
only returns a single
Method
object. This method takes into account the Java
Virtual Machine Specification limit of 64KB on the size of a method, and
may return more than one Method
.
If the code associated with the MethodGenerator
would
exceed the 64KB limit, this method will attempt to split the code in
the InstructionList
associated with this
MethodGenerator
into several methods.
classGen
- the ClassGenerator
of which these methods are
members
Method
s generatedprotected Method getThisMethod()
boolean widenConditionalBranchTargetOffsets()
Rewrites branches to avoid the JVM limits of relative branch
offsets. There is no need to invoke this method if the bytecode for the
MethodGenerator
does not exceed 32KB.
The Java Virtual Machine Specification permits the code portion of a method to be up to 64KB in length. However, some control transfer instructions specify relative offsets as a signed 16-bit quantity, limiting the range to a subset of the instructions that might be in a method.
The TABLESWITCH
and LOOKUPSWITCH
instructions always use 32-bit signed relative offsets, so they are
immune to this problem.
The GOTO
and JSR
instructions come in two forms, one of which uses 16-bit relative
offsets, and the other of which uses 32-bit relative offsets. The BCEL
library decides whether to use the wide form of GOTO
or
JSR
instructions based on the relative offset of the target
of the instruction without any intervention by the user of the
library.
This leaves the various conditional branch instructions,
IFEQ
, IFNULL
, IF_ICMPEQ
,
et al., all of which use 16-bit signed relative offsets, with no
32-bit wide form available.
This method scans the InstructionList
associated with this
MethodGenerator
and finds all conditional branch instructions
that might exceed the 16-bit limitation for relative branch offsets.
The logic of each such instruction is inverted, and made to target the
instruction which follows it. An unconditional branch to the original
target of the instruction is then inserted between the conditional
branch and the instruction which previously followed it. The
unconditional branch is permitted to have a 16-bit or a 32-bit relative
offset, as described above. For example,
1234: NOP
...
55278: IFEQ -54044
55280: NOP
is rewritten as
1234: NOP
...
55278: IFNE 7
55280: GOTO_W -54046
55285: NOP
Preconditions:
InstructionList#setPositions()
has been called for
the InstructionList
associated with this
MethodGenerator
.
Postconditions:
InstructionList
for this
MethodGenerator
will invalidate the changes made by this
method.
true
if the InstructionList
was
modified; false
otherwiseJava Virtual Machine Specification, Second Edition
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |