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

import org.mmtk.utility.Log;
import org.mmtk.utility.TracingConstants;
import org.mmtk.vm.VM;
import org.mmtk.utility.Constants;

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

/**
 * This supports <i>unsynchronized</i> enqueuing and dequeuing of tracing data
 * and bulk processing of the buffer.
 */
@Uninterruptible public class TraceBuffer extends LocalQueue
  implements Constants, TracingConstants {

  /***********************************************************************
   *
   * Class based constants
   */
  private static final Word TRACE_NEW_RECORD = Word.fromIntSignExtend(3);
  private static final Word TRACE_ALLOC_SIZE = Word.fromIntSignExtend(5);
//  private static final Word TRACE_ALLOC_NAME = Word.fromIntSignExtend(6);
  private static final Word TRACE_ALLOC_FP = Word.fromIntSignExtend(7);
  private static final Word TRACE_ALLOC_THREAD = Word.fromIntSignExtend(9);
  private static final Word TRACE_TIB_VALUE = Word.fromIntSignExtend(10);
  private static final Word TRACE_DEATH_TIME = Word.fromIntSignExtend(11);
  private static final Word TRACE_FIELD_TARGET = Word.fromIntSignExtend(12);
  private static final Word TRACE_ARRAY_TARGET = Word.fromIntSignExtend(13);
  private static final Word TRACE_FIELD_SLOT = Word.fromIntSignExtend(14);
  private static final Word TRACE_ARRAY_ELEMENT = Word.fromIntSignExtend(15);
  private static final Word TRACE_STATIC_TARGET = Word.fromIntSignExtend(17);
  private static final Word TRACE_BOOT_ALLOC_SIZE = Word.fromIntSignExtend(18);

  /*
   * Debugging and trace reducing constants
   */
  public static final boolean OMIT_ALLOCS=false;
  public static final boolean OMIT_UPDATES=false;
  public static final boolean OMIT_BOOTALLOCS=false;
  public static final boolean OMIT_UNREACHABLES=false;
  public static final boolean OMIT_OTHERS=false;
  public static final boolean OMIT_OUTPUT=OMIT_ALLOCS && OMIT_UPDATES &&
                                          OMIT_OTHERS;


  /***********************************************************************
   *
   * Public methods
   */

  /**
   * Constructor
   *
   * @param pool The shared queue to which this queue will append its
   * buffers (when full or flushed) and from which it will aquire new
   * buffers when it has exhausted its own.
   */
  public TraceBuffer(SharedDeque pool) {
    super(pool);
  }

  /**
   * Push word onto the tracing queue.
   *
   * @param i The data to be pushed onto the tracing queue
   */
  @Inline
  public final void push(Word i) {
    checkTailInsert(1);
    uncheckedTailInsert(i.toAddress());
  }

  /**
   * Process the data in the tracing buffer, output information as needed.
   */
  public final void process() {
    Word traceState = TRACE_NEW_RECORD;
    int entriesNotFlushed = 0;
    boolean loggedRecord = false;
    /* First we must flush any remaining data */
    if (!OMIT_OUTPUT) Log.writeln();

    /* Process through the entire buffer. */
    while (checkDequeue(1)) {
      /* For speed and efficiency, we will actually process the data buffer by
         buffer and not by dequeue-ing each entry. */
      while (!bufferOffset(head).isZero()) {
        head = head.minus(BYTES_IN_ADDRESS);
        Word val = head.loadWord();
        if (traceState.EQ(TRACE_NEW_RECORD)) {
          loggedRecord = false;
          if (val.EQ(TRACE_GCSTART)) {
            if (!OMIT_OTHERS) {
              Log.write('G');
              Log.write('C');
              Log.writeln('B', true);
            }
          } else if (val.EQ(TRACE_GCEND)) {
            if (!OMIT_OTHERS) {
              Log.write('G');
              Log.write('C');
              Log.writeln('E', true);
            }
          } else {
            traceState = val;
          }
        } else {
          if (traceState.EQ(TRACE_EXACT_ALLOC) ||
              traceState.EQ(TRACE_ALLOC)) {
            if (!OMIT_ALLOCS) {
              Log.write((traceState.EQ(TRACE_EXACT_ALLOC)) ? 'A' : 'a');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_ALLOC_SIZE;
          } else if (traceState.EQ(TRACE_EXACT_IMMORTAL_ALLOC) ||
                     traceState.EQ(TRACE_IMMORTAL_ALLOC)) {
            if (!OMIT_ALLOCS) {
              Log.write((traceState.EQ(TRACE_EXACT_IMMORTAL_ALLOC)) ? 'I' : 'i');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_ALLOC_SIZE;
          } else if (traceState.EQ(TRACE_BOOT_ALLOC)) {
            if (!OMIT_BOOTALLOCS) {
              Log.write('B');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_BOOT_ALLOC_SIZE;
          } else if (traceState.EQ(TRACE_DEATH)) {
            if (!OMIT_UNREACHABLES) {
              Log.write('D');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_DEATH_TIME;
          } else if (traceState.EQ(TRACE_BOOT_ALLOC_SIZE)) {
            if (!OMIT_BOOTALLOCS)
              Log.write(val);
            traceState = TRACE_NEW_RECORD;
          } else if (traceState.EQ(TRACE_ALLOC_SIZE)) {
            if (!OMIT_ALLOCS)
              Log.write(val);
            traceState = TRACE_ALLOC_FP;
          } else if (traceState.EQ(TRACE_ALLOC_FP)) {
            if (!OMIT_ALLOCS)
              Log.write(val);
            traceState = TRACE_ALLOC_THREAD;
          } else if (traceState.EQ(TRACE_ALLOC_THREAD)) {
            if (!OMIT_ALLOCS)
              Log.write(val);
            traceState = TRACE_NEW_RECORD;
          } else if (traceState.EQ(TRACE_TIB_SET)) {
            if (!OMIT_UPDATES) {
              Log.write('T');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_TIB_VALUE;
          } else if (traceState.EQ(TRACE_STATIC_SET)) {
            if (!OMIT_UPDATES) {
              Log.write('S');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_STATIC_TARGET;
          } else if (traceState.EQ(TRACE_TIB_VALUE) ||
                     traceState.EQ(TRACE_STATIC_TARGET)) {
            if (!OMIT_UPDATES)
              Log.write(val);
            traceState = TRACE_NEW_RECORD;
          } else if (traceState.EQ(TRACE_DEATH_TIME)) {
            if (!OMIT_UNREACHABLES)
              Log.write(val);
            traceState = TRACE_NEW_RECORD;
          } else if (traceState.EQ(TRACE_FIELD_SET) ||
                     traceState.EQ(TRACE_ARRAY_SET)) {
            if (!OMIT_UPDATES) {
              Log.write('U');
              Log.write(' ');
              Log.write(val);
              loggedRecord = true;
            }
            traceState = TRACE_FIELD_SLOT;
          } else if (traceState.EQ(TRACE_FIELD_TARGET) ||
                     traceState.EQ(TRACE_ARRAY_TARGET)) {
            if (!OMIT_UPDATES)
              Log.write(val);
            traceState = TRACE_NEW_RECORD;
          } else if (traceState.EQ(TRACE_FIELD_SLOT) ||
                     traceState.EQ(TRACE_ARRAY_ELEMENT)) {
            if (!OMIT_UPDATES)
              Log.write(val);
            traceState = TRACE_FIELD_TARGET;
          } else {
            VM.assertions.fail("Cannot understand directive!\n");
          }
          if (traceState.EQ(TRACE_NEW_RECORD) && loggedRecord) {
            entriesNotFlushed++;
            Log.writeln();
          } else if (loggedRecord) {
              Log.write(' ');
          }
        }
        if (entriesNotFlushed == 10) {
          if (!OMIT_OUTPUT)
            Log.flush();
          entriesNotFlushed = 0;
        }
      }
    }
    resetLocal();
  }
}
