예제 #1
0
파일: Atom.java 프로젝트: alanweide/coff
 /** Return atom as a string literal */
 @Pure
 public synchronized String toUnicodeString() throws java.io.UTFDataFormatException {
   if (unicodeStringOrJTOCoffset == null) {
     String s = UTF8Convert.fromUTF8(val);
     if (VM.runningVM) {
       s = InternedStrings.internUnfoundString(s);
       unicodeStringOrJTOCoffset = s;
     } else if (!VM.writingImage) {
       s = s.intern();
       int offset = Statics.findOrCreateObjectLiteral(s);
       unicodeStringOrJTOCoffset = offset;
     }
     return s;
   } else if (unicodeStringOrJTOCoffset instanceof String) {
     return (String) unicodeStringOrJTOCoffset;
   } else {
     if (VM.runningVM) {
       return (String)
           Statics.getSlotContentsAsObject(
               Offset.fromIntSignExtend((Integer) unicodeStringOrJTOCoffset));
     } else {
       return UTF8Convert.fromUTF8(val).intern();
     }
   }
 }
 /** Find or create a JTOC offset for this method */
 public final synchronized Offset findOrCreateJtocOffset() {
   if (VM.VerifyAssertions) VM._assert(!isStatic() && !isObjectInitializer());
   Offset jtocOffset = getJtocOffset();
   ;
   if (jtocOffset.EQ(Offset.zero())) {
     jtocOffset = Statics.allocateReferenceSlot(true);
     Statics.setSlotContents(jtocOffset, getCurrentEntryCodeArray());
     synchronized (jtocOffsets) {
       jtocOffsets.put(this, Integer.valueOf(jtocOffset.toInt()));
     }
   }
   return jtocOffset;
 }
  /**
   * Change machine code that will be used by future executions of this method (ie. optimized <->
   * non-optimized)
   *
   * <p>Side effect: updates JTOC or method dispatch tables ("type information blocks") for this
   * class and its subclasses
   *
   * @param compiledMethod new machine code
   */
  public final synchronized void replaceCompiledMethod(CompiledMethod compiledMethod) {
    if (VM.VerifyAssertions) VM._assert(getDeclaringClass().isInstantiated());
    // If we're replacing with a non-null compiledMethod, ensure that is still valid!
    if (compiledMethod != null) {
      synchronized (compiledMethod) {
        if (compiledMethod.isInvalid()) return;
      }
    }

    // Grab version that is being replaced
    CompiledMethod oldCompiledMethod = currentCompiledMethod;
    currentCompiledMethod = compiledMethod;

    // Install the new method in JTOC/TIB. If virtual, will also replace in
    // all subclasses that inherited the method.
    getDeclaringClass().updateMethod(this);

    // Replace constant-ified virtual method in JTOC if necessary
    Offset jtocOffset = getJtocOffset();
    if (jtocOffset.NE(Offset.zero())) {
      Statics.setSlotContents(jtocOffset, getCurrentEntryCodeArray());
    }

    // Now that we've updated the JTOC/TIB, old version is obsolete
    if (oldCompiledMethod != null) {
      CompiledMethods.setCompiledMethodObsolete(oldCompiledMethod);
    }
  }
예제 #4
0
파일: Atom.java 프로젝트: alanweide/coff
 /**
  * Offset of an atom's string in the JTOC, for string literals
  *
  * @return Offset of string literal in JTOC
  * @throws java.io.UTFDataFormatException
  */
 public synchronized int getStringLiteralOffset() throws java.io.UTFDataFormatException {
   if (unicodeStringOrJTOCoffset == null) {
     String s = UTF8Convert.fromUTF8(val);
     if (VM.runningVM) {
       s = InternedStrings.internUnfoundString(s);
     } else {
       s = s.intern();
     }
     int offset = Statics.findOrCreateObjectLiteral(s);
     unicodeStringOrJTOCoffset = offset;
     return offset;
   } else if (unicodeStringOrJTOCoffset instanceof String) {
     int offset = Statics.findOrCreateObjectLiteral(unicodeStringOrJTOCoffset);
     unicodeStringOrJTOCoffset = offset;
     return offset;
   } else {
     return (Integer) unicodeStringOrJTOCoffset;
   }
 }
예제 #5
0
파일: Atom.java 프로젝트: alanweide/coff
 /** Atom as string literal or null if atom hasn't been converted */
 private synchronized String toUnicodeStringInternal() {
   if (unicodeStringOrJTOCoffset == null) {
     return null;
   } else if (unicodeStringOrJTOCoffset instanceof String) {
     return (String) unicodeStringOrJTOCoffset;
   } else {
     if (VM.runningVM) {
       Object result =
           Statics.getSlotContentsAsObject(
               Offset.fromIntSignExtend((Integer) unicodeStringOrJTOCoffset));
       return (String) result;
     } else {
       try {
         return UTF8Convert.fromUTF8(val).intern();
       } catch (UTFDataFormatException e) {
         throw new Error("Error in UTF data encoding: ", e);
       }
     }
   }
 }
예제 #6
0
  private static <T> Object readValue(
      TypeReference type,
      int[] constantPool,
      DataInputStream input,
      ClassLoader classLoader,
      byte elementValue_tag)
      throws IOException, ClassNotFoundException {
    // decode
    Object value;
    switch (elementValue_tag) {
      case 'B':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Byte);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = (byte) Statics.getSlotContentsAsInt(offset);
          break;
        }
      case 'C':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Char);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = (char) Statics.getSlotContentsAsInt(offset);
          break;
        }
      case 'D':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Double);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          long longValue = Statics.getSlotContentsAsLong(offset);
          value = Double.longBitsToDouble(longValue);
          break;
        }
      case 'F':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Float);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          int intValue = Statics.getSlotContentsAsInt(offset);
          value = Float.intBitsToFloat(intValue);
          break;
        }
      case 'I':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Int);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = Statics.getSlotContentsAsInt(offset);
          break;
        }
      case 'J':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Long);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = Statics.getSlotContentsAsLong(offset);
          break;
        }
      case 'S':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Short);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = (short) Statics.getSlotContentsAsInt(offset);
          break;
        }
      case 'Z':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.Boolean);
          Offset offset = RVMClass.getLiteralOffset(constantPool, input.readUnsignedShort());
          value = Statics.getSlotContentsAsInt(offset) == 1;
          break;
        }
      case 's':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.JavaLangString);
          value = RVMClass.getUtf(constantPool, input.readUnsignedShort()).toString();
          break;
        }
      case 'e':
        {
          int typeNameIndex = input.readUnsignedShort();
          @SuppressWarnings("unchecked")
          Class enumType =
              TypeReference.findOrCreate(classLoader, RVMClass.getUtf(constantPool, typeNameIndex))
                  .resolve()
                  .getClassForType();
          int constNameIndex = input.readUnsignedShort();

          //noinspection unchecked
          value = Enum.valueOf(enumType, RVMClass.getUtf(constantPool, constNameIndex).toString());
          break;
        }
      case 'c':
        {
          if (VM.VerifyAssertions) VM._assert(type == null || type == TypeReference.JavaLangClass);
          int classInfoIndex = input.readUnsignedShort();
          // Value should be a class but resolving the class at this point could cause infinite
          // recursion in class loading
          TypeReference unresolvedValue =
              TypeReference.findOrCreate(
                  classLoader, RVMClass.getUtf(constantPool, classInfoIndex));
          if (unresolvedValue.peekType() != null) {
            value = unresolvedValue.peekType().getClassForType();
          } else {
            value = unresolvedValue;
          }
          break;
        }
      case '@':
        value = RVMAnnotation.readAnnotation(constantPool, input, classLoader);
        break;
      case '[':
        {
          int numValues = input.readUnsignedShort();
          if (numValues == 0) {
            if (type != null) {
              value = Array.newInstance(type.resolve().getClassForType(), 0);
            } else {
              value = new Object[0];
            }
          } else {
            byte innerElementValue_tag = input.readByte();
            TypeReference innerType = type == null ? null : type.getArrayElementType();
            switch (innerElementValue_tag) {
              case 'B':
                {
                  byte[] array = new byte[numValues];
                  array[0] =
                      (Byte)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Byte) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'C':
                {
                  char[] array = new char[numValues];
                  array[0] =
                      (Character)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Character) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'D':
                {
                  double[] array = new double[numValues];
                  array[0] =
                      (Double)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Double) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'F':
                {
                  float[] array = new float[numValues];
                  array[0] =
                      (Float)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Float) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'I':
                {
                  int[] array = new int[numValues];
                  array[0] =
                      (Integer)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Integer) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'J':
                {
                  long[] array = new long[numValues];
                  array[0] =
                      (Long)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Long) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 'S':
                {
                  short[] array = new short[numValues];
                  array[0] =
                      (Short)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] =
                        (Short)
                            readValue(
                                innerType, constantPool, input, classLoader, innerElementValue_tag);
                  }
                  value = array;
                  break;
                }
              case 'Z':
                {
                  boolean[] array = new boolean[numValues];
                  array[0] =
                      (Boolean)
                          readValue(
                              innerType, constantPool, input, classLoader, innerElementValue_tag);
                  for (int i = 1; i < numValues; i++) {
                    array[i] = (Boolean) readValue(innerType, constantPool, input, classLoader);
                  }
                  value = array;
                  break;
                }
              case 's':
              case '@':
              case 'e':
              case '[':
                {
                  Object value1 =
                      readValue(innerType, constantPool, input, classLoader, innerElementValue_tag);
                  value = Array.newInstance(value1.getClass(), numValues);
                  Array.set(value, 0, value1);
                  for (int i = 1; i < numValues; i++) {
                    Array.set(value, i, readValue(innerType, constantPool, input, classLoader));
                  }
                  break;
                }
              case 'c':
                {
                  Object value1 =
                      readValue(innerType, constantPool, input, classLoader, innerElementValue_tag);
                  Object[] values = new Object[numValues];
                  values[0] = value1;
                  boolean allClasses = value1 instanceof Class;
                  for (int i = 1; i < numValues; i++) {
                    values[i] = readValue(innerType, constantPool, input, classLoader);
                    if (allClasses && !(values[i] instanceof Class)) {
                      allClasses = false;
                    }
                  }
                  if (allClasses == true) {
                    Class<?>[] newValues = new Class[numValues];
                    for (int i = 0; i < numValues; i++) {
                      newValues[i] = (Class<?>) values[i];
                    }
                    value = newValues;
                  } else {
                    value = values;
                  }
                  break;
                }
              default:
                throw new ClassFormatError(
                    "Unknown element_value tag '" + (char) innerElementValue_tag + "'");
            }
          }
          break;
        }
      default:
        throw new ClassFormatError("Unknown element_value tag '" + (char) elementValue_tag + "'");
    }
    return value;
  }