示例#1
0
  /**
   * @param ec
   * @see org.jnode.vm.x86.compiler.l1a.Item#release(EmitterContext)
   */
  private void cleanup(EmitterContext ec) {
    // assertCondition(!ec.getVStack().contains(this), "Cannot release while
    // on vstack");
    final X86RegisterPool pool = ec.getGPRPool();

    switch (getKind()) {
      case Kind.GPR:
        pool.release(gpr);
        if (VmUtils.verifyAssertions()) VmUtils._assert(pool.isFree(gpr), "reg is free");
        break;

      case Kind.LOCAL:
        // nothing to do
        break;

      case Kind.CONSTANT:
        // nothing to do
        break;

      case Kind.FPUSTACK:
        // nothing to do
        break;

      case Kind.STACK:
        // nothing to do
        break;

      default:
        throw new IllegalArgumentException("Invalid item kind");
    }

    this.gpr = null;
    setKind((byte) 0);
  }
示例#2
0
 /**
  * Load this item to a general purpose register.
  *
  * @param ec
  */
 final void loadToGPR(EmitterContext ec) {
   if (!isGPR()) {
     X86Register r = ec.getGPRPool().request(JvmType.INT);
     if (r == null) {
       ec.getVStack().push(ec);
       r = ec.getGPRPool().request(JvmType.INT);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
 }
示例#3
0
 /**
  * Load this item into a register that is suitable for BITS8 mode.
  *
  * @param ec
  */
 final void loadToBITS8GPR(EmitterContext ec) {
   if (!isGPR() || !gpr.isSuitableForBits8()) {
     final X86RegisterPool pool = ec.getGPRPool();
     X86Register r = pool.request(JvmType.INT, this, true);
     if (r == null) {
       ec.getVStack().push(ec);
       r = ec.getGPRPool().request(JvmType.INT, this, true);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
 }
示例#4
0
 protected final void initialize(EmitterContext ec, byte kind, X86Register reg, short local) {
   super.initialize(
       kind, local, ((reg instanceof X86Register.XMM) ? (X86Register.XMM) reg : null));
   this.gpr = (reg instanceof X86Register.GPR) ? (X86Register.GPR) reg : null;
   if (VmUtils.verifyAssertions()) {
     switch (kind) {
       case Kind.GPR:
         VmUtils._assert((this.gpr != null), "kind == register implies that reg != null");
         break;
     }
     verifyState(ec);
   }
 }
示例#5
0
  /**
   * Gets the bytecode of a native code replacement method.
   *
   * @param method
   * @param cl
   * @return the bytecode
   */
  private static VmByteCode getNativeCodeReplacement(
      VmMethod method, VmClassLoader cl, boolean verbose) {
    final String className = method.getDeclaringClass().getName();
    final String nativeClassName = VmUtils.getNativeClassName(className);
    final VmType nativeType;
    try {
      nativeType = cl.loadClass(nativeClassName, false);
    } catch (ClassNotFoundException ex) {
      if (verbose) {
        BootLogInstance.get().error("Native class replacement (" + nativeClassName + ") not found");
      }
      return null;
    }

    String signature = method.getSignature();
    if (!method.isStatic()) {
      signature = '(' + Signature.toSignature(method.getDeclaringClass()) + signature.substring(1);
    }

    final VmMethod nativeMethod =
        nativeType.getNativeMethodReplacement(method.getName(), signature);

    if (nativeMethod == null) {
      if (verbose) {
        BootLogInstance.get().error("Native method replacement (" + method + ") not found");
      }
      return null;
    }
    if (!nativeMethod.isStatic()) {
      throw new ClassFormatError("Native method replacement must be static");
    }
    return nativeMethod.getBytecode();
  }
示例#6
0
 /** @see org.jnode.vm.x86.compiler.l1a.Item#load(EmitterContext) */
 final void load(EmitterContext ec) {
   if (!isGPR()) {
     final X86RegisterPool pool = ec.getGPRPool();
     X86Register r = pool.request(getType(), this);
     if (r == null) {
       final VirtualStack vstack = ec.getVStack();
       vstack.push(ec);
       r = pool.request(getType(), this);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
   if (VmUtils.verifyAssertions()) {
     verifyState(ec);
   }
 }
示例#7
0
 /**
  * Gets the compiled code of a given stackframe.
  *
  * @param sf Stackframe pointer
  * @return The compiled code
  */
 final VmCompiledCode getCompiledCode(Address sf) {
   final int ccid = sf.loadInt(getMethodIdOffset(sf));
   if (ccid == 0) {
     return null;
   } else {
     return VmUtils.getVm().getCompiledMethods().get(ccid);
   }
 }
示例#8
0
 /**
  * @see org.jnode.vm.x86.compiler.l1a.Item#spill(EmitterContext,
  *     org.jnode.assembler.x86.X86Register)
  */
 final void spill(EmitterContext ec, X86Register reg) {
   if (VmUtils.verifyAssertions()) {
     VmUtils._assert(
         isGPR() && (this.gpr.getNr() == reg.getNr()), "spill1 gpr=" + gpr + ", reg=" + reg);
   }
   final X86RegisterPool pool = ec.getGPRPool();
   X86Register r = pool.request(getType());
   if (r == null) {
     ec.getVStack().push(ec);
     if (getKind() == Kind.STACK) {
       return;
     }
     r = pool.request(getType());
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
   }
   loadTo(ec, (X86Register.GPR) r);
   pool.transferOwnerTo(r, this);
   if (VmUtils.verifyAssertions()) {
     verifyState(ec);
   }
 }
示例#9
0
  /**
   * Gets the method of a given stackframe.
   *
   * @param sf Stackframe pointer
   * @return The method
   */
  @KernelSpace
  final VmMethod getMethod(Address sf) {
    final int ccid = sf.loadInt(getMethodIdOffset(sf));
    if (ccid == 0) {
      return null;
    } else {
      final VmCompiledCode cc = VmUtils.getVm().getCompiledMethods().get(ccid);
      if (cc == null) {
        // (This can happen if an exception is thrown while a frame
        // for a 'native' method call is on the stack.  A panic is not a
        // good idea.  It is better to generate a stack trace with a missing
        // method name.)

        // Unsafe.die("Unknown ccid found on stack");
        return null;
      } else {
        return cc.getMethod();
      }
    }
  }
示例#10
0
  /**
   * Read the method table
   *
   * @param data
   * @param rejectNatives
   * @param cls
   * @param cp
   * @param statics
   * @param cl
   */
  private static void readMethods(
      ByteBuffer data,
      boolean rejectNatives,
      VmType cls,
      VmCP cp,
      VmStatics statics,
      VmClassLoader cl) {
    final int mcount = data.getChar();
    if (mcount > 0) {
      final VmMethod[] mtable = new VmMethod[mcount];

      for (int i = 0; i < mcount; i++) {
        final int modifiers = data.getChar();
        final String name = cp.getUTF8(data.getChar());
        final String signature = cp.getUTF8(data.getChar());
        final boolean isStatic = ((modifiers & Modifier.ACC_STATIC) != 0);

        final VmMethod mts;
        final boolean isSpecial = name.equals("<init>");
        // final int staticsIdx = statics.allocMethod();
        if (isStatic || isSpecial) {
          if (isSpecial) {
            mts = new VmSpecialMethod(name, signature, modifiers, cls);
          } else {
            mts = new VmStaticMethod(name, signature, modifiers, cls);
          }
        } else {
          mts = new VmInstanceMethod(name, signature, modifiers, cls);
        }
        // statics.setMethod(staticsIdx, mts);
        mtable[i] = mts;

        // Read methods attributes
        final int acount = data.getChar();
        VmAnnotation[] rVisAnn = null;
        VmAnnotation[] rInvisAnn = null;
        for (int a = 0; a < acount; a++) {
          String attrName = cp.getUTF8(data.getChar());
          int length = data.getInt();
          if (VmArray.equals(CodeAttrName, attrName)) {
            mts.setBytecode(readCode(data, cls, cp, mts));
          } else if (VmArray.equals(ExceptionsAttrName, attrName)) {
            mts.setExceptions(readExceptions(data, cls, cp));
          } else if (VmArray.equals(RuntimeVisibleAnnotationsAttrName, attrName)) {
            byte[] buf = new byte[length];
            data.slice().get(buf);
            mts.setRawAnnotations(buf);

            // todo will get obsolate with openjdk based annotation support
            // rVisAnn = readRuntimeAnnotations(data, cp, true, cl);
            rVisAnn = readRuntimeAnnotations2(data, cp, true, cl, cls);

          } else if (VmArray.equals(RuntimeInvisibleAnnotationsAttrName, attrName)) {
            rInvisAnn = readRuntimeAnnotations(data, cp, false, cl);
          } else if (VmArray.equals(RuntimeVisibleParameterAnnotationsAttrName, attrName)) {

            byte[] buf = new byte[length];
            data.slice().get(buf);
            mts.setRawParameterAnnotations(buf);
            // todo will get obsolate with openjdk based annotation support
            readRuntimeParameterAnnotations(data, cp, true, cl);
          } else if (VmArray.equals(RuntimeInvisibleParameterAnnotationsAttrName, attrName)) {
            readRuntimeParameterAnnotations(data, cp, false, cl);
          } else if (VmArray.equals(AnnotationDefaultAttrName, attrName)) {
            // todo will get obsolate with openjdk based annotation support
            byte[] buf = new byte[length];
            data.slice().get(buf);
            mts.setRawAnnotationDefault(buf);

            Class r_class;
            VmType vtm = mts.getReturnType();
            if (vtm.isPrimitive()) {
              r_class = getClassForJvmType(vtm.getJvmType());
            } else {
              try {
                r_class = Class.forName(vtm.getName(), false, vtm.getLoader().asClassLoader());
              } catch (ClassNotFoundException cnf) {
                throw new RuntimeException(cnf);
              }
            }
            Object defo =
                AnnotationParser.parseMemberValue(
                    r_class,
                    data,
                    new VmConstantPool(cls),
                    VmUtils.isRunningVm() ? cls.asClass() : cls.asClassDuringBootstrap());
            mts.setAnnotationDefault(defo);
          } else {
            skip(data, length);
          }
        }
        mts.setRuntimeAnnotations(rVisAnn);
        if (rVisAnn != null) {
          mts.addPragmaFlags(getMethodPragmaFlags(rVisAnn, cls.getName()));
        }
        if (rInvisAnn != null) {
          mts.addPragmaFlags(getMethodPragmaFlags(rInvisAnn, cls.getName()));
        }
        if ((modifiers & Modifier.ACC_NATIVE) != 0) {
          final VmByteCode bc = getNativeCodeReplacement(mts, cl, rejectNatives);
          if (bc != null) {
            mts.setModifier(false, Modifier.ACC_NATIVE);
            mts.setBytecode(bc);
          } else {
            if (rejectNatives) {
              throw new ClassFormatError("Native method " + mts);
            }
          }
        }
      }
      cls.setMethodTable(mtable);
    }
  }
示例#11
0
  /**
   * load item with register reg. Assumes that reg is properly allocated
   *
   * @param ec current emitter context
   * @param reg register to load the item to
   */
  final void loadTo(EmitterContext ec, X86Register.GPR reg) {
    if (VmUtils.verifyAssertions()) VmUtils._assert(reg != null, "Reg != null");
    final X86Assembler os = ec.getStream();
    final X86RegisterPool pool = ec.getGPRPool();
    final VirtualStack stack = ec.getVStack();
    final X86CompilerHelper helper = ec.getHelper();
    if (VmUtils.verifyAssertions()) {
      VmUtils._assert(!pool.isFree(reg), "reg not free");
    }

    switch (getKind()) {
      case Kind.GPR:
        if (this.gpr != reg) {
          os.writeMOV(reg.getSize(), reg, this.gpr);
          cleanup(ec);
        }
        break;

      case Kind.LOCAL:
        os.writeMOV(reg.getSize(), reg, helper.BP, getOffsetToFP(ec));
        break;

      case Kind.CONSTANT:
        loadToConstant(ec, os, reg);
        break;

      case Kind.FPUSTACK:
        // Make sure this item is on top of the FPU stack
        FPUHelper.fxch(os, stack.fpuStack, this);
        stack.fpuStack.pop(this);
        // Convert & move to new space on normal stack
        os.writeLEA(helper.SP, helper.SP, -helper.SLOTSIZE);
        popFromFPU(os, helper.SP, 0);
        os.writePOP(reg);
        break;

      case Kind.STACK:
        // TODO: make sure 'this' is on top of stack
        // TODO: implemen it for 64 bits
        if (!stack.operandStack.isTos(this)) {

          int stack_loc = stack.operandStack.stackLocation(this);
          if (stack_loc < 0) throw new StackException("Item not found on stack");

          stack.operandStack.makeTop(stack_loc);

          // todo test it
          os.writeMOV(
              org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32,
              reg,
              helper.SP,
              helper.SLOTSIZE);
          os.writeXCHG(
              helper.SP, org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32 * stack_loc, reg);
          os.writeMOV(
              org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32,
              helper.SP,
              helper.SLOTSIZE,
              reg);
        }

        if (VirtualStack.checkOperandStack) {
          stack.operandStack.pop(this);
        }
        os.writePOP(reg);
        break;

      default:
        throw new IllegalArgumentException("Invalid item kind");
    }
    setKind(Kind.GPR);
    this.gpr = reg;
  }
示例#12
0
 /**
  * Gets the register the is used by this item.
  *
  * @return The register that contains this item
  */
 final X86Register.GPR getRegister() {
   if (VmUtils.verifyAssertions()) VmUtils._assert(isGPR(), "Must be register");
   return gpr;
 }
示例#13
0
 /**
  * Gets the constant value of this item.
  *
  * @return
  */
 final long getValue() {
   if (VmUtils.verifyAssertions()) {
     VmUtils._assert(isConstant(), "kind == Kind.CONSTANT");
   }
   return value;
 }
示例#14
0
 /**
  * Gets the MSB part of the constant value of this item.
  *
  * @return
  */
 final int getMsbValue() {
   if (VmUtils.verifyAssertions()) {
     VmUtils._assert(isConstant(), "kind == Kind.CONSTANT");
   }
   return (int) ((value >>> 32) & 0xFFFFFFFFL);
 }
示例#15
0
 /**
  * Gets (creates if needed) a compiled code id.
  *
  * @return a compiled code id.
  */
 public final int getCompiledCodeId() {
   if (ccId < 0) {
     ccId = VmUtils.getVm().getCompiledMethods().createId();
   }
   return ccId;
 }