美文网首页
CellTypeState.java

CellTypeState.java

作者: 光剑书架上的书 | 来源:发表于2020-09-03 21:14 被阅读0次
    /*
     * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     *
     * This code is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License version 2 only, as
     * published by the Free Software Foundation.
     *
     * This code is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     * version 2 for more details (a copy is included in the LICENSE file that
     * accompanied this code).
     *
     * You should have received a copy of the GNU General Public License version
     * 2 along with this work; if not, write to the Free Software Foundation,
     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     *
     * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     * or visit www.oracle.com if you need additional information or have any
     * questions.
     *
     */
    
    package sun.jvm.hotspot.oops;
    
    import java.io.*;
    import sun.jvm.hotspot.utilities.*;
    
    /** Auxiliary class for GenerateOopMap */
    public class CellTypeState {
      private int _state;
    
      // Masks for separating the BITS and INFO portions of a
      // CellTypeState
      private static final int info_mask = Bits.rightNBits(28);
      private static final int bits_mask = ~info_mask;
    
      // These constant are used for manipulating the BITS portion of a
      // CellTypeState
      private static final int uninit_bit     = Bits.nthBit(31);
      private static final int ref_bit        = Bits.nthBit(30);
      private static final int val_bit        = Bits.nthBit(29);
      private static final int addr_bit       = Bits.nthBit(28);
      private static final int live_bits_mask = bits_mask & ~uninit_bit;
    
      // These constants are used for manipulating the INFO portion of a
      // CellTypeState
      private static final int top_info_bit        = Bits.nthBit(27);
      private static final int not_bottom_info_bit = Bits.nthBit(26);
      private static final int info_data_mask      = Bits.rightNBits(26);
      private static final int info_conflict       = info_mask;
    
      // Within the INFO data, these values are used to distinguish
      // different kinds of references.
      // 0 if this reference is locked as a monitor
      private static final int ref_not_lock_bit    = Bits.nthBit(25);
      // 1 if this reference is a "slot" reference
      private static final int ref_slot_bit        = Bits.nthBit(24);
      // 0 if it is a "line" reference.
      private static final int ref_data_mask       = Bits.rightNBits(24);
    
      // These values are used to initialize commonly used CellTypeState
      // constants.
      private static final int bottom_value        = 0;
      private static final int uninit_value        = uninit_bit | info_conflict;
      private static final int ref_value           = ref_bit;
      private static final int ref_conflict        = ref_bit | info_conflict;
      private static final int val_value           = val_bit | info_conflict;
      private static final int addr_value          = addr_bit;
      private static final int addr_conflict       = addr_bit | info_conflict;
    
      private CellTypeState() {}
    
      private CellTypeState(int state) {
        _state = state;
      }
    
      public CellTypeState copy() {
        return new CellTypeState(_state);
      }
    
      public static CellTypeState makeAny(int state) {
        CellTypeState s = new CellTypeState(state);
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(s.isValidState(), "check to see if CellTypeState is valid");
        }
        return s;
      }
    
      public static CellTypeState makeBottom() {
        return makeAny(0);
      }
    
      public static CellTypeState makeTop() {
        return makeAny(Bits.AllBits);
      }
    
      public static CellTypeState makeAddr(int bci) {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that((bci >= 0) && (bci < info_data_mask),
                      "check to see if ret addr is valid");
        }
        return makeAny(addr_bit | not_bottom_info_bit | (bci & info_data_mask));
      }
    
      public static CellTypeState makeSlotRef(int slot_num) {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(slot_num >= 0 && slot_num < ref_data_mask, "slot out of range");
        }
        return makeAny(ref_bit | not_bottom_info_bit | ref_not_lock_bit | ref_slot_bit |
                       (slot_num & ref_data_mask));
      }
    
      public static CellTypeState makeLineRef(int bci) {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(bci >= 0 && bci < ref_data_mask, "line out of range");
        }
        return makeAny(ref_bit | not_bottom_info_bit | ref_not_lock_bit |
                       (bci & ref_data_mask));
      }
    
      public static CellTypeState makeLockRef(int bci) {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(bci >= 0 && bci < ref_data_mask, "line out of range");
        }
        return makeAny(ref_bit | not_bottom_info_bit | (bci & ref_data_mask));
      }
    
      // Query methods:
      public boolean isBottom()     { return _state == 0; }
      public boolean isLive()       { return ((_state & live_bits_mask) != 0); }
      public boolean isValidState() {
        // Uninitialized and value cells must contain no data in their info field:
        if ((canBeUninit() || canBeValue()) && !isInfoTop()) {
          return false;
        }
        // The top bit is only set when all info bits are set:
        if (isInfoTop() && ((_state & info_mask) != info_mask)) {
          return false;
        }
        // The not_bottom_bit must be set when any other info bit is set:
        if (isInfoBottom() && ((_state & info_mask) != 0)) {
          return false;
        }
        return true;
      }
    
      public boolean isAddress()      { return ((_state & bits_mask) == addr_bit); }
      public boolean isReference()    { return ((_state & bits_mask) == ref_bit); }
      public boolean isValue()        { return ((_state & bits_mask) == val_bit); }
      public boolean isUninit()       { return ((_state & bits_mask) == uninit_bit); }
    
      public boolean canBeAddress()   { return ((_state & addr_bit) != 0); }
      public boolean canBeReference() { return ((_state & ref_bit) != 0); }
      public boolean canBeValue()     { return ((_state & val_bit) != 0); }
      public boolean canBeUninit()    { return ((_state & uninit_bit) != 0); }
    
      public boolean isInfoBottom()   { return ((_state & not_bottom_info_bit) == 0); }
      public boolean isInfoTop()      { return ((_state & top_info_bit) != 0); }
      public int     getInfo() {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that((!isInfoTop() && !isInfoBottom()),
                      "check to make sure top/bottom info is not used");
        }
        return (_state & info_data_mask);
      }
    
      public int     getMonitorSource() {
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(isLockReference(), "must be lock");
        }
        return getInfo();
      }
    
      public boolean isGoodAddress()   { return isAddress() && !isInfoTop(); }
      public boolean isLockReference() {
        return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == ref_bit);
      }
      public boolean isNonlockReference() {
        return ((_state & (bits_mask | top_info_bit | ref_not_lock_bit)) == (ref_bit | ref_not_lock_bit));
      }
    
      public boolean equal(CellTypeState a)     { return _state == a._state; }
      public boolean equalKind(CellTypeState a) {
        return (_state & bits_mask) == (a._state & bits_mask);
      }
    
      public char toChar() {
        if (canBeReference()) {
          if (canBeValue() || canBeAddress())
            return '#';    // Conflict that needs to be rewritten
          else
            return 'r';
        } else if (canBeValue())
          return 'v';
        else if (canBeAddress())
          return 'p';
        else if (canBeUninit())
          return ' ';
        else
          return '@';
      }
    
      // Set
      public void set(CellTypeState cts) {
        _state = cts._state;
      }
    
      // Merge
      public CellTypeState merge (CellTypeState cts, int slot) {
        CellTypeState result = new CellTypeState();
    
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(!isBottom() && !cts.isBottom(),
                      "merge of bottom values is handled elsewhere");
        }
    
        result._state = _state | cts._state;
    
        // If the top bit is set, we don't need to do any more work.
        if (!result.isInfoTop()) {
          Assert.that((result.canBeAddress() || result.canBeReference()),
                      "only addresses and references have non-top info");
    
          if (!equal(cts)) {
            // The two values being merged are different.  Raise to top.
            if (result.isReference()) {
              result = CellTypeState.makeSlotRef(slot);
            } else {
              result._state |= info_conflict;
            }
          }
        }
        if (Assert.ASSERTS_ENABLED) {
          Assert.that(result.isValidState(), "checking that CTS merge maintains legal state");
        }
    
        return result;
      }
    
      // Debugging output
      public void print(PrintStream tty) {
        if (canBeAddress()) {
          tty.print("(p");
        } else {
          tty.print("( ");
        }
        if (canBeReference()) {
          tty.print("r");
        } else {
          tty.print(" ");
        }
        if (canBeValue()) {
          tty.print("v");
        } else {
          tty.print(" ");
        }
        if (canBeUninit()) {
          tty.print("u|");
        } else {
          tty.print(" |");
        }
        if (isInfoTop()) {
          tty.print("Top)");
        } else if (isInfoBottom()) {
          tty.print("Bot)");
        } else {
          if (isReference()) {
            int info = getInfo();
            int data = info & ~(ref_not_lock_bit | ref_slot_bit);
            if ((info & ref_not_lock_bit) != 0) {
              // Not a monitor lock reference.
              if ((info & ref_slot_bit) != 0) {
                // slot
                tty.print("slot" + data + ")");
              } else {
                // line
                tty.print("line" + data + ")");
              }
            } else {
              // lock
              tty.print("lock" + data + ")");
            }
          } else {
            tty.print("" + getInfo() + ")");
          }
        }
      }
    
      // Default values of common values
      public static CellTypeState bottom    = CellTypeState.makeBottom();
      public static CellTypeState uninit    = CellTypeState.makeAny(uninit_value);
      public static CellTypeState ref       = CellTypeState.makeAny(ref_conflict);
      public static CellTypeState value     = CellTypeState.makeAny(val_value);
      public static CellTypeState refUninit = CellTypeState.makeAny(ref_conflict | uninit_value);
      public static CellTypeState top       = CellTypeState.makeTop();
      public static CellTypeState addr      = CellTypeState.makeAny(addr_conflict);
    }
    
    

    相关文章

      网友评论

          本文标题:CellTypeState.java

          本文链接:https://www.haomeiwen.com/subject/zuaosktx.html