private void generateSelfGetMethodCase(MethodBuilder builder, int labelIdx, MemberRef field) { Class wrapper = null; if (field.type().isPrimitive()) { wrapper = PrimitiveUtil.wrapper(field.type()); } builder.aload(1); builder.ldc(field.name()); builder.invokeVirtual( Type.STRING, BloatJ2MEContext.EQUALS_METHODNAME, new Type[] {Type.OBJECT}, Type.BOOLEAN); builder.ifeq(labelIdx + 1); if (wrapper != null) { builder.newRef(wrapper); builder.dup(); } builder.aload(0); builder.getfield(field); if (wrapper != null) { builder.invokeSpecial( _context.getType(wrapper), BloatJ2MEContext.INIT_METHODNAME, new Type[] {field.type()}, Type.VOID); } builder.areturn(); builder.label(labelIdx + 1); }
private void generateSelfSetFieldCase(MethodBuilder builder, int labelIdx, MemberRef field) { Type fieldType = field.type(); Class wrapper = PrimitiveUtil.wrapper(fieldType); builder.aload(1); builder.ldc(field.name()); builder.invokeVirtual( Type.STRING, BloatJ2MEContext.EQUALS_METHODNAME, new Type[] {Type.OBJECT}, Type.BOOLEAN); builder.ifeq(labelIdx + 1); builder.aload(0); builder.aload(2); if (wrapper != null) { builder.checkcast(wrapper); builder.invokeVirtual( _context.getType(wrapper), PrimitiveUtil.conversionFunctionName(wrapper), new Type[0], fieldType); } else { builder.checkcast(fieldType); } builder.putfield(field); builder.returnInstruction(); builder.label(labelIdx + 1); }
public FieldNode field(MemberRef ref) { for (ClassNode c : classes()) { if (ref.declaringClass().equals(Type.getType("L" + c.name() + ";"))) { for (FieldNode f : c.fields()) { if (ref.nameAndType().equals(f.editor.nameAndType())) { return f; } } } } return null; }
public int compare(final Object o1, final Object o2) { Assert.isTrue(o1 instanceof MemberRef, o1 + " is not a MemberRef!"); Assert.isTrue(o2 instanceof MemberRef, o2 + " is not a MemberRef!"); final MemberRef me1 = (MemberRef) o1; final MemberRef me2 = (MemberRef) o2; final String s1 = me1.declaringClass() + "." + me1.name() + me1.type(); final String s2 = me2.declaringClass() + "." + me2.name() + me2.type(); return (s1.compareTo(s2)); }
/** * Inserts residency/update/swizzle checks into a method. Iterates over the bytecodes in the * method and inserts the appropriate residency opcode. * * @param method The method to which to add checks. * @see MethodEditor#code */ private static void transform(final MethodEditor method) { if (Main.VERBOSE > 1) { System.out.println("Decorating method " + method); } // Optimize initialization of arrays to speed things up. CompactArrayInitializer.transform(method); final ListIterator iter = method.code().listIterator(); // Go through the code (Instructions and Labels) in the method INST: while (iter.hasNext()) { final Object ce = iter.next(); if (Main.VERBOSE > 2) { System.out.println("Examining " + ce); } if (ce instanceof Instruction) { final Instruction inst = (Instruction) ce; int uctype = Main.NONE; // Type of update check (POINTER or // SCALAR) boolean insert_sc = false; // Insert swizzle check (aaload // only)? final int opc = inst.opcodeClass(); int depth; switch (opc) { case opcx_arraylength: case opcx_athrow: case opcx_getfield: case opcx_instanceof: { depth = 0; break; } case opcx_iaload: case opcx_laload: case opcx_faload: case opcx_daload: case opcx_baload: case opcx_caload: case opcx_saload: { depth = 1; break; } case opcx_aaload: { depth = 1; insert_sc = true; break; } case opcx_iastore: case opcx_fastore: case opcx_aastore: case opcx_bastore: case opcx_castore: case opcx_sastore: { depth = 2; break; } case opcx_lastore: case opcx_dastore: { depth = 3; break; } case opcx_putfield: { final MemberRef ref = (MemberRef) inst.operand(); depth = ref.type().stackHeight(); if (ref.type().isReference()) { uctype = Main.POINTER; } else { uctype = Main.SCALAR; } break; } case opcx_invokevirtual: case opcx_invokespecial: case opcx_invokeinterface: { final MemberRef ref = (MemberRef) inst.operand(); depth = ref.type().stackHeight(); break; } case opcx_rc: { // Skip any existing residency checks. iter.remove(); continue INST; } case opcx_aupdate: { // Skip any existing update checks. iter.remove(); continue INST; } case opcx_supdate: { // Skip any existing update checks. iter.remove(); continue INST; } default: { continue INST; } } Instruction addInst; // Insert a residency check... if (Main.RC) { Object t; // ////////////////////////////////// // Before... // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next // // After... // +-----+----+------+-----------+ // | ... | RC | inst | afterInst | // +-----+----+------+-----------+ // ^prev ^next // ////////////////////////////////// // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next addInst = new Instruction(Opcode.opcx_rc, new Integer(depth)); iter.add(addInst); // +-----+----+------+-----------+ // | ... | RC | inst | afterInst | // +-----+----+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+----+------+-----------+ // | ... | RC | inst | afterInst | // +-----+----+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+----+------+-----------+ // | ... | RC | inst | afterInst | // +-----+----+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+----+------+-----------+ // | ... | RC | inst | afterInst | // +-----+----+------+-----------+ // ^prev ^next if (Main.VERBOSE > 2) { System.out.println("Inserting " + addInst + " before " + inst); } } else { if (Main.VERBOSE > 2) { System.out.println("Not inserting rc before " + inst); } } // Insert a swizzle check... if (insert_sc) { if (Main.SC) { Object t; // //////////////////////////////////////////// // Before... // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next // // After... // +-----+------+----------+------+-----------+ // | ... | dup2 | aswizzle | inst | afterInst | // +-----+------+----------+------+-----------+ // ^prev ^next // ///////////////////////////////////////////// // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next addInst = new Instruction(Opcode.opcx_dup2); iter.add(addInst); // +-----+------+------+-----------+ // | ... | dup2 | inst | afterInst | // +-----+------+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+------+------+-----------+ // | ... | dup2 | inst | afterInst | // +-----+------+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+------+------+-----------+ // | ... | dup2 | inst | afterInst | // +-----+------+------+-----------+ // ^prev ^next addInst = new Instruction(Opcode.opcx_aswizzle); iter.add(addInst); // +-----+------+----------+------+-----------+ // | ... | dup2 | aswizzle | inst | afterInst | // +-----+------+----------+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+------+----------+------+-----------+ // | ... | dup2 | aswizzle | inst | afterInst | // +-----+------+----------+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+------+----------+------+-----------+ // | ... | dup2 | aswizzle | inst | afterInst | // +-----+------+----------+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+------+----------+------+-----------+ // | ... | dup2 | aswizzle | inst | afterInst | // +-----+------+----------+------+-----------+ // ^prev ^next if (Main.VERBOSE > 2) { System.out.println("Inserting dup2,aswizzle before " + inst); } } else { if (Main.VERBOSE > 2) { System.out.println("Not inserting aswizzle before " + inst); } } } // Insert an update check... if (uctype != Main.NONE) { if (Main.UC) { Object t; // //////////////////////////////////////////// // Before... // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next // // After... // +-----+---------+------+-----------+ // | ... | aupdate | inst | afterInst | // +-----+---------+------+-----------+ // ^prev ^next // ///////////////////////////////////////////// // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+------+-----------+ // | ... | inst | afterInst | // +-----+------+-----------+ // ^prev ^next addInst = new Instruction(Opcode.opcx_aupdate, new Integer(depth)); /* * if (uctype == POINTER) { addInst = new * Instruction(opcx_aupdate, new Integer(depth)); } else { * addInst = new Instruction(opcx_supdate, new * Integer(depth)); } */ iter.add(addInst); // +-----+---------+------+-----------+ // | ... | aupdate | inst | afterInst | // +-----+---------+------+-----------+ // ^prev ^next t = iter.previous(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+---------+------+-----------+ // | ... | aupdate | inst | afterInst | // +-----+---------+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == addInst, t + " != " + addInst); // +-----+---------+------+-----------+ // | ... | aupdate | inst | afterInst | // +-----+---------+------+-----------+ // ^prev ^next t = iter.next(); Assert.isTrue(t == inst, t + " != " + inst); // +-----+---------+------+-----------+ // | ... | aupdate | inst | afterInst | // +-----+---------+------+-----------+ // ^prev ^next if (Main.VERBOSE > 2) { System.out.println("Inserting " + addInst + " before " + inst); } } else if (Main.VERBOSE > 2) { System.out.println("Not inserting uc before " + inst); } } } } }