001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.osr.bytecodes;
014
015import static org.jikesrvm.classloader.ClassLoaderConstants.DoubleTypeCode;
016import static org.jikesrvm.classloader.ClassLoaderConstants.LongTypeCode;
017import static org.jikesrvm.classloader.ClassLoaderConstants.VoidTypeCode;
018import static org.jikesrvm.osr.OSRConstants.PSEUDO_InvokeCompiledMethod;
019
020import org.jikesrvm.classloader.RVMMethod;
021import org.jikesrvm.classloader.TypeReference;
022import org.jikesrvm.compilers.common.CompiledMethod;
023import org.jikesrvm.compilers.common.CompiledMethods;
024
025/**
026 * invoke a compiled method
027 */
028public class InvokeCompiledMethod extends PseudoBytecode {
029
030  private static int bsize = 10;
031  private final int cmid;
032
033  // the bc index of referred call site
034  private final int origIdx;
035
036  public InvokeCompiledMethod(int cmethId, int origBCIndex) {
037    this.cmid = cmethId;
038    this.origIdx = origBCIndex;
039  }
040
041  @Override
042  public byte[] getBytes() {
043    byte[] codes = initBytes(bsize, PSEUDO_InvokeCompiledMethod);
044    int2bytes(codes, 2, cmid);
045    int2bytes(codes, 6, origIdx);
046    return codes;
047  }
048
049  @Override
050  public int getSize() {
051    return bsize;
052  }
053
054  @Override
055  public int stackChanges() {
056    CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid);
057    RVMMethod callee = cm.getMethod();
058
059    int psize = callee.getParameterWords();
060    int schanges = -psize;
061
062    // pop receiver
063    if (!callee.isStatic()) {
064      schanges--;
065    }
066
067    TypeReference rtype = callee.getReturnType();
068    byte tcode = rtype.getName().parseForTypeCode();
069
070    if (tcode == VoidTypeCode) {
071      // do nothing
072    } else {
073      if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
074        schanges++;
075      }
076      schanges++;
077    }
078
079    return schanges;
080  }
081
082  @Override
083  public String toString() {
084    //CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid);
085    return "InvokeCompiledMethod (0x" + Integer.toHexString(cmid) + ") " + "@" + origIdx;
086  }
087}