use of com.android.dx.rop.cst.TypedConstant in project J2ME-Loader by nikita36078.
the class StdAttributeFactory method constantValue.
/**
* Parses a {@code ConstantValue} attribute.
*/
private Attribute constantValue(DirectClassFile cf, int offset, int length, ParseObserver observer) {
if (length != 2) {
return throwBadLength(2);
}
ByteArray bytes = cf.getBytes();
ConstantPool pool = cf.getConstantPool();
int idx = bytes.getUnsignedShort(offset);
TypedConstant cst = (TypedConstant) pool.get(idx);
Attribute result = new AttConstantValue(cst);
if (observer != null) {
observer.parsed(bytes, offset, 2, "value: " + cst);
}
return result;
}
use of com.android.dx.rop.cst.TypedConstant in project J2ME-Loader by nikita36078.
the class CfTranslator method processFields.
/**
* Processes the fields of the given class.
*
* @param cf {@code non-null;} class being translated
* @param out {@code non-null;} output class
* @param dexFile {@code non-null;} dex output
*/
private static void processFields(DirectClassFile cf, ClassDefItem out, DexFile dexFile) {
CstType thisClass = cf.getThisClass();
FieldList fields = cf.getFields();
int sz = fields.size();
for (int i = 0; i < sz; i++) {
Field one = fields.get(i);
try {
CstFieldRef field = new CstFieldRef(thisClass, one.getNat());
int accessFlags = one.getAccessFlags();
if (AccessFlags.isStatic(accessFlags)) {
TypedConstant constVal = one.getConstantValue();
EncodedField fi = new EncodedField(field, accessFlags);
if (constVal != null) {
constVal = coerceConstant(constVal, field.getType());
}
out.addStaticField(fi, constVal);
} else {
EncodedField fi = new EncodedField(field, accessFlags);
out.addInstanceField(fi);
}
Annotations annotations = AttributeTranslator.getAnnotations(one.getAttributes());
if (annotations.size() != 0) {
out.addFieldAnnotations(field, annotations, dexFile);
}
dexFile.getFieldIds().intern(field);
} catch (RuntimeException ex) {
String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
throw ExceptionWithContext.withContext(ex, msg);
}
}
}
use of com.android.dx.rop.cst.TypedConstant in project J2ME-Loader by nikita36078.
the class ConstCollector method updateConstUses.
/**
* Updates all uses of various consts to use the values in the newly
* assigned registers.
*
* @param newRegs {@code non-null;} mapping between constant and new reg
* @param origRegCount {@code >=0;} original SSA reg count, not including
* newly added constant regs
*/
private void updateConstUses(HashMap<TypedConstant, RegisterSpec> newRegs, int origRegCount) {
/*
* set of constants associated with a local variable; used
* only if COLLECT_ONE_LOCAL is true.
*/
final HashSet<TypedConstant> usedByLocal = new HashSet<TypedConstant>();
final ArrayList<SsaInsn>[] useList = ssaMeth.getUseListCopy();
for (int i = 0; i < origRegCount; i++) {
SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
if (insn == null) {
continue;
}
final RegisterSpec origReg = insn.getResult();
TypeBearer typeBearer = insn.getResult().getTypeBearer();
if (!typeBearer.isConstant())
continue;
TypedConstant cst = (TypedConstant) typeBearer;
final RegisterSpec newReg = newRegs.get(cst);
if (newReg == null) {
continue;
}
if (ssaMeth.isRegALocal(origReg)) {
if (!COLLECT_ONE_LOCAL) {
continue;
} else {
/*
* TODO: If the same local gets the same cst
* multiple times, it would be nice to reuse the
* register.
*/
if (usedByLocal.contains(cst)) {
continue;
} else {
usedByLocal.add(cst);
fixLocalAssignment(origReg, newRegs.get(cst));
}
}
}
// maps an original const register to the new collected register
RegisterMapper mapper = new RegisterMapper() {
@Override
public int getNewRegisterCount() {
return ssaMeth.getRegCount();
}
@Override
public RegisterSpec map(RegisterSpec registerSpec) {
if (registerSpec.getReg() == origReg.getReg()) {
return newReg.withLocalItem(registerSpec.getLocalItem());
}
return registerSpec;
}
};
for (SsaInsn use : useList[origReg.getReg()]) {
if (use.canThrow() && use.getBlock().getSuccessors().cardinality() > 1) {
continue;
}
use.mapSourceRegisters(mapper);
}
}
}
use of com.android.dx.rop.cst.TypedConstant in project J2ME-Loader by nikita36078.
the class ConstCollector method run.
/**
* Applies the optimization.
*/
private void run() {
int regSz = ssaMeth.getRegCount();
ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
SsaBasicBlock start = ssaMeth.getEntryBlock();
// Constant to new register containing the constant
HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
for (int i = 0; i < toCollect; i++) {
TypedConstant cst = constantList.get(i);
RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
Rop constRop = Rops.opConst(cst);
if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
} else {
// We need two new basic blocks along with the new insn
SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
// Insert a block containing the const insn.
SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
// Insert a block containing the move-result-pseudo insn.
SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
resultBlock.addInsnToHead(insn);
}
newRegs.put(cst, result);
}
updateConstUses(newRegs, regSz);
}
use of com.android.dx.rop.cst.TypedConstant in project J2ME-Loader by nikita36078.
the class EscapeAnalysis method replaceDef.
/**
* Replaces the instructions that define an array with equivalent registers.
* For each entry in the array, a register is created, initialized to zero.
* A mapping between this register and the corresponding array index is
* added.
*
* @param def {@code non-null;} move result instruction for array
* @param prev {@code non-null;} instruction for instantiating new array
* @param length size of the new array
* @param newRegs {@code non-null;} mapping of array indices to new
* registers to be populated
*/
private void replaceDef(SsaInsn def, SsaInsn prev, int length, ArrayList<RegisterSpec> newRegs) {
Type resultType = def.getResult().getType();
// Create new zeroed out registers for each element in the array
for (int i = 0; i < length; i++) {
Constant newZero = Zeroes.zeroFor(resultType.getComponentType());
TypedConstant typedZero = (TypedConstant) newZero;
RegisterSpec newReg = RegisterSpec.make(ssaMeth.makeNewSsaReg(), typedZero);
newRegs.add(newReg);
insertPlainInsnBefore(def, RegisterSpecList.EMPTY, newReg, RegOps.CONST, newZero);
}
}
Aggregations