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     */
013    package org.jikesrvm.osr.bytecodes;
014    
015    import org.jikesrvm.VM;
016    import org.jikesrvm.adaptive.AosEntrypoints;
017    import org.jikesrvm.classloader.RVMMethod;
018    import org.jikesrvm.classloader.TypeReference;
019    
020    /**
021     * Special invokestatic, with only two possible target
022     * ObjectHolder.getRefAt and ObjectHolder.cleanRefs
023     * indiced by GETREFAT and CLEANREFS.
024     */
025    public class InvokeStatic extends PseudoBytecode {
026    
027      private static final int bsize = 6;
028      private final int tid;  // target INDEX
029    
030      public InvokeStatic(int targetId) {
031        this.tid = targetId;
032      }
033    
034      @Override
035      public byte[] getBytes() {
036        byte[] codes = initBytes(bsize, PSEUDO_InvokeStatic);
037        int2bytes(codes, 2, tid);
038        return codes;
039      }
040    
041      @Override
042      public int getSize() {
043        return bsize;
044      }
045    
046      @Override
047      public int stackChanges() {
048        RVMMethod callee = targetMethod(tid);
049        int psize = callee.getParameterWords();
050        int schanges = -psize;
051    
052        TypeReference rtype = callee.getReturnType();
053        byte tcode = rtype.getName().parseForTypeCode();
054    
055        if (tcode == VoidTypeCode) {
056          // do nothing
057        } else {
058          if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
059            schanges++;
060          }
061          schanges++;
062        }
063    
064        return schanges;
065      }
066    
067      @Override
068      public String toString() {
069        return "InvokeStatic " + tid;
070      }
071    
072      public static RVMMethod targetMethod(int tid) {
073        switch (tid) {
074          case GETREFAT:
075            return AosEntrypoints.osrGetRefAtMethod;
076          case CLEANREFS:
077            return AosEntrypoints.osrCleanRefsMethod;
078          default:
079            if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
080            return null;
081        }
082      }
083    }