/*
 *  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.utility.heap;

import org.mmtk.policy.Space;
import org.mmtk.utility.Constants;

import org.mmtk.vm.VM;

import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;

/**
 * This class manages the encoding and decoding of space descriptors.<p>
 *
 * Space descriptors are integers that encode a space's mapping into
 * virtual memory.  For discontiguous spaces, they indicate
 * discontiguity and mapping must be done by consulting the space map.
 * For contiguous spaces, the space's address range is encoded into
 * the integer (using a fixed point notation).<p>
 *
 * The purpose of this class is to allow <code>static final int</code>
 * space descriptors to exist for each space, which can then be used
 * in tests to determine whether an object is in a space.  A good
 * compiler can perform this decoding at compile time and produce
 * optimal code for the test.
 */
@Uninterruptible public class SpaceDescriptor implements Constants {

  /****************************************************************************
   *
   * Class variables
   */

  private static final int TYPE_BITS = 2;
  private static final int TYPE_SHARED = 0;
  private static final int TYPE_CONTIGUOUS = 1;
  private static final int TYPE_CONTIGUOUS_HI = 3;
  private static final int TYPE_MASK = (1 << TYPE_BITS) - 1;
  private static final int SIZE_SHIFT = TYPE_BITS;
  private static final int SIZE_BITS = 10;
  private static final int SIZE_MASK = ((1 << SIZE_BITS) - 1) << SIZE_SHIFT;
  private static final int EXPONENT_SHIFT = SIZE_SHIFT + SIZE_BITS;
  private static final int EXPONENT_BITS = 5;
  private static final int EXPONENT_MASK = ((1 << EXPONENT_BITS) - 1) << EXPONENT_SHIFT;
  private static final int MANTISSA_SHIFT = EXPONENT_SHIFT + EXPONENT_BITS;
  private static final int MANTISSA_BITS = 14;
  private static final int BASE_EXPONENT = BITS_IN_INT - MANTISSA_BITS;

  private static int discontiguousSpaceIndex = 0;
  private static final int DISCONTIG_INDEX_INCREMENT = 1<<TYPE_BITS;

  /****************************************************************************
   *
   * Descriptor creation
   */

  /**
   * Create a descriptor for a <i>contiguous</i> space
   *
   * @param start The start address of the space
   * @param end The end address of the space
   * @return An integer descriptor encoding the region of virtual
   * memory occupied by the space
   */
  public static int createDescriptor(Address start, Address end) {
    int chunks = end.diff(start).toWord().rshl(Space.LOG_BYTES_IN_CHUNK).toInt();
    if (VM.VERIFY_ASSERTIONS)
      VM.assertions._assert(!start.isZero() && chunks > 0 && chunks < (1 << SIZE_BITS));
    boolean top = end.EQ(Space.HEAP_END);
    Word tmp = start.toWord();
    tmp = tmp.rshl(BASE_EXPONENT);
    int exponent = 0;
    while (!tmp.isZero() && tmp.and(Word.one()).isZero()) {
      tmp = tmp.rshl(1);
      exponent++;
    }
    int mantissa = tmp.toInt();
    if (VM.VERIFY_ASSERTIONS)
      VM.assertions._assert(tmp.lsh(BASE_EXPONENT + exponent).EQ(start.toWord()));
    return (mantissa<<MANTISSA_SHIFT) |
           (exponent<<EXPONENT_SHIFT) |
           (chunks << SIZE_SHIFT) |
           ((top) ? TYPE_CONTIGUOUS_HI : TYPE_CONTIGUOUS);
  }

  /**
   * Create a descriptor for a <i>dis-contiguous</i> (shared) space
   *
   * @return An integer descriptor reflecting the fact that this space
   * is shared (and thus discontiguous and so must be established via
   * maps).
   */
  public static int createDescriptor() {
    discontiguousSpaceIndex += DISCONTIG_INDEX_INCREMENT;
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((discontiguousSpaceIndex & TYPE_CONTIGUOUS) != TYPE_CONTIGUOUS);
    return discontiguousSpaceIndex;
  }

  /****************************************************************************
   *
   * Descriptor interrogation
   */

  /**
   * Return true if this descriptor describes a contiguous space
   *
   * @param descriptor
   * @return True if this descriptor describes a contiguous space
   */
  @Inline
  public static boolean isContiguous(int descriptor) {
    return ((descriptor & TYPE_CONTIGUOUS) == TYPE_CONTIGUOUS);
  }

  /**
   * Return true if this descriptor describes a contiguous space that
   * is at the top of the virtual address space
   *
   * @param descriptor
   * @return True if this descriptor describes a contiguous space that
   * is at the top of the virtual address space
   */
  @Inline
  public static boolean isContiguousHi(int descriptor) {
    return ((descriptor & TYPE_MASK) == TYPE_CONTIGUOUS_HI);
  }

  /**
   * Return the start of this region of memory encoded in this descriptor
   *
   * @param descriptor
   * @return The start of this region of memory encoded in this descriptor
   */
  @Inline
  public static Address getStart(int descriptor) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isContiguous(descriptor));
    Word mantissa = Word.fromIntSignExtend(descriptor >>> MANTISSA_SHIFT);
    int exponent = (descriptor & EXPONENT_MASK) >>> EXPONENT_SHIFT;
    return mantissa.lsh(BASE_EXPONENT + exponent).toAddress();
  }

  /**
   * Return the size of the region of memory encoded in this
   * descriptor, in chunks
   *
   * @param descriptor
   * @return The size of the region of memory encoded in this
   * descriptor, in chunks
   */
  @Inline
  public static int getChunks(int descriptor) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isContiguous(descriptor));
    return (descriptor & SIZE_MASK) >>> SIZE_SHIFT;
  }
}
