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 */ 013package org.mmtk.utility.deque; 014 015import org.mmtk.plan.TransitiveClosure; 016import org.mmtk.vm.VM; 017 018import org.vmmagic.pragma.*; 019import org.vmmagic.unboxed.*; 020 021/** 022 * This class is a combination of a Deque and a TraceStep, designed to include 023 * intelligent processing of child references as objects are scanned. 024 * 025 * @see org.mmtk.plan.TransitiveClosure 026 */ 027@Uninterruptible 028public abstract class ObjectReferenceBuffer extends TransitiveClosure { 029 /**************************************************************************** 030 * 031 * Instance variables 032 */ 033 034 /** 035 * 036 */ 037 private final ObjectReferenceDeque values; 038 039 /**************************************************************************** 040 * 041 * Initialization 042 */ 043 044 /** 045 * Constructor 046 * 047 * @param name The name of the underlying deque. 048 * @param queue The shared deque that is used. 049 */ 050 public ObjectReferenceBuffer(String name, SharedDeque queue) { 051 values = new ObjectReferenceDeque(name, queue); 052 } 053 054 @Override 055 @Inline 056 public final void processEdge(ObjectReference source, Address slot) { 057 ObjectReference object = VM.activePlan.global().loadObjectReference(slot); 058 process(object); 059 } 060 061 /** 062 * This is the method that ensures 063 * 064 * @param object The object to process. 065 */ 066 protected abstract void process(ObjectReference object); 067 068 /** 069 * Process each of the child objects for the passed object. 070 * 071 * @param object The object to process the children of. 072 */ 073 @Inline 074 public final void processChildren(ObjectReference object) { 075 VM.scanning.scanObject(this, object); 076 } 077 078 /** 079 * Pushes an object onto the queue, forcing an inlined sequence. 080 * 081 * @param object The object to push. 082 */ 083 @Inline 084 public final void push(ObjectReference object) { 085 values.push(object); 086 } 087 088 /** 089 * Pushes an object onto the queue, forcing an out of line sequence. 090 * 091 * @param object The object to push. 092 */ 093 @Inline 094 public final void pushOOL(ObjectReference object) { 095 values.pushOOL(object); 096 } 097 098 /** 099 * Retrieves an object. 100 * 101 * @return The object retrieved. 102 */ 103 @Inline 104 public final ObjectReference pop() { 105 return values.pop(); 106 } 107 108 @Inline 109 public final boolean isEmpty() { 110 return values.isEmpty(); 111 } 112 113 /** 114 * Flushes all local state back to the shared queue. 115 */ 116 public final void flushLocal() { 117 values.flushLocal(); 118 } 119 120 /** 121 * @return {@code true} if this buffer is locally empty 122 */ 123 public final boolean isFlushed() { 124 return values.isFlushed(); 125 } 126}