/*
 *  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;

import org.mmtk.vm.VM;

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

/**
 * This class implements basic memory copying, setting and clearing
 * operations.
 *
 * NOTE: Most of the operations in this class are performed at teh
 * granularity of a Java integer (ie 4-byte units)
 *
 * FIXME: Why can't these operations be performed at word-granularity?
 */
@Uninterruptible
public class Memory implements Constants {

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

  /** zero operations greater than this size are done using the
   * underlying OS implementation of zero() */
  private static final int SMALL_REGION_THRESHOLD = 1<<8; // empirically chosen


  /****************************************************************************
   *
   * Basic memory setting and zeroing operations
   */

  /**
   * Zero a region of memory
   *
   * @param start The start of the region to be zeroed (must be 4-byte aligned)
   * @param bytes The number of bytes to be zeroed (must be 4-byte aligned)
   */
  @Inline
  public static void zero(Address start, Extent bytes) {
    if (VM.VERIFY_ASSERTIONS) {
      assertAligned(start);
      assertAligned(bytes);
    }
    if (bytes.GT(Extent.fromIntZeroExtend(SMALL_REGION_THRESHOLD)))
      VM.memory.zero(start, bytes);
    else
      zeroSmall(start, bytes);
  }

  /**
   * Zero a small region of memory
   *
   * @param start The start of the region to be zeroed (must be 4-byte aligned)
   * @param bytes The number of bytes to be zeroed (must be 4-byte aligned)
   */
  @Inline
  public static void zeroSmall(Address start, Extent bytes) {
    if (VM.VERIFY_ASSERTIONS) {
      assertAligned(start);
      assertAligned(bytes);
    }
    Address end = start.plus(bytes);
    for (Address addr = start; addr.LT(end); addr = addr.plus(BYTES_IN_INT))
      addr.store(0);
  }

  /**
   * Set a region of memory
   *
   * @param start The start of the region to be zeroed (must be 4-byte aligned)
   * @param bytes The number of bytes to be zeroed (must be 4-byte aligned)
   * @param value The value to which the integers in the region should be set
   */
  @Inline
  public static void set(Address start, int bytes, int value) {
    if (VM.VERIFY_ASSERTIONS) {
      assertAligned(start);
      assertAligned(bytes);
    }
    Address end = start.plus(bytes);
    for (Address addr = start; addr.LT(end); addr = addr.plus(BYTES_IN_INT))
      addr.store(value);
  }


  /****************************************************************************
   *
   * Helper methods
   */

  /**
   * Check that a memory range is zeroed
   *
   * @param start The start address of the range to be checked
   * @param bytes The size of the region to be checked, in bytes
   * @return True if the region is zeroed
   */
  @Inline
  public static boolean IsZeroed(Address start, int bytes) {
    return isSet(start, bytes, false, 0);
  }

  /**
   * Assert that a memory range is zeroed.  An assertion failure will
   * occur if the region is not zeroed.
   *
   * this is in the inline allocation sequence when
   * VM.VERIFY_ASSERTIONS is true, it is carefully written to
   * reduce the impact on code space.
   *
   * @param start The start address of the range to be checked
   * @param bytes The size of the region to be checked, in bytes
   */
  @NoInline
  public static void assertIsZeroed(Address start, int bytes) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isSet(start, bytes, true, 0));
  }

  /**
   * Verbosely check and return true if a memory range is set to some
   * integer value
   *
   * @param start The start address of the range to be checked
   * @param bytes The size of the region to be checked, in bytes
   * @param value The value to which this region should be set
   * @return True if the region has been correctly set
   */
  @Inline
  public static boolean isSet(Address start, int bytes, int value) {
    return isSet(start, bytes, true, value);
  }

  /**
   * Assert appropriate alignment, triggering an assertion failure if
   * the value does not satisify the alignment requirement of the
   * memory operations.
   *
   * @param value The value to be tested
   */
  private static void assertAligned(int value) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((value & (BYTES_IN_INT - 1)) == 0);
  }

  private static void assertAligned(Word value) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(value.and(Word.fromIntSignExtend(BYTES_IN_INT-1)).isZero());
  }

  private static void assertAligned(Extent value) {
    assertAligned(value.toWord());
  }

  private static void assertAligned(Address value) {
    assertAligned(value.toWord());
  }

  /**
   * Test whether a memory range is set to a given integer value
   *
   * @param start The address to start checking at
   * @param bytes The size of the region to check, in bytes
   * @param verbose If true, produce verbose output
   * @param value The value to which the memory should be set
   */
  @NoInline
  private static boolean isSet(Address start, int bytes, boolean verbose,
      int value)
    /* Inlining this loop into the uninterruptible code can
     *  cause/encourage the GCP into moving a get_obj_tib into the
     * interruptible region where the tib is being installed via an
     * int_store
   */ {
    if (VM.VERIFY_ASSERTIONS) assertAligned(bytes);
    for (int i = 0; i < bytes; i += BYTES_IN_INT)
      if (start.loadInt(Offset.fromIntSignExtend(i)) != value) {
        if (verbose) {
          Log.prependThreadId();
          Log.write("VM range does not contain only value ");
          Log.writeln(value);
          Log.write("Non-zero range: "); Log.write(start);
          Log.write(" .. "); Log.writeln(start.plus(bytes));
          Log.write("First bad value at "); Log.writeln(start.plus(i));
          dumpMemory(start, 0, bytes);
        }
        return false;
      }
    return true;
  }

  /**
   * Dump the contents of memory around a given address
   *
   * @param addr The address around which the memory should be dumped
   * @param beforeBytes The number of bytes before the address to be
   * included in the dump
   * @param afterBytes The number of bytes after the address to be
   * included in the dump
   */
  public static void dumpMemory(Address addr, int beforeBytes, int afterBytes) {
    VM.memory.dumpMemory(addr, beforeBytes, afterBytes);
  }
}
