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.compilers.opt.escape;
014
015import org.jikesrvm.classloader.RVMMethod;
016
017/**
018 * Hold semantic information about a method that is not defined in
019 * RVMMethod.
020 */
021class MethodSummary {
022
023  /**
024   * Long is 64 bits, but we need to reserve a bit for the result
025   * and we start counting at zero.
026   */
027  private static final int MAXIMUM_PARAMETER_INDEX = 62;
028
029  /**
030   * Is this method currently being analyzed?  Used for recursive
031   * invocations of the optimizing compiler.
032   */
033  private boolean inProgress = false;
034
035  private static final long RESULT_ESCAPES = 0x8000000000000000L;
036
037  private static final long EVERYTHING_ESCAPES = 0xFFFFFFFFFFFFFFFFL;
038
039  /**
040   * Escape result. Top bit is for the result of the method, i.e. the
041   * return value. The this parameter counts as a parameter.
042   */
043  private long escapeInfo;
044
045  /**
046   * @param m RVMMethod representing this method.
047   */
048  MethodSummary(RVMMethod m) {
049    escapeInfo = EVERYTHING_ESCAPES;
050  }
051
052  /**
053   * Record that a parameter may or may not escape from a thread.
054   *
055   * @param p the number of the parameter
056   * @param b may it escape?
057   */
058  public void setParameterMayEscapeThread(int p, boolean b) {
059    if (p > MAXIMUM_PARAMETER_INDEX) return;
060    long mask = 1L << p;
061    if (b) {
062      escapeInfo |= mask;
063    } else {
064      escapeInfo &= (~mask);
065    }
066  }
067
068  /**
069   * Query whether a parameter may escape from a thread.
070   * @param p the number of the parameter
071   * @return {@code false} iff the parameter <em>cannot</em> escape from the
072   * thread, {@code true} otherwise.
073   */
074  public boolean parameterMayEscapeThread(int p) {
075    if (p > MAXIMUM_PARAMETER_INDEX) return true;
076    long mask = 1L << p;
077    return (escapeInfo & mask) != 0;
078  }
079
080  /**
081   * Record that a result of this method may or may not escape from a thread.
082   *
083   * @param b may it escape?
084   */
085  public void setResultMayEscapeThread(boolean b) {
086    if (b) {
087      escapeInfo |= RESULT_ESCAPES;
088    } else {
089      escapeInfo &= ~RESULT_ESCAPES;
090    }
091  }
092
093  /**
094   * Query whether the result of this method may escape from a thread.
095   * @return {@code false} iff the parameter <em> cannot </em> escape from the
096   * thread, {@code true} otherwise.
097   */
098  public boolean resultMayEscapeThread() {
099    return (escapeInfo & RESULT_ESCAPES) != 0L;
100  }
101
102  /**
103   * @return whether the analysis of this method is in progress
104   */
105  public boolean inProgress() {
106    return inProgress;
107  }
108
109  public void setInProgress(boolean b) {
110    inProgress = b;
111  }
112}