/*
 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
 *
 *  This file is licensed to You under the Eclipse Public License (EPL);
 *  You may not use this file except in compliance with the License. You
 *  may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/eclipse-1.0.php
 *
 *  See the COPYRIGHT.txt file distributed with this work for information
 *  regarding copyright ownership.
 */
package org.mmtk.plan.refcount;

import org.mmtk.utility.Constants;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Word;

@Uninterruptible
public class RCHeader implements Constants {
  /* Requirements */
  public static final int LOCAL_GC_BITS_REQUIRED = 0;
  public static final int GLOBAL_GC_BITS_REQUIRED = 2;
  public static final int GC_HEADER_WORDS_REQUIRED = 1;

  /****************************************************************************
   * Object Logging (applies to *all* objects)
   */

  /* Mask bits to signify the start/finish of logging an object */
  public static final int      LOG_BIT  = 0;
  public static final Word       LOGGED = Word.zero();                          //...00000
  public static final Word    UNLOGGED  = Word.one();                           //...00001
  public static final Word BEING_LOGGED = Word.one().lsh(2).minus(Word.one());  //...00011
  public static final Word LOGGING_MASK = LOGGED.or(UNLOGGED).or(BEING_LOGGED); //...00011

  /**
   * Return true if <code>object</code> is yet to be logged (for
   * coalescing RC).
   *
   * @param object The object in question
   * @return <code>true</code> if <code>object</code> needs to be logged.
   */
  @Inline
  @Uninterruptible
  public static boolean logRequired(ObjectReference object) {
    Word value = VM.objectModel.readAvailableBitsWord(object);
    return value.and(LOGGING_MASK).EQ(UNLOGGED);
  }

  /**
   * Attempt to log <code>object</code> for coalescing RC. This is
   * used to handle a race to log the object, and returns
   * <code>true</code> if we are to log the object and
   * <code>false</code> if we lost the race to log the object.
   *
   * <p>If this method returns <code>true</code>, it leaves the object
   * in the <code>BEING_LOGGED</code> state.  It is the responsibility
   * of the caller to change the object to <code>LOGGED</code> once
   * the logging is complete.
   *
   * @see #makeLogged(ObjectReference)
   * @param object The object in question
   * @return <code>true</code> if the race to log
   * <code>object</code>was won.
   */
  @Inline
  @Uninterruptible
  public static boolean attemptToLog(ObjectReference object) {
    Word oldValue;
    do {
      oldValue = VM.objectModel.prepareAvailableBits(object);
      if (oldValue.and(LOGGING_MASK).EQ(LOGGED)) {
        return false;
      }
    } while ((oldValue.and(LOGGING_MASK).EQ(BEING_LOGGED)) ||
             !VM.objectModel.attemptAvailableBits(object, oldValue, oldValue.or(BEING_LOGGED)));
    if (VM.VERIFY_ASSERTIONS) {
      Word value = VM.objectModel.readAvailableBitsWord(object);
      VM.assertions._assert(value.and(LOGGING_MASK).EQ(BEING_LOGGED));
    }
    return true;
  }


  /**
   * Signify completion of logging <code>object</code>.
   *
   * <code>object</code> is left in the <code>LOGGED</code> state.
   *
   * @see #attemptToLog(ObjectReference)
   * @param object The object whose state is to be changed.
   */
  @Inline
  @Uninterruptible
  public static void makeLogged(ObjectReference object) {
    Word value = VM.objectModel.readAvailableBitsWord(object);
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(value.and(LOGGING_MASK).NE(LOGGED));
    VM.objectModel.writeAvailableBitsWord(object, value.and(LOGGING_MASK.not()));
  }

  /**
   * Change <code>object</code>'s state to <code>UNLOGGED</code>.
   *
   * @param object The object whose state is to be changed.
   */
  @Inline
  @Uninterruptible
  public static void makeUnlogged(ObjectReference object) {
    Word value = VM.objectModel.readAvailableBitsWord(object);
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(value.and(LOGGING_MASK).EQ(LOGGED));
    VM.objectModel.writeAvailableBitsWord(object, value.or(UNLOGGED));
  }

  /************************************************************************
   * RC header word
   */

  /* Header offset */
  public static final Offset RC_HEADER_OFFSET = VM.objectModel.GC_HEADER_OFFSET();

  /* Reserved to allow alignment hole filling to work */
  public static final int RESERVED_ALIGN_BIT = 0;

  /* The mark bit used for backup tracing. */
  public static final int MARK_BIT = 1;
  public static final Word MARK_BIT_MASK = Word.one().lsh(MARK_BIT);

  /* Current not using any bits for cycle detection, etc */
  public static final int BITS_USED = 2;

  /* Reference counting increments */
  public static final int INCREMENT_SHIFT = BITS_USED;
  public static final Word INCREMENT = Word.one().lsh(INCREMENT_SHIFT);
  public static final int AVAILABLE_BITS = BITS_IN_ADDRESS - BITS_USED;
  public static final Word INCREMENT_LIMIT = Word.one().lsh(BITS_IN_ADDRESS-1).not();
  public static final Word LIVE_THRESHOLD = INCREMENT;

  /* Return values from decRC */
  public static final int DEC_KILL = 0;
  public static final int DEC_ALIVE = 1;

  /**
   * Has this object been marked by the most recent backup trace.
   */
  @Inline
  public static boolean isMarked(ObjectReference object) {
    return isHeaderMarked(object.toAddress().loadWord(RC_HEADER_OFFSET));
  }

  /**
   * Has this object been marked by the most recent backup trace.
   */
  @Inline
  public static void clearMarked(ObjectReference object) {
    Word oldValue, newValue;
    do {
      oldValue = object.toAddress().prepareWord(RC_HEADER_OFFSET);
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isHeaderMarked(oldValue));
      newValue = oldValue.and(MARK_BIT_MASK.not());
    } while (!object.toAddress().attempt(oldValue, newValue, RC_HEADER_OFFSET));
    /*
    Word header = object.toAddress().loadWord(RC_HEADER_OFFSET);
    object.toAddress().store(header.and(MARK_BIT_MASK.not()), RC_HEADER_OFFSET);*/
  }

  /**
   * Has this object been marked by the most recent backup trace.
   */
  @Inline
  private static boolean isHeaderMarked(Word header) {
    return header.and(MARK_BIT_MASK).EQ(MARK_BIT_MASK);
  }

  /**
   * Attempt to atomically mark this object. Return true if the mark was performed.
   */
  @Inline
  public static boolean testAndMark(ObjectReference object) {
    Word oldValue, newValue;
    do {
      oldValue = object.toAddress().prepareWord(RC_HEADER_OFFSET);
      if (isHeaderMarked(oldValue)) {
        return false;
      }
      newValue = oldValue.or(MARK_BIT_MASK);
    } while (!object.toAddress().attempt(oldValue, newValue, RC_HEADER_OFFSET));
    return true;
  }

  /**
   * Perform any required initialization of the GC portion of the header.
   *
   * @param object the object
   * @param initialInc start with a reference count of 1 (0 if false)
   */
  @Inline
  public static void initializeHeader(ObjectReference object, boolean initialInc) {
    Word initialValue =  (initialInc) ? INCREMENT : Word.zero();
    object.toAddress().store(initialValue, RC_HEADER_OFFSET);
  }

  /**
   * Return true if given object is live
   *
   * @param object The object whose liveness is to be tested
   * @return True if the object is alive
   */
  @Inline
  @Uninterruptible
  public static boolean isLiveRC(ObjectReference object) {
    return object.toAddress().loadWord(RC_HEADER_OFFSET).GE(LIVE_THRESHOLD);
  }

  /**
   * Return the reference count for the object.
   *
   * @param object The object whose liveness is to be tested
   * @return True if the object is alive
   */
  @Inline
  @Uninterruptible
  public static int getRC(ObjectReference object) {
    return object.toAddress().loadWord(RC_HEADER_OFFSET).rshl(INCREMENT_SHIFT).toInt();
  }

  /**
   * Increment the reference count of an object.
   *
   * @param object The object whose reference count is to be incremented.
   */
  @Inline
  public static void incRC(ObjectReference object) {
    Word oldValue, newValue;
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(RCBase.isRCObject(object));
    do {
      oldValue = object.toAddress().prepareWord(RC_HEADER_OFFSET);
      newValue = oldValue.plus(INCREMENT);
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(newValue.LE(INCREMENT_LIMIT));
    } while (!object.toAddress().attempt(oldValue, newValue, RC_HEADER_OFFSET));
  }

  /**
   * Decrement the reference count of an object.  Return either
   * <code>DEC_KILL</code> if the count went to zero,
   * <code>DEC_ALIVE</code> if the count did not go to zero.
   *
   * @param object The object whose RC is to be decremented.
   * @return <code>DEC_KILL</code> if the count went to zero,
   * <code>DEC_ALIVE</code> if the count did not go to zero.
   */
  @Inline
  @Uninterruptible
  public static int decRC(ObjectReference object) {
    Word oldValue, newValue;
    int rtn;
    if (VM.VERIFY_ASSERTIONS) {
      VM.assertions._assert(RCBase.isRCObject(object));
      VM.assertions._assert(isLiveRC(object));
    }
    do {
      oldValue = object.toAddress().prepareWord(RC_HEADER_OFFSET);
      newValue = oldValue.minus(INCREMENT);
      if (newValue.LT(LIVE_THRESHOLD)) {
        rtn = DEC_KILL;
      } else {
        rtn = DEC_ALIVE;
      }
    } while (!object.toAddress().attempt(oldValue, newValue, RC_HEADER_OFFSET));
    return rtn;
  }
}
