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.jikesrvm.objectmodel;
014
015import static org.jikesrvm.runtime.UnboxedSizeConstants.BITS_IN_ADDRESS;
016
017import org.jikesrvm.scheduler.RVMThread;
018import org.vmmagic.unboxed.Word;
019
020/**
021 * Constants used to implement thin locks.
022 * <p>
023 * A portion of a word, either in the object header
024 * or in some other location, is used to provide light weight
025 * synchronization operations. This class defines
026 * how the bits available for thin locks are allocated.
027 * Either a lock is in fat state, in which case it looks like
028 * 1Z..Z where Z..Z is the id of a heavy lock, or it is in
029 * thin state in which case it looks like 0I..IC..C where
030 * I is the thread id of the thread that owns the lock and
031 * C is the recursion count of the lock.
032 * <pre>
033 * aaaaTTTTTTTTTTbbbbb
034 * JavaHeader.NUM_THIN_LOCK_BITS = # of T's
035 * JavaHeader.THIN_LOCK_SHIFT = # of b's
036 * </pre>
037 */
038public final class ThinLockConstants {
039
040  // biased locking / thin locking status bits:
041  // 00 -> thin biasable, and biased if TID is non-zero
042  // 01 -> thin unbiasable
043  // 10 -> fat unbiasable
044
045  public static final int TL_NUM_BITS_STAT = 2;
046  public static final int TL_NUM_BITS_TID = RVMThread.LOG_MAX_THREADS;
047  public static final int TL_NUM_BITS_RC = JavaHeader.NUM_THIN_LOCK_BITS - TL_NUM_BITS_TID - TL_NUM_BITS_STAT;
048
049  public static final int TL_THREAD_ID_SHIFT = JavaHeader.THIN_LOCK_SHIFT;
050  public static final int TL_LOCK_COUNT_SHIFT = TL_THREAD_ID_SHIFT + TL_NUM_BITS_TID;
051  public static final int TL_STAT_SHIFT = TL_LOCK_COUNT_SHIFT + TL_NUM_BITS_RC;
052  public static final int TL_LOCK_ID_SHIFT = JavaHeader.THIN_LOCK_SHIFT;
053  public static final int TL_DEDICATED_U16_OFFSET = JavaHeader.THIN_LOCK_DEDICATED_U16_OFFSET;
054  public static final int TL_DEDICATED_U16_SHIFT = JavaHeader.THIN_LOCK_DEDICATED_U16_SHIFT;
055
056  public static final Word TL_LOCK_COUNT_UNIT = Word.fromIntSignExtend(1 << TL_LOCK_COUNT_SHIFT);
057
058  public static final Word TL_LOCK_COUNT_MASK = Word.fromIntSignExtend(-1).rshl(BITS_IN_ADDRESS - TL_NUM_BITS_RC).lsh(TL_LOCK_COUNT_SHIFT);
059  public static final Word TL_THREAD_ID_MASK = Word.fromIntSignExtend(-1).rshl(BITS_IN_ADDRESS - TL_NUM_BITS_TID).lsh(TL_THREAD_ID_SHIFT);
060  public static final Word TL_LOCK_ID_MASK =
061      Word.fromIntSignExtend(-1).rshl(BITS_IN_ADDRESS - (TL_NUM_BITS_RC + TL_NUM_BITS_TID)).lsh(TL_LOCK_ID_SHIFT);
062  public static final Word TL_STAT_MASK = Word.fromIntSignExtend(-1).rshl(BITS_IN_ADDRESS - TL_NUM_BITS_TID).lsh(TL_STAT_SHIFT);
063  public static final Word TL_UNLOCK_MASK = Word.fromIntSignExtend(-1).rshl(BITS_IN_ADDRESS - JavaHeader
064      .NUM_THIN_LOCK_BITS).lsh(JavaHeader.THIN_LOCK_SHIFT).not();
065
066  public static final Word TL_STAT_BIASABLE = Word.fromIntSignExtend(0).lsh(TL_STAT_SHIFT);
067  public static final Word TL_STAT_THIN = Word.fromIntSignExtend(1).lsh(TL_STAT_SHIFT);
068  public static final Word TL_STAT_FAT = Word.fromIntSignExtend(2).lsh(TL_STAT_SHIFT);
069
070  private ThinLockConstants() {
071    // prevent instantiation
072  }
073
074}
075