public Instruction shrink() { opcode = canonicalOpcode(); // Is this instruction pointing to a variable with index from 0 to 3? if (variableIndex <= 3) { switch (opcode) { case InstructionConstants.OP_ILOAD: opcode = (byte)(InstructionConstants.OP_ILOAD_0 + variableIndex); break; case InstructionConstants.OP_LLOAD: opcode = (byte)(InstructionConstants.OP_LLOAD_0 + variableIndex); break; case InstructionConstants.OP_FLOAD: opcode = (byte)(InstructionConstants.OP_FLOAD_0 + variableIndex); break; case InstructionConstants.OP_DLOAD: opcode = (byte)(InstructionConstants.OP_DLOAD_0 + variableIndex); break; case InstructionConstants.OP_ALOAD: opcode = (byte)(InstructionConstants.OP_ALOAD_0 + variableIndex); break; case InstructionConstants.OP_ISTORE: opcode = (byte)(InstructionConstants.OP_ISTORE_0 + variableIndex); break; case InstructionConstants.OP_LSTORE: opcode = (byte)(InstructionConstants.OP_LSTORE_0 + variableIndex); break; case InstructionConstants.OP_FSTORE: opcode = (byte)(InstructionConstants.OP_FSTORE_0 + variableIndex); break; case InstructionConstants.OP_DSTORE: opcode = (byte)(InstructionConstants.OP_DSTORE_0 + variableIndex); break; case InstructionConstants.OP_ASTORE: opcode = (byte)(InstructionConstants.OP_ASTORE_0 + variableIndex); break; } } // Only make the instruction wide if necessary. wide = requiredVariableIndexSize() > 1 || requiredConstantSize() > 1; return this; }
protected void writeInfo(byte[] code, int offset) { int variableIndexSize = variableIndexSize(); int constantSize = constantSize(); if (requiredVariableIndexSize() > variableIndexSize) { throw new IllegalArgumentException("Instruction has invalid variable index size ("+this.toString(offset)+")"); } if (requiredConstantSize() > constantSize) { throw new IllegalArgumentException("Instruction has invalid constant size ("+this.toString(offset)+")"); } writeValue(code, offset, variableIndex, variableIndexSize); offset += variableIndexSize; writeSignedValue(code, offset, constant, constantSize); }
public VariableInstruction(byte opcode) { this(opcode, embeddedVariable(opcode), 0); }
public String toString() { return getName() + (wide ? "_w" : "") + " v"+variableIndex + (constantSize() > 0 ? ", "+constant : ""); }
public int length(int offset) { return (wide ? 2 : 1) + variableIndexSize() + constantSize(); }
protected void readInfo(byte[] code, int offset) { int variableIndexSize = variableIndexSize(); int constantSize = constantSize(); // Also initialize embedded variable indexes. if (variableIndexSize == 0) { // An embedded variable index can be decoded as follows. variableIndex = opcode < InstructionConstants.OP_ISTORE_0 ? (opcode - InstructionConstants.OP_ILOAD_0 ) & 3 : (opcode - InstructionConstants.OP_ISTORE_0) & 3; } else { variableIndex = readValue(code, offset, variableIndexSize); offset += variableIndexSize; } constant = readSignedValue(code, offset, constantSize); }
public InstructionSequenceBuilder iinc(int variableIndex, int constant) { return add(new VariableInstruction(InstructionConstants.OP_IINC, variableIndex, constant)); }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { if (partialEvaluator.isTraced(offset) && variableInstruction.isLoad()) { int variableIndex = variableInstruction.variableIndex; if (variableIndex < codeAttribute.u2maxLocals) { // The parameter indices stored in the producer values are // parameter offsets, taking into account Category 2 types, // and therefore compatible with variable indices. Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex); if (producer != null && producer.instructionOffsetValue().contains(variableIndex | InstructionOffsetValue.METHOD_PARAMETER)) { // Mark the variable. markParameterUsed(method, variableIndex); // Account for Category 2 instructions, which take up two entries. if (variableInstruction.stackPopCount(clazz) == 2 || variableInstruction.stackPushCount(clazz) == 2) { markParameterUsed(method, variableIndex + 1); } } } } }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { // Write out the instruction. instructionWriter.visitVariableInstruction(clazz, method, codeAttribute, newOffset, variableInstruction); newOffset += variableInstruction.length(newOffset); }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { // Is the variable being loaded or incremented? if (variableInstruction.isLoad()) { markVariableProducers(offset, variableInstruction.variableIndex); } else { markStackProducers(clazz, offset, variableInstruction); } }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { if (partialEvaluator.isTraced(offset) && variableInstruction.isLoad()) { int parameterIndex = variableInstruction.variableIndex; if (parameterIndex < codeAttribute.u2maxLocals) { Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(parameterIndex); if (producer != null && producer.instructionOffsetValue().contains(PartialEvaluator.AT_METHOD_ENTRY)) { // Mark the variable. markParameterUsed(method, parameterIndex); // Account for Category 2 instructions, which take up two entries. if (variableInstruction.isCategory2()) { markParameterUsed(method, parameterIndex + 1); } } } } }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { // Mark the variable. variableUsed[variableInstruction.variableIndex] = true; // Account for Category 2 instructions, which take up two entries. if (variableInstruction.isCategory2()) { variableUsed[variableInstruction.variableIndex + 1] = true; } } }
protected void readInfo(byte[] code, int offset) { int variableIndexSize = variableIndexSize(); int constantSize = constantSize(); // Also initialize embedded variable indexes. if (variableIndexSize == 0) { // An embedded variable index can be decoded as follows. variableIndex = opcode < InstructionConstants.OP_ISTORE_0 ? (opcode - InstructionConstants.OP_ILOAD_0 ) & 3 : (opcode - InstructionConstants.OP_ISTORE_0) & 3; } else { variableIndex = readValue(code, offset, variableIndexSize); offset += variableIndexSize; } constant = readSignedValue(code, offset, constantSize); }
public CompactCodeAttributeComposer iinc(int variableIndex, int constant) { return add(new VariableInstruction(InstructionConstants.OP_IINC, variableIndex, constant)); }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { if (partialEvaluator.isTraced(offset) && variableInstruction.isLoad()) { int variableIndex = variableInstruction.variableIndex; if (variableIndex < codeAttribute.u2maxLocals) { // The parameter indices stored in the producer values are // parameter offsets, taking into account Category 2 types, // and therefore compatible with variable indices. Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex); if (producer != null && producer.instructionOffsetValue().contains(variableIndex | InstructionOffsetValue.METHOD_PARAMETER)) { // Mark the variable. markParameterUsed(method, variableIndex); // Account for Category 2 instructions, which take up two entries. if (variableInstruction.stackPopCount(clazz) == 2 || variableInstruction.stackPushCount(clazz) == 2) { markParameterUsed(method, variableIndex + 1); } } } } }
public String toString() { return getName() + (wide ? "_w" : "") + " v"+variableIndex + (constantSize() > 0 ? ", "+constant : ""); }
public int length(int offset) { return (wide ? 2 : 1) + variableIndexSize() + constantSize(); }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { // Write out the instruction. instructionWriter.visitVariableInstruction(clazz, method, codeAttribute, newOffset, variableInstruction); newOffset += variableInstruction.length(newOffset); }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { // Is the variable being loaded or incremented? if (variableInstruction.isLoad()) { // Mark any variable initializations for this variable load that // are required according to the JVM. markVariableInitializersBefore(offset, variableInstruction.variableIndex, null); } } }
public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) { int variableSize = variableInstruction.variableIndex + 1; if (variableInstruction.isCategory2()) { variableSize++; } if (codeAttribute.u2maxLocals < variableSize) { codeAttribute.u2maxLocals = variableSize; if (DEBUG) { System.out.println(" Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset)); } } } }