001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.mmtk.utility.deque;
014
015 import org.mmtk.plan.TransitiveClosure;
016 import org.mmtk.utility.Constants;
017 import org.mmtk.vm.VM;
018
019 import org.vmmagic.pragma.*;
020 import org.vmmagic.unboxed.*;
021
022 /**
023 * This class is a combination of a Deque and a TraceStep, designed to include
024 * intelligent processing of child references as objects are scanned.
025 *
026 * @see org.mmtk.plan.TransitiveClosure
027 */
028 @Uninterruptible
029 public abstract class ObjectReferenceBuffer extends TransitiveClosure implements Constants {
030 /****************************************************************************
031 *
032 * Instance variables
033 */
034
035 /**
036 *
037 */
038 private final ObjectReferenceDeque values;
039
040 /****************************************************************************
041 *
042 * Initialization
043 */
044
045 /**
046 * Constructor
047 *
048 * @param name The name of the underlying deque.
049 * @param queue The shared deque that is used.
050 */
051 public ObjectReferenceBuffer(String name, SharedDeque queue) {
052 values = new ObjectReferenceDeque(name, queue);
053 }
054
055 @Override
056 @Inline
057 public final void processEdge(ObjectReference source, Address slot) {
058 ObjectReference object = VM.activePlan.global().loadObjectReference(slot);
059 process(object);
060 }
061
062 /**
063 * This is the method that ensures
064 *
065 * @param object The object to process.
066 */
067 protected abstract void process(ObjectReference object);
068
069 /**
070 * Process each of the child objects for the passed object.
071 *
072 * @param object The object to process the children of.
073 */
074 @Inline
075 public final void processChildren(ObjectReference object) {
076 VM.scanning.scanObject(this, object);
077 }
078
079 /**
080 * Pushes an object onto the queue, forcing an inlined sequence.
081 *
082 * @param object The object to push.
083 */
084 @Inline
085 public final void push(ObjectReference object) {
086 values.push(object);
087 }
088
089 /**
090 * Pushes an object onto the queue, forcing an out of line sequence.
091 *
092 * @param object The object to push.
093 */
094 @Inline
095 public final void pushOOL(ObjectReference object) {
096 values.pushOOL(object);
097 }
098
099 /**
100 * Retrieves an object.
101 *
102 * @return The object retrieved.
103 */
104 @Inline
105 public final ObjectReference pop() {
106 return values.pop();
107 }
108
109 @Inline
110 public final boolean isEmpty() {
111 return values.isEmpty();
112 }
113
114 /**
115 * Flushes all local state back to the shared queue.
116 */
117 public final void flushLocal() {
118 values.flushLocal();
119 }
120
121 /**
122 * Return {@code true} if this buffer is locally empty
123 */
124 public final boolean isFlushed() {
125 return values.isFlushed();
126 }
127 }