Package org.jnode.vm

Source Code of org.jnode.vm.HeapHelperImpl$ThreadRootVisitor

/*
* $Id$
*
* Copyright (C) 2003-2014 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;

import org.jnode.annotation.MagicPermission;
import org.jnode.annotation.Uninterruptible;
import org.jnode.vm.classmgr.ObjectFlags;
import org.jnode.vm.classmgr.ObjectLayout;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.facade.ObjectVisitor;
import org.jnode.vm.facade.VmThread;
import org.jnode.vm.facade.VmThreadVisitor;
import org.jnode.vm.facade.VmUtils;
import org.jnode.vm.isolate.VmIsolate;
import org.jnode.vm.memmgr.HeapHelper;
import org.jnode.vm.memmgr.VmHeapManager;
import org.jnode.vm.scheduler.Monitor;
import org.jnode.vm.scheduler.MonitorManager;
import org.jnode.vm.scheduler.VmProcessor;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.Extent;
import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Word;

/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
@MagicPermission
@Uninterruptible
final class HeapHelperImpl extends HeapHelper {

    private static final class ThreadRootVisitor implements VmThreadVisitor {

        private VmHeapManager heapManager;

        private ObjectVisitor visitor;

        public final void initialize(ObjectVisitor visitor,
                                     VmHeapManager heapManager) {
            this.visitor = visitor;
            this.heapManager = heapManager;
        }

        public boolean visit(VmThread thread) {
            return thread.accept(visitor, heapManager);
        }
    }

    private final int flagsOffset;

    private final ThreadRootVisitor threadRootVisitor;

    /**
     * Initialize this instance.
     *
     * @param arch
     */
    public HeapHelperImpl(BaseVmArchitecture arch) {
        if (VmUtils.getVm() != null) {
            throw new SecurityException(
                "Cannot instantiate HeapHelpImpl at runtime");
        }
        final int refSize = arch.getReferenceSize();
        flagsOffset = ObjectLayout.FLAGS_SLOT * refSize;
        this.threadRootVisitor = new ThreadRootVisitor();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#allocateBlock(Extent)
     */
    public final Address allocateBlock(Extent size) {
        return MemoryBlockManager.allocateBlock(size);
    }

    /**
     * Change the color of the given object from oldColor to newColor.
     *
     * @param dst
     * @param oldColor
     * @param newColor
     * @return True if the color was changed, false if the current color of the
     *         object was not equal to oldColor.
     */
    public boolean atomicChangeObjectColor(Object dst, int oldColor,
                                           int newColor) {
        final Address addr = ObjectReference.fromObject(dst).toAddress().add(
            flagsOffset);
        for (;;) {
            Word oldValue = addr.prepareWord();
            if (oldValue
                .and(Word.fromIntZeroExtend(ObjectFlags.GC_COLOUR_MASK))
                .NE(Word.fromIntZeroExtend(oldColor))) {
                return false;
            }
            Word newValue = oldValue.and(
                Word.fromIntZeroExtend(ObjectFlags.GC_COLOUR_MASK).not())
                .or(Word.fromIntZeroExtend(newColor));
            if (addr.attempt(oldValue, newValue)) {
                return true;
            }
        }
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#clear(Address, Extent)
     */
    public final void clear(Address dst, Extent size) {
        Unsafe.clear(dst, size);
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#clear(Address, int)
     */
    public final void clear(Address dst, int size) {
        Unsafe.clear(dst, Extent.fromIntSignExtend(size));
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#copy(Address, Address, int)
     */
    public final void copy(Address src, Address dst, Extent size) {
        Unsafe.copy(src, dst, size);
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#die(java.lang.String)
     */
    public final void die(String msg) {
        try {
            VmProcessor.current().getArchitecture().getStackReader()
                .debugStackTrace();
        } finally {
            Unsafe.die(msg);
        }
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getBootHeapEnd()
     */
    public final Address getBootHeapEnd() {
        return Unsafe.getBootHeapEnd();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getBootHeapStart()
     */
    public final Address getBootHeapStart() {
        return Unsafe.getBootHeapStart();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getBootImageEnd()
     */
    public final Address getBootImageEnd() {
        return Unsafe.getBootHeapEnd();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getBootImageStart()
     */
    public final Address getBootImageStart() {
        return Unsafe.getKernelStart();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getHeapSize()
     */
    public Extent getHeapSize() {
        final Word end = Unsafe.getMemoryEnd().toWord();
        final Word start = Unsafe.getMemoryStart().toWord();
        return end.sub(start).toExtent();
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#getInflatedMonitor(java.lang.Object,
     *      org.jnode.vm.BaseVmArchitecture)
     */
    public final Monitor getInflatedMonitor(Object object, BaseVmArchitecture arch) {
        return MonitorManager.getInflatedMonitor(object);
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#invokeFinalizer(org.jnode.vm.classmgr.VmMethod,
     *      java.lang.Object)
     */
    public final void invokeFinalizer(VmMethod finalizer, Object object) {
        Unsafe.pushObject(object);
        Unsafe.invokeVoid(finalizer);
    }

    /**
     * Unblock all threads (on all processors). This method is called after a
     * call a call to {@link #stopThreadsAtSafePoint()}.
     */
    public void restartThreads() {
        VmMagic.currentProcessor().enableReschedule(true);
    }

    /**
     * Mark the given object as finalized.
     *
     * @param dst
     */
    public final void setFinalized(Object dst) {
        final Address addr = ObjectReference.fromObject(dst).toAddress().add(
            flagsOffset);
        int oldValue;
        int newValue;
        do {
            oldValue = addr.prepareInt();
            if ((oldValue & ObjectFlags.STATUS_FINALIZED) != 0) {
                return;
            }
            newValue = oldValue | ObjectFlags.STATUS_FINALIZED;
        } while (!addr.attempt(oldValue, newValue));
        // } while (!Unsafe.atomicCompareAndSwap(addr, oldValue, newValue));
    }

    /**
     * Stop and block all threads (on all processors) on a GC safe point. Only
     * the calling thread (the GC thread) will continue.
     */
    public final void stopThreadsAtSafePoint() {
        VmMagic.currentProcessor().disableReschedule(true);
    }

    /**
     * Visit all roots of the object tree.
     *
     * @param visitor
     */
    public void visitAllRoots(ObjectVisitor visitor, VmHeapManager heapManager) {
        final org.jnode.vm.facade.Vm vm = VmUtils.getVm();
        if (!vm.getSharedStatics().walk(visitor)) {
            return;
        }
        if (!VmProcessor.current().getIsolatedStatics().walk(visitor)) {
            return;
        }
        if (!VmIsolate.walkIsolates(visitor)) {
            return;
        }
        threadRootVisitor.initialize(visitor, heapManager);
        VmMagic.currentProcessor().getScheduler().visitAllThreads(threadRootVisitor);
    }

    /**
     * @see org.jnode.vm.memmgr.HeapHelper#bootArchitecture(boolean)
     */
    public final void bootArchitecture(boolean emptyMMap) {
        ((BaseVmArchitecture) VmUtils.getVm().getArch()).boot(emptyMMap);
    }
}
TOP

Related Classes of org.jnode.vm.HeapHelperImpl$ThreadRootVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.