/* * 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.Constants; import org.vmmagic.unboxed.*; import org.vmmagic.pragma.*; /** * Class that defines a doubly-linked double-ended queue (deque). The * double-linking increases the space demands slightly, but makes it far * more efficient to dequeue buffers and, for example, enables sorting of * its contents. */ @Uninterruptible class Deque implements Constants { /**************************************************************************** * * Protected instance methods * * protected int enqueued; */ @Inline protected final Offset bufferOffset(Address buf) { return buf.toWord().and(BUFFER_MASK).toOffset(); } @Inline protected final Address bufferStart(Address buf) { return buf.toWord().and(BUFFER_MASK.not()).toAddress(); } @Inline protected final Address bufferEnd(Address buf) { return bufferStart(buf).plus(USABLE_BUFFER_BYTES); } @Inline protected final Address bufferFirst(Address buf) { return bufferStart(buf); } @Inline protected final Address bufferLast(Address buf, int arity) { return bufferStart(buf).plus(bufferLastOffset(arity)); } @Inline protected final Address bufferLast(Address buf) { return bufferLast(buf, 1); } @Inline protected final Offset bufferLastOffset(int arity) { return Offset.fromIntZeroExtend(USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - (USABLE_BUFFER_BYTES % (arity << LOG_BYTES_IN_ADDRESS))); } /**************************************************************************** * * Private and protected static final fields (aka constants) */ protected static final int LOG_PAGES_PER_BUFFER = 0; protected static final int PAGES_PER_BUFFER = 1 << LOG_PAGES_PER_BUFFER; private static final int LOG_BUFFER_SIZE = (LOG_BYTES_IN_PAGE + LOG_PAGES_PER_BUFFER); protected static final int BUFFER_SIZE = 1 << LOG_BUFFER_SIZE; protected static final Word BUFFER_MASK = Word.one().lsh(LOG_BUFFER_SIZE).minus(Word.one()); protected static final int NEXT_FIELD_OFFSET = BYTES_IN_ADDRESS; protected static final int META_DATA_SIZE = 2 * BYTES_IN_ADDRESS; protected static final int USABLE_BUFFER_BYTES = BUFFER_SIZE - META_DATA_SIZE; protected static final Address TAIL_INITIAL_VALUE = Address.zero(); protected static final Address HEAD_INITIAL_VALUE = Address.zero(); }