示例#1
0
  /** {@inheritDoc} */
  public void convert(Klass klass) {
    lastClassNameStack.push(klass.getName());
    int state = klass.getState();
    if (state < Klass.STATE_CONVERTING) {
      if (klass.isArray()) {
        convert(Klass.OBJECT);
        klass.changeState(Klass.STATE_CONVERTED);
      } else {
        traceProgress();

        ClassFile classFile = getClassFile(klass);
        classFile.convertPhase1(this, translationStrategy != BY_METHOD);
        if (klass.hasGlobalStatics()) {
          // record globals now.
          recordGlobalStatics(klass);
        }

        if (translationStrategy == BY_METHOD || translationStrategy == BY_CLASS) {
          // if NOT inlining, then generate squawk code now.
          classFile.convertPhase2(this, translationStrategy == BY_METHOD);
          classFiles.remove(klass.getName());
        }
      }
    }
    lastClassNameStack.pop();
  }
示例#2
0
 public void dumpReplayData(PrintStream out) {
   NMethod nm = getNativeMethod();
   int code_size = 0;
   if (nm != null) {
     code_size = (int) nm.codeEnd().minus(nm.getVerifiedEntryPoint());
   }
   Klass holder = getMethodHolder();
   out.println(
       "ciMethod "
           + holder.getName().asString()
           + " "
           + OopUtilities.escapeString(getName().asString())
           + " "
           + getSignature().asString()
           + " "
           + getInvocationCount()
           + " "
           + getBackedgeCount()
           + " "
           + interpreterInvocationCount()
           + " "
           + interpreterThrowoutCount()
           + " "
           + code_size);
 }
示例#3
0
文件: Frame.java 项目: johangas/moped
 /**
  * Tests two given types to ensure that they are both {@link Klass#isSquawkPrimitive() Squawk
  * primitives} or both not Squawk primitives. If they are both Squawk primitives, then they must
  * be exactly the same type. This enforces the constraint that Squawk primitive values cannot be
  * assigned to or compared with any other type.
  *
  * @param type1 the first type to compare
  * @param type2 the second type to compare
  */
 public void verifyUseOfSquawkPrimitive(Klass type1, Klass type2) {
   if (type1.isSquawkPrimitive() || type2.isSquawkPrimitive()) {
     if (type1 != type2) {
       // Offsets are implemented as Words
       //                if (type1.getClassID() + type2.getClassID() != CID.UWORD + CID.OFFSET) {
       String type = type1.getName();
       throw codeParser.verifyError(
           type
               + " values can only be written to or compared with other "
               + type
               + " values, not with "
               + type2.getName());
       //                }
     }
   }
 }
示例#4
0
 /**
  * Generate squawk code for methods of <code>klass</code> when doing whole-suite translation
  * (inlining, etc.)
  *
  * @param klass the klass to generate code for
  */
 void convertPhase2(Klass klass) {
   Assert.that(translationStrategy != BY_METHOD);
   convert(klass);
   if (klass.getState() < Klass.STATE_CONVERTED) {
     if (!VM
         .isVerbose()) { // "squawk -verbose" will show the class names as it finishes loading
                         // them, which is progress enough
       traceProgress();
     }
     lastClassNameStack.push(klass.getName());
     ClassFile classFile = getClassFile(klass);
     classFile.convertPhase2(this, false);
     classFiles.remove(klass.getName());
     lastClassNameStack.pop();
   }
 }
示例#5
0
 /**
  * Gets the class file corresponding to a given instance class. The <code>klass</code> must not
  * yet be converted and it must not be a {@link Klass#isSynthetic() synthetic} class.
  *
  * @param klass the instance class for which a class file is requested
  * @return the class file for <code>klass</code>
  */
 ClassFile getClassFile(Klass klass) {
   Assert.that(!klass.isSynthetic(), "synthethic class has no classfile");
   String name = klass.getName();
   ClassFile classFile = (ClassFile) classFiles.get(name);
   if (classFile == null) {
     classFile = new ClassFile(klass);
     classFiles.put(name, classFile);
   }
   return classFile;
 }
示例#6
0
 boolean computeSubtypeOf(Klass k) {
   // An array is a subtype of Serializable, Clonable, and Object
   Symbol name = k.getName();
   if (name != null
       && (name.equals(javaIoSerializableName())
           || name.equals(javaLangCloneableName())
           || name.equals(javaLangObjectName()))) {
     return true;
   } else {
     return false;
   }
 }
示例#7
0
文件: Frame.java 项目: johangas/moped
 /**
  * Creates and returns the detailed error message when a local variable is used as a Squawk
  * primitive as well as some value not of exactly the same type. The message includes information
  * derived from the LocalVariableTable attribute so that the source code can be easily changed.
  *
  * @param index the local variable index that is (mis)used
  * @return the detailed error message
  */
 private String getBadAddressLocalVariableMessage(int index, Klass type1, Klass type2) {
   Assert.that(type1.isSquawkPrimitive() || type2.isSquawkPrimitive());
   if (type2.isSquawkPrimitive()) {
     Klass otherType = type1;
     type1 = type2;
     type2 = otherType;
   }
   StringBuffer buf =
       new StringBuffer(
           "Stack location "
               + index
               + " cannot be used for both a local variable of type "
               + type1.getName()
               + " and of type "
               + type2.getName()
               + ". Try moving the variable of type "
               + type1.getName()
               + " to the top-most scope of the method.");
   Enumeration e = codeParser.getLocalVariableTableEntries();
   if (e != null) {
     buf.append(" (source code usage: ");
     while (e.hasMoreElements()) {
       LocalVariableTableEntry entry = (LocalVariableTableEntry) e.nextElement();
       if (entry.getIndex() == index) {
         int start = codeParser.getSourceLineNumber(entry.getStart().getBytecodeOffset());
         int end = codeParser.getSourceLineNumber(entry.getEnd().getBytecodeOffset());
         buf.append(entry.getType().getName())
             .append(' ')
             .append(entry.getName())
             .append(" from line ")
             .append(start)
             .append(" to line ")
             .append(end)
             .append(';');
       }
     }
   }
   return buf.toString();
 }
示例#8
0
  /**
   * Gets the fully qualified name of this type. The returned name is formatted as it might appear
   * in a Java programming language declaration for objects of this type.
   *
   * <p>For primitive classes the returned name is the name of the corresponding primitive type; for
   * example, "int" is returned as the name of the class represented by {@link
   * java.lang.Integer#TYPE Integer.TYPE}.
   *
   * @return a string containing the type name.
   */
  public String getName() {
    String name = klass.getName();
    if (!klass.isArray()) {
      return name;
    }

    int dimensions = 0;
    while (name.charAt(dimensions) == '[') {
      ++dimensions;
    }

    name = name.substring(dimensions);
    char first = name.charAt(0);
    if (first == 'L') {
      name = name.substring(1, name.length() - 2).replace('/', '.');
    } else {
      switch (first) {
        case 'I':
          name = "int";
          break;
        case 'J':
          name = "long";
          break;
        case 'F':
          name = "float";
          break;
        case 'D':
          name = "double";
          break;
        case 'Z':
          name = "boolean";
          break;
        case 'C':
          name = "char";
          break;
        case 'S':
          name = "short";
          break;
        case 'B':
          name = "byte";
          break;
        case 'V':
          name = "void";
          break;
      }
    }
    while (dimensions-- != 0) {
      name += "[]";
    }
    return name;
  }
示例#9
0
 /** {@inheritDoc} */
 public void load(Klass klass) {
   Assert.that(VM.isHosted() || VM.getCurrentIsolate().getLeafSuite() == suite);
   int state = klass.getState();
   if (state < Klass.STATE_LOADED) {
     if (klass.isArray()) {
       load(klass.getComponentType());
     } else {
       lastClassNameStack.push(klass.getName());
       ClassFile classFile = getClassFile(klass);
       load(classFile);
       lastClassNameStack.pop();
     }
   }
 }
示例#10
0
  public void writeBytes(OutputStream os) throws IOException {
    // Map between any modified UTF-8 and it's constant pool index.
    Map utf8ToIndex = new HashMap();
    DataOutputStream dos = new DataOutputStream(os);
    TypeArray tags = getTags();
    int len = (int) getLength();
    int ci = 0; // constant pool index

    // collect all modified UTF-8 Strings from Constant Pool

    for (ci = 1; ci < len; ci++) {
      byte cpConstType = tags.getByteAt(ci);
      if (cpConstType == JVM_CONSTANT_Utf8) {
        Symbol sym = getSymbolAt(ci);
        utf8ToIndex.put(sym.asString(), new Short((short) ci));
      } else if (cpConstType == JVM_CONSTANT_Long || cpConstType == JVM_CONSTANT_Double) {
        ci++;
      }
    }

    for (ci = 1; ci < len; ci++) {
      int cpConstType = (int) tags.getByteAt(ci);
      // write cp_info
      // write constant type
      switch (cpConstType) {
        case JVM_CONSTANT_Utf8:
          {
            dos.writeByte(cpConstType);
            Symbol sym = getSymbolAt(ci);
            dos.writeShort((short) sym.getLength());
            dos.write(sym.asByteArray());
            if (DEBUG) debugMessage("CP[" + ci + "] = modified UTF-8 " + sym.asString());
            break;
          }

        case JVM_CONSTANT_Unicode:
          throw new IllegalArgumentException("Unicode constant!");

        case JVM_CONSTANT_Integer:
          dos.writeByte(cpConstType);
          dos.writeInt(getIntAt(ci));
          if (DEBUG) debugMessage("CP[" + ci + "] = int " + getIntAt(ci));
          break;

        case JVM_CONSTANT_Float:
          dos.writeByte(cpConstType);
          dos.writeFloat(getFloatAt(ci));
          if (DEBUG) debugMessage("CP[" + ci + "] = float " + getFloatAt(ci));
          break;

        case JVM_CONSTANT_Long:
          {
            dos.writeByte(cpConstType);
            long l = getLongAt(ci);
            // long entries occupy two pool entries
            ci++;
            dos.writeLong(l);
            break;
          }

        case JVM_CONSTANT_Double:
          dos.writeByte(cpConstType);
          dos.writeDouble(getDoubleAt(ci));
          // double entries occupy two pool entries
          ci++;
          break;

        case JVM_CONSTANT_Class:
          {
            dos.writeByte(cpConstType);
            // Klass already resolved. ConstantPool constains klassOop.
            Klass refKls = (Klass) getObjAt(ci);
            String klassName = refKls.getName().asString();
            Short s = (Short) utf8ToIndex.get(klassName);
            dos.writeShort(s.shortValue());
            if (DEBUG) debugMessage("CP[" + ci + "] = class " + s);
            break;
          }

          // case JVM_CONSTANT_ClassIndex:
        case JVM_CONSTANT_UnresolvedClass:
          {
            dos.writeByte(JVM_CONSTANT_Class);
            String klassName = getSymbolAt(ci).asString();
            Short s = (Short) utf8ToIndex.get(klassName);
            dos.writeShort(s.shortValue());
            if (DEBUG) debugMessage("CP[" + ci + "] = class " + s);
            break;
          }

        case JVM_CONSTANT_String:
          {
            dos.writeByte(cpConstType);
            String str = OopUtilities.stringOopToString(getObjAt(ci));
            Short s = (Short) utf8ToIndex.get(str);
            dos.writeShort(s.shortValue());
            if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
            break;
          }

          // case JVM_CONSTANT_StringIndex:
        case JVM_CONSTANT_UnresolvedString:
          {
            dos.writeByte(JVM_CONSTANT_String);
            String val = getSymbolAt(ci).asString();

            Short s = (Short) utf8ToIndex.get(val);
            dos.writeShort(s.shortValue());
            if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
            break;
          }

          // all external, internal method/field references
        case JVM_CONSTANT_Fieldref:
        case JVM_CONSTANT_Methodref:
        case JVM_CONSTANT_InterfaceMethodref:
          {
            dos.writeByte(cpConstType);
            int value = getIntAt(ci);
            short klassIndex = (short) extractLowShortFromInt(value);
            short nameAndTypeIndex = (short) extractHighShortFromInt(value);
            dos.writeShort(klassIndex);
            dos.writeShort(nameAndTypeIndex);
            if (DEBUG)
              debugMessage(
                  "CP[" + ci + "] = ref klass = " + klassIndex + ", N&T = " + nameAndTypeIndex);
            break;
          }

        case JVM_CONSTANT_NameAndType:
          {
            dos.writeByte(cpConstType);
            int value = getIntAt(ci);
            short nameIndex = (short) extractLowShortFromInt(value);
            short signatureIndex = (short) extractHighShortFromInt(value);
            dos.writeShort(nameIndex);
            dos.writeShort(signatureIndex);
            if (DEBUG)
              debugMessage(
                  "CP[" + ci + "] = N&T name = " + nameIndex + ", type = " + signatureIndex);
            break;
          }
      } // switch
    }
    dos.flush();
    return;
  }