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 }