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.compilers.opt.ir.operand;
014    
015    import java.util.Arrays;
016    import org.jikesrvm.classloader.MemberReference;
017    /*
018     * An InlinedOsrTypeInfoOperand object keeps necessary information
019     * to recover non-inlined status for an inlined method.
020     */
021    
022    public final class InlinedOsrTypeInfoOperand extends Operand {
023    
024      ////////////////////////////////////////////
025      //             DATA Type                  //
026      ////////////////////////////////////////////
027    
028      /* the type info is organized by calling sequences, e.g.,
029       * a calls b calls c, then the type information is
030       * methodids: a_ids, b_ids, c_ids
031       * bcindexes: a_pc,  b_pc,  c_pc
032       * localsize: a_lsize, b_lsize, c_lsize
033       * stacksize: a_ssize, b_sszie, c_sszie
034       * localTypeCodes |-- a_lsize --|-- b_lsize --|-- c_lsize --|
035       * stackTypeCodes |-- a_ssize --|-- b_ssize --|-- c_ssize --|
036       */
037      public int[] methodids;
038      public int[] bcindexes;
039      public byte[][] localTypeCodes;
040      public byte[][] stackTypeCodes;
041    
042      public int validOps;
043    
044      /* operands of OsrPoint is laid out as following:
045         | locals 1 | stacks 1 | locals 2 | stacks 2 | ....
046       */
047    
048      public InlinedOsrTypeInfoOperand(int[] mids, int[] cpcs, byte[][] ltypes, byte[][] stypes) {
049        this.methodids = mids;
050        this.bcindexes = cpcs;
051        this.localTypeCodes = ltypes;
052        this.stackTypeCodes = stypes;
053      }
054    
055      /**
056       * Return a new operand that is semantically equivalent to <code>this</code>.
057       *
058       * @return a copy of <code>this</code>
059       */
060      public Operand copy() {
061        return new InlinedOsrTypeInfoOperand(methodids, bcindexes, localTypeCodes, stackTypeCodes);
062      }
063    
064      /**
065       * Are two operands semantically equivalent?
066       *
067       * @param op other operand
068       * @return   <code>true</code> if <code>this</code> and <code>op</code>
069       *           are semantically equivalent or <code>false</code>
070       *           if they are not.
071       */
072      public boolean similar(Operand op) {
073        boolean result = true;
074    
075        if (!(op instanceof InlinedOsrTypeInfoOperand)) {
076          return false;
077        }
078    
079        InlinedOsrTypeInfoOperand other = (InlinedOsrTypeInfoOperand) op;
080    
081        result =
082            Arrays.equals(this.methodids, other.methodids) &&
083            Arrays.equals(this.bcindexes, other.bcindexes) &&
084            Arrays.equals(this.localTypeCodes, other.localTypeCodes) &&
085            Arrays.equals(this.stackTypeCodes, other.stackTypeCodes);
086    
087        return result;
088      }
089    
090      /**
091       * Returns the string representation of this operand.
092       *
093       * @return a string representation of this operand.
094       */
095      public String toString() {
096        StringBuffer buf = new StringBuffer("(");
097    
098        for (int i = 0, n = methodids.length; i < n; i++) {
099          buf.append(bcindexes[i]).append("@").append(MemberReference.getMemberRef(methodids[i]).getName()).append(" : ");
100    
101          for (int j = 0, m = localTypeCodes[i].length; j < m; j++) {
102            buf.append((char) localTypeCodes[i][j]);
103          }
104    
105          buf.append(",");
106          for (int j = 0, m = stackTypeCodes[i].length; j < m; j++) {
107            buf.append((char) stackTypeCodes[i][j]);
108          }
109    
110          if (i != n - 1) {
111            buf.append(" | ");
112          }
113        }
114        buf.append(")");
115        return new String(buf);
116      }
117    }