示例#1
0
 private static boolean checkMethodUsedByBaseClassOrInterface(
     BytecodeMethod mtd, ByteCodeClass cls) {
   if (cls == null) {
     return false;
   }
   if (cls.getBaseInterfacesObject() != null) {
     for (ByteCodeClass bc : cls.getBaseInterfacesObject()) {
       for (BytecodeMethod m : bc.getMethods()) {
         if (m.getMethodName().equals(mtd.getMethodName())) {
           if (m.isUsedByNative()) {
             return true;
           }
           break;
         }
       }
     }
   }
   for (BytecodeMethod m : cls.getMethods()) {
     if (m.getMethodName().equals(mtd.getMethodName())) {
       if (m.isUsedByNative()) {
         return true;
       }
       break;
     }
   }
   return false;
 }
示例#2
0
  private static boolean cullMethods(boolean found) {
    for (ByteCodeClass bc : classes) {
      bc.unmark();
      if (bc.isIsInterface() || bc.getBaseClass() == null) {
        continue;
      }
      for (BytecodeMethod mtd : bc.getMethods()) {
        if (mtd.isEliminated()
            || mtd.isUsedByNative()
            || mtd.isMain()
            || mtd.getMethodName().equals("__CLINIT__")
            || mtd.getMethodName().equals("finalize")
            || mtd.isNative()) {
          continue;
        }

        if (!isMethodUsed(mtd)) {
          if (isMethodUsedByBaseClassOrInterface(mtd, bc)) {
            continue;
          }
          found = true;
          mtd.setEliminated(true);
          /*if(ByteCodeTranslator.verbose) {
          System.out.println("Eliminating method: " + mtd.getClsName() + "." + mtd.getMethodName());
          }*/
        }
      }
    }
    return found;
  }
示例#3
0
  private static void generateClassAndMethodIndexHeader(File outputDirectory) throws Exception {
    int classOffset = 0;
    int methodOffset = 0;
    ArrayList<BytecodeMethod> methods = new ArrayList<BytecodeMethod>();
    for (ByteCodeClass bc : classes) {
      bc.setClassOffset(classOffset);
      classOffset++;

      methodOffset = bc.updateMethodOffsets(methodOffset);
      methods.addAll(bc.getMethods());
    }

    StringBuilder bld = new StringBuilder();
    StringBuilder bldM = new StringBuilder();
    bldM.append("#include \"cn1_class_method_index.h\"\n");
    bldM.append("#include \"cn1_globals.h\"\n\n");
    bld.append("#ifndef __CN1_CLASS_METHOD_INDEX_H__\n#define __CN1_CLASS_METHOD_INDEX_H__\n\n");

    bld.append("// maps to offsets in the constant pool below\nextern int classNameLookup[];\n");
    bldM.append("// maps to offsets in the constant pool below\nint classNameLookup[] = {");
    boolean first = true;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append(addToConstantPool(bc.getClsName().replace('_', '.')));
      bldM.append("");
    }
    bldM.append("};\n\n");

    for (ByteCodeClass bc : classes) {
      bld.append("#define cn1_class_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(bc.getClassOffset());
      bld.append("\n");
    }

    int arrayId = classes.size() + 1;

    bld.append("#define cn1_array_start_offset ");
    bld.append(arrayId);
    bld.append("\n");

    // leave space for primitive arrays
    arrayId += 100;

    for (ByteCodeClass bc : classes) {
      bld.append("#define cn1_array_1_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      bld.append("#define cn1_array_2_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      bld.append("#define cn1_array_3_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;

      /*bld.append("#define cn1_array_4_id_");
      bld.append(bc.getClsName());
      bld.append(" ");
      bld.append(arrayId);
      bld.append("\n");
      arrayId++;*/
    }

    bld.append("\n\n");

    bld.append("// maps to offsets in the constant pool below\nextern int methodNameLookup[];\n");
    bldM.append("// maps to offsets in the constant pool below\nint methodNameLookup[] = {");
    first = true;
    for (BytecodeMethod m : methods) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append(addToConstantPool(m.getMethodName()));
      bldM.append("");
    }
    bldM.append("};\n\n");

    ArrayList<Integer> instances = new ArrayList<Integer>();
    int counter = 0;
    for (ByteCodeClass bc : classes) {
      /*bld.append("extern int classInstanceOfArr");
      bld.append(counter);
      bld.append("[];\n");*/
      bldM.append("int classInstanceOfArr");
      bldM.append(counter);
      bldM.append("[] = {");
      counter++;
      appendClassOffset(bc, instances);

      for (Integer i : instances) {
        bldM.append(i);
        bldM.append(", ");
      }
      instances.clear();
      bldM.append("-1};\n");
    }
    bld.append("extern int *classInstanceOf[];\n");
    bldM.append("int *classInstanceOf[");
    bldM.append(classes.size());
    bldM.append("] = {");
    first = true;
    counter = 0;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append("classInstanceOfArr");
      bldM.append(counter);
      counter++;
    }
    bldM.append("};\n\n");

    bld.append("#define CN1_CONSTANT_POOL_SIZE ");
    bld.append(constantPool.size());
    bld.append("\n\nextern const char * const constantPool[];\n");

    bldM.append("\n\nconst char * const constantPool[] = {\n");
    first = true;
    int offset = 0;
    for (String con : constantPool) {
      if (first) {
        bldM.append("\n    \"");
      } else {
        bldM.append(",\n    \"");
      }
      first = false;
      try {
        bldM.append(encodeString(con));
      } catch (Throwable t) {
        t.printStackTrace();
        System.out.println("Error writing the constant pool string: '" + con + "'");
        System.exit(1);
      }
      bldM.append("\" /* ");
      bldM.append(offset);
      offset++;
      bldM.append(" */");
    }
    bldM.append("};\n\nint classListSize = ");
    bldM.append(classes.size());
    bldM.append(";\n");

    for (ByteCodeClass bc : classes) {
      bldM.append("extern struct clazz class__");
      bldM.append(bc.getClsName().replace('/', '_').replace('$', '_'));
      bldM.append(";\n");
    }
    bldM.append("\n\nstruct clazz* classesList[] = {");
    first = true;
    for (ByteCodeClass bc : classes) {
      if (first) {
        bldM.append("\n    ");
      } else {
        bldM.append(",\n    ");
      }
      first = false;
      bldM.append("    &class__");
      bldM.append(bc.getClsName().replace('/', '_').replace('$', '_'));
    }
    bldM.append("};\n\n\n");

    // generate the markStatics method
    for (ByteCodeClass bc : classes) {
      bc.appendStaticFieldsExtern(bldM);
    }
    bldM.append(
        "\n\nextern int recursionKey;\nvoid markStatics(CODENAME_ONE_THREAD_STATE) {\n    recursionKey++;\n");
    for (ByteCodeClass bc : classes) {
      bc.appendStaticFieldsMark(bldM);
    }
    bldM.append("}\n\n");

    bld.append("\n\n#endif // __CN1_CLASS_METHOD_INDEX_H__\n");

    FileOutputStream fos =
        new FileOutputStream(new File(outputDirectory, "cn1_class_method_index.h"));
    fos.write(bld.toString().getBytes("UTF-8"));
    fos.close();
    fos = new FileOutputStream(new File(outputDirectory, "cn1_class_method_index.m"));
    fos.write(bldM.toString().getBytes("UTF-8"));
    fos.close();
  }