org.apache.xalan.xsltc.compiler.util
Class MethodGenerator

java.lang.Object
  extended by MethodGen
      extended by org.apache.xalan.xsltc.compiler.util.MethodGenerator
All Implemented Interfaces:
Constants
Direct Known Subclasses:
AttributeSetMethodGenerator, CompareGenerator, MatchGenerator, NamedMethodGenerator, RtMethodGenerator, TestGenerator

public class MethodGenerator
extends MethodGen
implements Constants


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
           
 
Fields inherited from interface org.apache.xalan.xsltc.compiler.Constants
ABSOLUTE_ITERATOR, ACC_FINAL, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_SUPER, ADD_ATTRIBUTE, ADD_ATTRIBUTE_SIG, ADD_ITERATOR, ADD_ITERATOR_SIG, ADD_PARAMETER, ADD_PARAMETER_SIG, APPLY_TEMPLATES, ATTR_SET_SIG, ATTRIBUTE_LIST_FIELD, ATTRIBUTE_LIST_IMPL_CLASS, ATTRIBUTE_LIST_IMPL_SIG, ATTRIBUTES_SIG, BASIS_LIBRARY_CLASS, BOOLEAN_CLASS, BOOLEAN_VALUE, BOOLEAN_VALUE_SIG, CACHED_NODE_LIST_ITERATOR_CLASS, CHARACTERS, CHARACTERS_SIG, CHARACTERSW, CHARACTERSW_SIG, CLEAR_ATTRIBUTES, CLEAR_ATTRIBUTES_SIG, COLLATOR_CLASS, COLLATOR_SIG, COMPILER_PACKAGE, CURRENT_NODE_LIST_FILTER, CURRENT_NODE_LIST_FILTER_SIG, CURRENT_NODE_LIST_ITERATOR, CURRENT_NODE_LIST_ITERATOR_SIG, DEFAULT_NODE_COUNTER, DEFAULT_NODE_COUNTER_SIG, DOCUMENT_PNAME, DOM_ADAPTER_CLASS, DOM_ADAPTER_SIG, DOM_FIELD, DOM_IMPL, DOM_IMPL_CLASS, DOM_IMPL_SIG, DOM_INTF, DOM_INTF_SIG, DOM_PNAME, DOUBLE_CLASS, DOUBLE_SIG, DOUBLE_VALUE, DOUBLE_VALUE_SIG, DUP_FILTERED_ITERATOR, EMPTYATTR_FIELD, EMPTYSTRING, ERROR, EXPAND_STYLESHEET_QNAME_REF, EXPAND_STYLESHEET_QNAME_SIG, FALLBACK_CLASS, FATAL, FILTER_INTERFACE, FILTER_INTERFACE_SIG, FILTER_ITERATOR, FILTER_STEP_ITERATOR, FORMAT_SYMBOLS_FIELD, GET_ATTRIBUTE_VALUE, GET_ATTRIBUTE_VALUE_SIG, GET_CHILDREN, GET_CHILDREN_SIG, GET_ELEMENT_VALUE, GET_ELEMENT_VALUE_SIG, GET_ITERATOR_SIG, GET_NODE_NAME, GET_NODE_NAME_SIG, GET_NODE_TYPE, GET_NODE_TYPE_SIG, GET_NODE_VALUE, GET_NODE_VALUE_ITERATOR, GET_NODE_VALUE_ITERATOR_SIG, GET_NODE_VALUE_SIG, GET_PARAMETER, GET_PARAMETER_SIG, GET_PARENT, GET_PARENT_SIG, GET_TYPED_CHILDREN, GET_TYPED_CHILDREN_SIG, GET_UNPARSED_ENTITY_URI, GET_UNPARSED_ENTITY_URI_SIG, HAS_ATTRIBUTE, HAS_ATTRIBUTE_SIG, HASIDCALL_INDEX, HASIDCALL_INDEX_SIG, INT_VALUE, INT_VALUE_SIG, INTEGER_CLASS, INTEGER_SIG, INTERNAL, INVOKE_METHOD, ITERATOR_FIELD_SIG, ITERATOR_PNAME, KEY_INDEX_CLASS, KEY_INDEX_ITERATOR_SIG, KEY_INDEX_SIG, LAST_INDEX, LOAD_DOCUMENT_CLASS, LOCALE_CLASS, LOCALE_SIG, LOOKUP_STYLESHEET_QNAME_NS_REF, LOOKUP_STYLESHEET_QNAME_NS_SIG, MAKE_NODE, MAKE_NODE_LIST, MAKE_NODE_LIST_SIG, MAKE_NODE_LIST_SIG2, MAKE_NODE_SIG, MAKE_NODE_SIG2, MATCHING_ITERATOR, MATH_CLASS, MULTI_DOM_CLASS, MULTI_DOM_SIG, NAMES_INDEX, NAMES_INDEX_SIG, NAMESPACE_FEATURE, NAMESPACE_INDEX, NAMESPACE_INDEX_SIG, NEXT, NEXT_SIG, NEXTID, NODE, NODE_COUNTER, NODE_COUNTER_SIG, NODE_FIELD, NODE_FIELD_SIG, NODE_ITERATOR, NODE_ITERATOR_BASE, NODE_ITERATOR_SIG, NODE_PNAME, NODE_SIG, NODE_SORT_FACTORY, NODE_SORT_FACTORY_SIG, NODE_SORT_RECORD, NODE_SORT_RECORD_SIG, NS_ANCESTORS_INDEX_SIG, NTH_ITERATOR_CLASS, OBJECT_CLASS, OBJECT_SIG, ORDER_ITERATOR, ORDER_ITERATOR_SIG, OUTPUT_BASE, OUTPUT_HANDLER, OUTPUT_HANDLER_SIG, POP_PARAM_FRAME, POP_PARAM_FRAME_SIG, POSITION_INDEX, PREFIX_URIS_ARRAY_SIG, PREFIX_URIS_IDX_SIG, PUSH_PARAM_FRAME, PUSH_PARAM_FRAME_SIG, REDIRECT_URI, RESET, RESET_SIG, RTF_INITIAL_SIZE, RUNTIME_NODE_CLASS, RUNTIME_PACKAGE, SAX_IMPL, SAX_IMPL_CLASS, SAX_IMPL_SIG, SET_START_NODE, SET_START_NODE_SIG, SINGLETON_ITERATOR, SORT_ITERATOR, SORT_ITERATOR_SIG, STATIC_CHAR_DATA_FIELD, STATIC_CHAR_DATA_FIELD_SIG, STATIC_NAMES_ARRAY_FIELD, STATIC_NAMESPACE_ARRAY_FIELD, STATIC_NS_ANCESTORS_ARRAY_FIELD, STATIC_PREFIX_URIS_ARRAY_FIELD, STATIC_PREFIX_URIS_IDX_ARRAY_FIELD, STATIC_TYPES_ARRAY_FIELD, STATIC_URIS_ARRAY_FIELD, STEP_ITERATOR_CLASS, STREAM_XML_OUTPUT, STRING, STRING_BUFFER_CLASS, STRING_BUFFER_SIG, STRING_CLASS, STRING_SIG, STRING_TO_INT, STRING_TO_INT_SIG, STRING_TO_REAL, STRING_TO_REAL_SIG, STRING_VALUE_HANDLER, STRING_VALUE_HANDLER_SIG, STRING_WRITER, STRIP_SPACE, STRIP_SPACE_INTF, STRIP_SPACE_PARAMS, STRIP_SPACE_SIG, TRANSLET_CLASS, TRANSLET_FIELD, TRANSLET_FIELD_SIG, TRANSLET_INTF, TRANSLET_INTF_SIG, TRANSLET_OUTPUT_BASE, TRANSLET_OUTPUT_INTERFACE, TRANSLET_OUTPUT_PNAME, TRANSLET_OUTPUT_SIG, TRANSLET_PNAME, TRANSLET_SIG, TRANSLET_URI, TRANSLET_VERSION_INDEX, TRANSLET_VERSION_INDEX_SIG, TYPES_INDEX, TYPES_INDEX_SIG, UNION_ITERATOR_CLASS, UNION_ITERATOR_SIG, UNSUPPORTED, URIS_INDEX, URIS_INDEX_SIG, WARNING, WRITER_SIG, XHTML_URI, XMLNS_PREFIX, XMLNS_STRING, XMLNS_URI, XSLT_PACKAGE, XSLT_URI
 
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 Methods 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

INVALID_INDEX

protected static final int INVALID_INDEX
See Also:
Constant Field Values

START_ELEMENT_SIG

private static final java.lang.String START_ELEMENT_SIG
See Also:
Constant Field Values

END_ELEMENT_SIG

private static final java.lang.String END_ELEMENT_SIG
See Also:
Constant Field Values

_mapTypeSub

private InstructionList _mapTypeSub

DOM_INDEX

private static final int DOM_INDEX
See Also:
Constant Field Values

ITERATOR_INDEX

private static final int ITERATOR_INDEX
See Also:
Constant Field Values

HANDLER_INDEX

private static final int HANDLER_INDEX
See Also:
Constant Field Values

MAX_METHOD_SIZE

private static final int MAX_METHOD_SIZE
See Also:
Constant Field Values

MAX_BRANCH_TARGET_OFFSET

private static final int MAX_BRANCH_TARGET_OFFSET
See Also:
Constant Field Values

MIN_BRANCH_TARGET_OFFSET

private static final int MIN_BRANCH_TARGET_OFFSET
See Also:
Constant Field Values

TARGET_METHOD_SIZE

private static final int TARGET_METHOD_SIZE
See Also:
Constant Field Values

MINIMUM_OUTLINEABLE_CHUNK_SIZE

private static final int MINIMUM_OUTLINEABLE_CHUNK_SIZE
See Also:
Constant Field Values

_iloadCurrent

private Instruction _iloadCurrent

_istoreCurrent

private Instruction _istoreCurrent

_astoreHandler

private final Instruction _astoreHandler

_aloadHandler

private final Instruction _aloadHandler

_astoreIterator

private final Instruction _astoreIterator

_aloadIterator

private final Instruction _aloadIterator

_aloadDom

private final Instruction _aloadDom

_astoreDom

private final Instruction _astoreDom

_startElement

private final Instruction _startElement

_endElement

private final Instruction _endElement

_startDocument

private final Instruction _startDocument

_endDocument

private final Instruction _endDocument

_attribute

private final Instruction _attribute

_uniqueAttribute

private final Instruction _uniqueAttribute

_namespace

private final Instruction _namespace

_setStartNode

private final Instruction _setStartNode

_reset

private final Instruction _reset

_nextNode

private final Instruction _nextNode

_slotAllocator

private SlotAllocator _slotAllocator

_allocatorInit

private boolean _allocatorInit

_localVariableRegistry

private MethodGenerator.LocalVariableRegistry _localVariableRegistry

_preCompiled

private java.util.Hashtable _preCompiled
A mapping between patterns and instruction lists used by test sequences to avoid compiling the same pattern multiple times. Note that patterns whose kernels are "*", "node()" and "@*" can between shared by test sequences.


m_totalChunks

private int m_totalChunks
Track the number of outlineable chunks seen.


m_openChunks

private int m_openChunks
Track the number of outlineable chunks started but not yet ended. Used to detect imbalances in byte code generation.

Constructor Detail

MethodGenerator

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

addLocalVariable

public LocalVariableGen addLocalVariable(java.lang.String name,
                                         Type type,
                                         InstructionHandle start,
                                         InstructionHandle end)
Allocates a local variable. If the slot allocator has already been initialized, then call addLocalVariable2() so that the new variable is known to the allocator. Failing to do this may cause the allocator to return a slot that is already in use.


addLocalVariable2

public LocalVariableGen addLocalVariable2(java.lang.String name,
                                          Type type,
                                          InstructionHandle start)

getLocalVariableRegistry

private MethodGenerator.LocalVariableRegistry getLocalVariableRegistry()

offsetInLocalVariableGenRange

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.

Preconditions:

Parameters:
lvg - the LocalVariableGen for the variable
offset - the position in the byte code
Returns:
true if and only if the specified variable is in use at the particular byte code offset.

removeLocalVariable

public void removeLocalVariable(LocalVariableGen lvg)

loadDOM

public Instruction loadDOM()

storeDOM

public Instruction storeDOM()

storeHandler

public Instruction storeHandler()

loadHandler

public Instruction loadHandler()

storeIterator

public Instruction storeIterator()

loadIterator

public Instruction loadIterator()

setStartNode

public final Instruction setStartNode()

reset

public final Instruction reset()

nextNode

public final Instruction nextNode()

startElement

public final Instruction startElement()

endElement

public final Instruction endElement()

startDocument

public final Instruction startDocument()

endDocument

public final Instruction endDocument()

attribute

public final Instruction attribute()

uniqueAttribute

public final Instruction uniqueAttribute()

namespace

public final Instruction namespace()

loadCurrentNode

public Instruction loadCurrentNode()

storeCurrentNode

public Instruction storeCurrentNode()

loadContextNode

public Instruction loadContextNode()
by default context node is the same as current node. MK437


storeContextNode

public Instruction storeContextNode()

getLocalIndex

public int getLocalIndex(java.lang.String name)

getLocalVariable

public LocalVariableGen getLocalVariable(java.lang.String name)

setMaxLocals

public void setMaxLocals()

addInstructionList

public void addInstructionList(Pattern pattern,
                               InstructionList ilist)
Add a pre-compiled pattern to this mode.


getInstructionList

public InstructionList getInstructionList(Pattern pattern)
Get the instruction list for a pre-compiled pattern. Used by test sequences to avoid compiling patterns more than once.


getCandidateChunks

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.

Parameters:
classGen - The ClassGen with which the generated methods will be associated
totalMethodSize - the size of the bytecode in the original method
Returns:
a java.util.ArrayList containing the MethodGenerator.Chunks that may be outlined from this method

mergeAdjacentChunks

private java.util.ArrayList mergeAdjacentChunks(MethodGenerator.Chunk[] chunks)
Merge adjacent sibling chunks to produce larger candidate chunks for outlining

Parameters:
chunks - array of sibling MethodGenerator.Chunks that are under consideration for outlining. Chunks must be in the order encountered in the InstructionList
Returns:
a java.util.ArrayList of MethodGenerator.Chunks maximally merged

outlineChunks

public 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.

Parameters:
classGen - The ClassGen with which the generated methods will be associated
originalMethodSize - The number of bytes of bytecode represented by the InstructionList of this method
Returns:
an array of the outlined Methods and the original method itself

outline

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. No OutlineableChunkStart or OutlineableChunkEnd instructions are copied.

Parameters:
first - The InstructionHandle of the first instruction in the chunk to outline
last - The InstructionHandle of the last instruction in the chunk to outline
outlinedMethodName - The name of the new method
classGen - The ClassGenerator of which the original and new methods will be members
Returns:
The new Method containing the outlined code.

loadLocal

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

Parameters:
index - the JVM stack frame index of the variable that is to be loaded
type - the Type of the variable
Returns:
the generated LoadInstruction

storeLocal

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

Parameters:
index - the JVM stack frame index of the variable that is to be stored
type - the Type of the variable
Returns:
the generated StoredInstruction

markChunkStart

public void markChunkStart()
Mark the end of the method's 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.


markChunkEnd

public void markChunkEnd()
Mark the end of an outlineable chunk of code. See OutlineableChunkStart for more information.


getGeneratedMethods

Method[] getGeneratedMethods(ClassGenerator classGen)

Get all Methods 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.

Parameters:
classGen - the ClassGenerator of which these methods are members
Returns:
an array of all the Methods generated

getThisMethod

protected Method getThisMethod()

widenConditionalBranchTargetOffsets

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 JSRinstructions 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:

Postconditions:

Returns:
true if the InstructionList was modified; false otherwise
See Also:
Java Virtual Machine Specification, Second Edition