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

import org.mmtk.plan.Plan;
import org.mmtk.policy.Space;
import org.mmtk.utility.*;
import org.mmtk.utility.statistics.*;

import org.mmtk.vm.VM;

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

/**
 * This abstract base class provides the basis for processor-local
 * allocation.  The key functionality provided is the retry mechanism
 * that is necessary to correctly handle the fact that a "slow-path"
 * allocation can cause a GC which violate the uninterruptability assumption.
 * This results in the thread being moved to a different processor so that
 * the allocator object it is using is not actually the one for the processor
 * it is running on.
 *
 * This class also includes functionality to assist allocators with
 * ensuring that requests are aligned according to requests.
 *
 * Failing to handle this properly will lead to very hard to trace bugs
 * where the allocation that caused a GC or allocations immediately following
 * GC are run incorrectly.
 */
@Uninterruptible public abstract class Allocator implements Constants {

  /**
   * Return the space this allocator is currently bound to.
   *
   * @return The Space.
   */
  protected abstract Space getSpace();

  /**
   * Aligns up an allocation request. The allocation request accepts a
   * region, that must be at least particle aligned, an alignment
   * request (some power of two number of particles) and an offset (a
   * number of particles). There is also a knownAlignment parameter to
   * allow a more optimised check when the particular allocator in use
   * always aligns at a coarser grain than individual particles, such
   * as some free lists.
   *
   * @param region The region to align up.
   * @param alignment The requested alignment
   * @param offset The offset from the alignment
   * @param knownAlignment The statically known minimum alignment.
   * @return The aligned up address.
   */
  @Inline
  public static Address alignAllocation(Address region, int alignment, int offset, int knownAlignment, boolean fillAlignmentGap) {
    if (VM.VERIFY_ASSERTIONS) {
      VM.assertions._assert(knownAlignment >= MIN_ALIGNMENT);
      VM.assertions._assert(MIN_ALIGNMENT >= BYTES_IN_INT);
      VM.assertions._assert(!(fillAlignmentGap && region.isZero()));
      VM.assertions._assert(alignment <= MAX_ALIGNMENT);
      VM.assertions._assert(offset >= 0);
      VM.assertions._assert(region.toWord().and(Word.fromIntSignExtend(MIN_ALIGNMENT-1)).isZero());
      VM.assertions._assert((alignment & (MIN_ALIGNMENT - 1)) == 0);
      VM.assertions._assert((offset & (MIN_ALIGNMENT - 1)) == 0);
    }

    // No alignment ever required.
    if (alignment <= knownAlignment || MAX_ALIGNMENT <= MIN_ALIGNMENT)
      return region;

    // May require an alignment
    Word mask = Word.fromIntSignExtend(alignment - 1);
    Word negOff = Word.fromIntSignExtend(-offset);
    Offset delta = negOff.minus(region.toWord()).and(mask).toOffset();

    if (fillAlignmentGap && ALIGNMENT_VALUE != 0) {
      if ((MAX_ALIGNMENT - MIN_ALIGNMENT) == BYTES_IN_WORD) {
        // At most a single hole
        if (delta.toInt() == (BYTES_IN_WORD)) {
          region.store(Word.fromIntSignExtend(ALIGNMENT_VALUE));
          region = region.plus(delta);
        return region;
        }
      } else {
        while (delta.toInt() >= (BYTES_IN_WORD)) {
          region.store(Word.fromIntSignExtend(ALIGNMENT_VALUE));
          region = region.plus(BYTES_IN_WORD);
          delta = delta.minus(BYTES_IN_WORD);
        }
      }
    }

    return region.plus(delta);
  }

  /**
   * Fill the specified region with the alignment value.
   *
   * @param start The start of the region.
   * @param end A pointer past the end of the region.
   */
  @Inline
  public static void fillAlignmentGap(Address start, Address end) {
    if ((MAX_ALIGNMENT - MIN_ALIGNMENT) == BYTES_IN_INT) {
      // At most a single hole
      if (!end.diff(start).isZero()) {
        start.store(ALIGNMENT_VALUE);
      }
    } else {
      while (start.LT(end)) {
        start.store(ALIGNMENT_VALUE);
        start = start.plus(BYTES_IN_INT);
      }
    }
  }

  /**
   * Aligns up an allocation request. The allocation request accepts a
   * region, that must be at least particle aligned, an alignment
   * request (some power of two number of particles) and an offset (a
   * number of particles).
   *
   * @param region The region to align up.
   * @param alignment The requested alignment
   * @param offset The offset from the alignment
   * @return The aligned up address.
   */
  @Inline
  public static Address alignAllocation(Address region, int alignment, int offset) {
    return alignAllocation(region, alignment, offset, MIN_ALIGNMENT, true);
  }

  /**
   * Aligns up an allocation request. The allocation request accepts a
   * region, that must be at least particle aligned, an alignment
   * request (some power of two number of particles) and an offset (a
   * number of particles).
   *
   * @param region The region to align up.
   * @param alignment The requested alignment
   * @param offset The offset from the alignment
   * @return The aligned up address.
   */
  @Inline
  public static Address alignAllocationNoFill(Address region, int alignment, int offset) {
    return alignAllocation(region, alignment, offset, MIN_ALIGNMENT, false);
  }

  /**
   * This method calculates the minimum size that will guarantee the allocation
   * of a specified number of bytes at the specified alignment.
   *
   * @param size The number of bytes (not aligned).
   * @param alignment The requested alignment (some factor of 2).
   */
  @Inline
  public static int getMaximumAlignedSize(int size, int alignment) {
    return getMaximumAlignedSize(size, alignment, MIN_ALIGNMENT);
  }

  /**
   * This method calculates the minimum size that will guarantee the allocation
   * of a specified number of bytes at the specified alignment.
   *
   * @param size The number of bytes (not aligned).
   * @param alignment The requested alignment (some factor of 2).
   * @param knownAlignment The known minimum alignment. Specifically for use in
   * allocators that enforce greater than particle alignment. It is a <b>precondition</b>
   * that size is aligned to knownAlignment, and that knownAlignment >= MIN_ALGINMENT.
   */
  @Inline
  public static int getMaximumAlignedSize(int size, int alignment, int knownAlignment) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(size == Conversions.roundDown(size, knownAlignment));
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(knownAlignment >= MIN_ALIGNMENT);

    if (MAX_ALIGNMENT <= MIN_ALIGNMENT || alignment <= knownAlignment) {
      return size;
    } else {
      return size + alignment - knownAlignment;
    }
  }

  /**
   * Single slow path allocation attempt. This is called by allocSlow.
   *
   * @param bytes The size of the allocation request
   * @param alignment The required alignment
   * @param offset The alignment offset
   * @return The start address of the region, or zero if allocation fails
   */
  protected abstract Address allocSlowOnce(int bytes, int alignment, int offset);

  /**
   * <b>Out-of-line</b> slow path allocation. This method forces slow path
   * allocation to be out of line (typically desirable, but not when the
   * calling context is already explicitly out-of-line).
   *
   * @param bytes The size of the allocation request
   * @param alignment The required alignment
   * @param offset The alignment offset
   * @return The start address of the region, or zero if allocation fails
   */
  @NoInline
  public final Address allocSlow(int bytes, int alignment, int offset) {
    return allocSlowInline(bytes, alignment, offset);
  }

  /**
   * <b>Inline</b> slow path allocation. This method attempts allocSlowOnce
   * several times, and allows collection to occur, and ensures that execution
   * safely resumes by taking care of potential thread/mutator context affinity
   * changes. All allocators should use this as the trampoline for slow
   * path allocation.
   *
   * @param bytes The size of the allocation request
   * @param alignment The required alignment
   * @param offset The alignment offset
   * @return The start address of the region, or zero if allocation fails
   */
  @Inline
  public final Address allocSlowInline(int bytes, int alignment, int offset) {
    int gcCountStart = Stats.gcCount();
    Allocator current = this;
    Space space = current.getSpace();
    for (int i = 0; i < Plan.MAX_COLLECTION_ATTEMPTS; i++) {
      Address result = current.allocSlowOnce(bytes, alignment, offset);
      if (!result.isZero()) {
        return result;
      }
      if (!Plan.gcInProgress()) {
        /* This is in case a GC occurs, and our mutator context is stale.
         * In some VMs the scheduler can change the affinity between the
         * current thread and the mutator context. This is possible for
         * VMs that dynamically multiplex Java threads onto multiple mutator
         * contexts, */
        current = VM.activePlan.mutator().getAllocatorFromSpace(space);
      }
    }
    Log.write("GC Error: Allocator.allocSlow failed on request of ");
    Log.write(bytes);
    Log.write(" on space ");
    Log.writeln(space.getName());
    Log.write("gcCountStart = ");
    Log.writeln(gcCountStart);
    Log.write("gcCount (now) = ");
    Log.writeln(Stats.gcCount());
    Space.printUsageMB();
    VM.assertions.fail("Allocation Failed!");
    /* NOTREACHED */
    return Address.zero();
  }
}
