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