1
/*
2
 * $Id$
3
 *
4
 * Copyright (C) 2003-2009 JNode.org
5
 *
6
 * This library is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful, but 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
14
 * License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this library; If not, write to the Free Software Foundation, Inc., 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
 */
20
21
package org.jnode.vm.memmgr.generational;
22
23
import org.jnode.annotation.MagicPermission;
24
import org.jnode.vm.ObjectVisitor;
25
import org.jnode.vm.VmMagic;
26
import org.jnode.vm.classmgr.ObjectLayout;
27
import org.jnode.vm.memmgr.HeapHelper;
28
import org.vmmagic.unboxed.Address;
29
import org.vmmagic.unboxed.Extent;
30
import org.vmmagic.unboxed.Offset;
31
import org.vmmagic.unboxed.Word;
32
33
/**
34
 * @author epr
35
 */
36
@MagicPermission
37
public final class VmBootHeap extends VmAbstractHeap {
38
39
    // public static final String START_FIELD_NAME = "start";
40
    // public static final String END_FIELD_NAME = "end";
41
    /**
42
     * Offset (in bytes) from the start of an object to the size of an object
43
     */
44
    private Offset sizeOffset;
45
46
    /**
47
     * Initialize this instance
48
     * 
49
     * @param helper
50
     */
51
    public VmBootHeap(HeapHelper helper) {
52
        super(helper);
53
    }
54
55
    /**
56
     * @param start
57
     * @param end
58
     * @param slotSize
59
     * @see VmAbstractHeap#initialize(Address, Address, int) For this class, the
60
     *      parameters are always null, so ignore them!
61
     */
62
    public void initialize(Address start, Address end, int slotSize) {
63
        // Unsafe.debug("bootheap.initialize");
64
        // Unsafe.debug("start"); Unsafe.debug(Unsafe.addressToInt(start));
65
        // Unsafe.debug("end"); Unsafe.debug(Unsafe.addressToInt(end));
66
67
        this.start = start;
68
        this.end = end;
69
        initializeAbstract(slotSize);
70
        this.sizeOffset = Offset.fromIntSignExtend(-((ObjectLayout.HEADER_SLOTS + 1) * slotSize));
71
        this.headerSize = ObjectLayout.objectAlign(this.headerSize + slotSize);
72
73
        // Create an allocation bitmap
74
        final int heapSize = getSize();
75
        final int bits = ObjectLayout.objectAlign(heapSize) / ObjectLayout.OBJECT_ALIGN;
76
        final int bitmapSize = ObjectLayout.objectAlign(bits / 8);
77
        allocationBitmapPtr = helper.allocateBlock(Extent.fromIntZeroExtend(bitmapSize));
78
        // allocationBitmapPtr = MemoryBlockManager.allocateBlock(bitmapSize);
79
80
        // Initialize the allocation bitmap
81
        helper.clear(allocationBitmapPtr, bitmapSize);
82
        // Go through the heap and mark all objects in the allocation bitmap.
83
        final Word heapSizeW = Word.fromIntZeroExtend(heapSize);
84
        final Word headerSize = Word.fromIntZeroExtend(this.headerSize);
85
        Word offset = headerSize;
86
        while (offset.LT(heapSizeW)) {
87
            final Address ptr = start.add(offset);
88
            setAllocationBit(ptr, true);
89
            final Word objSize = ptr.loadWord(sizeOffset);
90
            offset = offset.add(objSize).add(headerSize);
91
        }
92
        // Unsafe.debug("end of bootheap.initialize");
93
    }
94
95
    /**
96
     * Let all objects in this heap make a visit to the given visitor.
97
     * 
98
     * @param visitor
99
     * @param locking
100
     *            If true, use lock/unlock while proceeding to the next object.
101
     *            This parameter is irrelevant here, since the structure of this
102
     *            heap never changes.
103
     */
104
    protected void walk(ObjectVisitor visitor, boolean locking, Word flagsMask, Word flagsValue) {
105
        // Go through the heap and mark all objects in the allocation bitmap.
106
        final Word headerSize = Word.fromIntZeroExtend(this.headerSize);
107
        final Offset sizeOffset = this.sizeOffset;
108
        final Word size = Word.fromIntZeroExtend(getSize());
109
        Word offset = headerSize;
110
        while (offset.LT(size)) {
111
            final Address ptr = start.add(offset);
112
            final Object object = ptr.toObjectReference().toObject();
113
            final Word flags = VmMagic.getObjectFlags(object).and(flagsMask);
114
            if (!flags.EQ(flagsValue) || visitor.visit(object)) {
115
                // Continue
116
                final Word objSize = ptr.loadWord(sizeOffset);
117
                offset = offset.add(objSize).add(headerSize);
118
            } else {
119
                // Stop
120
                offset = size;
121
            }
122
        }
123
    }
124
}