/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.vm.memmgr.def; import org.jnode.vm.VmMagic; import org.jnode.annotation.MagicPermission; import org.jnode.vm.classmgr.ObjectFlags; import org.jnode.vm.facade.VmWriteBarrier; import org.jnode.vm.memmgr.HeapHelper; import org.jnode.vm.objects.VmSystemObject; import org.vmmagic.pragma.UninterruptiblePragma; /** * @author Ewout Prangsma (epr@users.sourceforge.net) */ @MagicPermission final class DefaultWriteBarrier extends VmSystemObject implements VmWriteBarrier { /** * The heap helper */ private final HeapHelper helper; /** * Is the write barrier active? */ private boolean active; /** * Are there any object colors changed by the write barrier, since the last * reset */ private boolean changed; private int arrayCopyCount; private int arrayStoreCount; private int putFieldCount; private int putStaticCount; /** * Initialize this instance. */ public DefaultWriteBarrier(HeapHelper helper) { this.helper = helper; } /** * @see org.jnode.vm.facade.VmWriteBarrier#arrayCopyWriteBarrier(java.lang.Object[], * int, int) */ public final void arrayCopyWriteBarrier(Object array, int start, int end) throws UninterruptiblePragma { // The source array is already reachable, so by definition, all // entries will be reachable. // So we do nothing here arrayCopyCount++; } /** * @see org.jnode.vm.facade.VmWriteBarrier#arrayStoreWriteBarrier(java.lang.Object, * int, java.lang.Object) */ public final void arrayStoreWriteBarrier(Object ref, int index, Object value) throws UninterruptiblePragma { if (active) { shade(value); } arrayStoreCount++; } /** * @see org.jnode.vm.facade.VmWriteBarrier#putfieldWriteBarrier(java.lang.Object, * int, java.lang.Object) */ public final void putfieldWriteBarrier(Object ref, int offset, Object value) throws UninterruptiblePragma { if (active) { shade(value); } putFieldCount++; } /** * @see org.jnode.vm.facade.VmWriteBarrier#putstaticWriteBarrier(boolean, int, * java.lang.Object) */ public final void putstaticWriteBarrier(boolean shared, int staticsIndex, Object value) throws UninterruptiblePragma { if (active) { shade(value); } putStaticCount++; } /** * Set the GC color of the given value to gray if it is white. * * @param value */ private final void shade(Object value) throws UninterruptiblePragma { if (value != null) { while (true) { final int gcColor = VmMagic.getObjectColor(value); if (gcColor > ObjectFlags.GC_WHITE) { // Not white or yellow, we're done return; } if (helper.atomicChangeObjectColor(value, gcColor, ObjectFlags.GC_GREY)) { // Change to grey, we're done changed = true; return; } } } } public String toString() { return "arrayCopy: " + arrayCopyCount + ", arrayStore: " + arrayStoreCount + ", putField: " + putFieldCount + ", putStatic: " + putStaticCount; } /** * @param active The active to set. */ final void setActive(boolean active) { this.changed = false; this.active = active; } /** * @return Returns the changed. */ final boolean isChanged() { return this.changed; } /** * Reset the changed attribute to false. */ final void resetChanged() { this.changed = false; } }