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}