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 private final ObjectReferenceDeque values;
035
036 /****************************************************************************
037 *
038 * Initialization
039 */
040
041 /**
042 * Constructor
043 *
044 * @param name The name of the underlying deque.
045 * @param queue The shared deque that is used.
046 */
047 public ObjectReferenceBuffer(String name, SharedDeque queue) {
048 values = new ObjectReferenceDeque(name, queue);
049 }
050
051 /**
052 * Trace an edge during GC.
053 *
054 * @param source The source of the reference.
055 * @param slot The location containing the object reference.
056 */
057 @Inline
058 public final void processEdge(ObjectReference source, Address slot) {
059 ObjectReference object = VM.activePlan.global().loadObjectReference(slot);
060 process(object);
061 }
062
063 /**
064 * This is the method that ensures
065 *
066 * @param object The object to process.
067 */
068 protected abstract void process(ObjectReference object);
069
070 /**
071 * Process each of the child objects for the passed object.
072 *
073 * @param object The object to process the children of.
074 */
075 @Inline
076 public final void processChildren(ObjectReference object) {
077 VM.scanning.scanObject(this, object);
078 }
079
080 /**
081 * Pushes an object onto the queue, forcing an inlined sequence.
082 *
083 * @param object The object to push.
084 */
085 @Inline
086 public final void push(ObjectReference object) {
087 values.push(object);
088 }
089
090 /**
091 * Pushes an object onto the queue, forcing an out of line sequence.
092 *
093 * @param object The object to push.
094 */
095 @Inline
096 public final void pushOOL(ObjectReference object) {
097 values.pushOOL(object);
098 }
099
100 /**
101 * Retrives an object.
102 *
103 * @return The object retrieved.
104 */
105 @Inline
106 public final ObjectReference pop() {
107 return values.pop();
108 }
109
110 @Inline
111 public final boolean isEmpty() {
112 return values.isEmpty();
113 }
114
115 /**
116 * Flushes all local state back to the shared queue.
117 */
118 public final void flushLocal() {
119 values.flushLocal();
120 }
121
122 /**
123 * Return true if this buffer is locally empty
124 */
125 public final boolean isFlushed() {
126 return values.isFlushed();
127 }
128 }