public class MethodModel extends Object
Modifier and Type | Class and Description |
---|---|
static class |
MethodModel.FakeLocalVariableTableEntry |
public boolean isGetter()
public boolean isSetter()
public boolean methodUsesPutfield()
public boolean isNoCL()
public boolean isPrivateMemoryGetter()
public ClassModel.ClassModelMethod getMethod()
public ClassModel.ConstantPool.FieldEntry getAccessorVariableFieldEntry()
public Set<MethodModel> getCalledMethods()
public void checkForRecursion(Set<MethodModel> transitiveCalledMethods) throws AparapiException
AparapiException
public void setRequiredPragmas(Instruction instruction)
public boolean requiresDoublePragma()
public boolean requiresByteAddressableStorePragma()
public Map<Integer,Instruction> createListOfInstructions() throws ClassParseException
ClassParseException
public void buildBranchGraphs(Map<Integer,Instruction> pcMap)
Each branch node contains a 'target' field indended to reference the node that the branch targets. Each instruction also contain four seperate lists of branch nodes that reference it. These lists hold forwardConditional, forwardUnconditional, reverseConditional and revereseUnconditional branches that reference it.
So assuming that we had a branch node at pc offset 100 which represented 'goto 200'.
Following this call the branch node at pc offset 100 will have a 'target' field which actually references the instruction at pc offset 200, and the instruction at pc offset 200 will have the branch node (at 100) added to it's forwardUnconditional list.
InstructionSet.Branch#getTarget()
public void deoptimizeReverseBranches()
public void txFormDups(ExpressionList _expressionList, Instruction _instruction) throws ClassParseException
Here we replace DUP style instructions with a 'mock' instruction which 'clones' the effect of the instruction. This would be invalid to execute but is useful to replace the DUP with a 'pattern' which it simulates. This allows us to later apply transforms to represent the original code.
An example might be the bytecode for the following sequence.
Which results in the following bytecode
results[10]++;
return
First we need to know what the stack will look like before the dup2 is encountered.
Using our folding technique we represent the first two instructions inside ()
0: aload_0 // reference through 'this' to get
1: getfield // field 'results' which is an array of int
4: bipush 10 // push the array index
6: dup2 // dreaded dup2 we'll come back here
7: iaload // ignore for the moment.
8: iconst_1
9: iadd
10: iastore
11: return
getfield (aload_0 // result in the array field reference on stack
bipush 10 // the array index
dup2 // dreaded dup2 we'll come back here
The dup2
essentially copies the top two elements on the stack. So we emulate this by replacing the dup2 with clones of the instructions which would reinstate the same stack state.
So after the dup2
transform we end up with:-
getfield (aload_0) // result in the array field reference on stack
bipush 10 // the array index
{getfield (aload_0)} // result in the array field reference on stack
{bipush 10} // the array index
So carrying on lets look at the iaload
which consumes two operands (the index and the array field reference) and creates one (the result of an array access)
getfield (aload_0) // result in the array field reference on stack
bipush 10 // the array index
{getfield (aload_0)} // result in the array field reference on stack
{bipush 10} // the array index
iaload
So we now have
getfield (aload_0) // result in the array field reference on stack
bipush 10 // the array index
iaload ({getfield(aload_0), {bipush 10}) // results in the array element on the stack
iconst
iadd
And if you are following along the iadd
will fold the previous two stack entries essentially pushing the result of
results[10]+1 on the stack.
getfield (aload_0) // result in the array field reference on stack
bipush 10 // the array index
iadd (iaload ({getfield(aload_0), {bipush 10}, iconst_1) // push of results[10]+1
Then the final istore
instruction which consumes 3 stack operands (the field array reference, the index and the value to assign).
Which results in
istore (getfield (aload_0), bipush 10, iadd (iaload ({getfield(aload_0), {bipush 10}, iconst_1)) // results[10] = results[10+1]
Where results[10] = results[10+1] is the long-hand form of the results[10]++
and will be transformed by one of the 'inc' transforms to the more familiar form a little later.
_expressionList
- _instruction
- ClassParseException
public ClassModel.LocalVariableTableEntry<ClassModel.LocalVariableInfo> getLocalVariableTableEntry()
public ClassModel.ConstantPool getConstantPool()
public ClassModel.LocalVariableInfo getLocalVariable(int _pc, int _index)
public String getSimpleName()
public String getName()
public String getReturnType()
public List<InstructionSet.MethodCall> getMethodCalls()
public Instruction getPCHead()
public Instruction getExprHead()
Copyright © 2016 Syncleus. All rights reserved.