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.mmtk.utility;
014
015import org.mmtk.vm.VM;
016import org.vmmagic.pragma.Uninterruptible;
017import org.vmmagic.unboxed.ObjectReference;
018
019/**
020 * This class provides generic support for operations over the GC byte
021 * within each object's header word. Specifically this class manages
022 * global status bits which cut across policies (for example the logging bit).<p>
023 *
024 * The general pattern for use of the GC byte is that the high order bits
025 * successively reserved for global use, as necessary.  Any GC policy may use
026 * those bits that are not reserved for global use.
027 */
028@Uninterruptible
029public class HeaderByte {
030  private static final int TOTAL_BITS = 8;
031
032  public static final boolean NEEDS_UNLOGGED_BIT = VM.activePlan.constraints().needsLogBitInHeader();
033  private static final int UNLOGGED_BIT_NUMBER = TOTAL_BITS - (NEEDS_UNLOGGED_BIT ? 1 : 0);
034  public static final byte UNLOGGED_BIT = (byte) (1 << UNLOGGED_BIT_NUMBER);
035  public static final int USED_GLOBAL_BITS = TOTAL_BITS - UNLOGGED_BIT_NUMBER;
036
037
038  public static void markAsUnlogged(ObjectReference object) {
039    byte value = VM.objectModel.readAvailableByte(object);
040    VM.objectModel.writeAvailableByte(object, (byte) (value | UNLOGGED_BIT));
041  }
042
043  /**
044   * Mark an object as logged.  Since duplicate logging does
045   * not raise any correctness issues, we do <i>not</i> worry
046   * about synchronization and allow threads to race to log the
047   * object, potentially including it twice (unlike reference
048   * counting where duplicates would lead to incorrect reference
049   * counts).
050   *
051   * @param object The object to be marked as logged
052   */
053  public static void markAsLogged(ObjectReference object) {
054    byte value = VM.objectModel.readAvailableByte(object);
055    VM.objectModel.writeAvailableByte(object, (byte) (value & ~UNLOGGED_BIT));
056  }
057
058  /**
059   * Return {@code true} if the specified object needs to be logged.
060   *
061   * @param object The object in question
062   * @return {@code true} if the object in question needs to be logged (remembered).
063   */
064  public static boolean isUnlogged(ObjectReference object) {
065    byte value = VM.objectModel.readAvailableByte(object);
066    return (value & UNLOGGED_BIT) == UNLOGGED_BIT;
067  }
068}