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.policy;
014
015 import org.mmtk.plan.TransitiveClosure;
016 import org.mmtk.utility.heap.FreeListPageResource;
017 import org.mmtk.utility.heap.VMRequest;
018 import org.mmtk.utility.DoublyLinkedList;
019
020 import org.mmtk.vm.VM;
021
022 import org.vmmagic.pragma.*;
023 import org.vmmagic.unboxed.*;
024
025 /**
026 * Each instance of this class corresponds to one explicitly managed
027 * large object space.
028 */
029 @Uninterruptible
030 public final class ExplicitLargeObjectSpace extends BaseLargeObjectSpace {
031
032 /****************************************************************************
033 *
034 * Instance variables
035 */
036 private final DoublyLinkedList cells;
037
038 /****************************************************************************
039 *
040 * Initialization
041 */
042
043 /**
044 * The caller specifies the region of virtual memory to be used for
045 * this space. If this region conflicts with an existing space,
046 * then the constructor will fail.
047 *
048 * @param name The name of this space (used when printing error messages etc)
049 * @param pageBudget The number of pages this space may consume
050 * before consulting the plan
051 * @param vmRequest An object describing the virtual memory requested.
052 */
053 public ExplicitLargeObjectSpace(String name, int pageBudget, VMRequest vmRequest) {
054 super(name, pageBudget, vmRequest);
055 cells = new DoublyLinkedList(LOG_BYTES_IN_PAGE, true);
056 }
057
058
059 /****************************************************************************
060 *
061 * Collection
062 */
063
064 /**
065 * Prepare for a new collection increment.
066 */
067 public void prepare() {
068 }
069
070 /**
071 * A new collection increment has completed.
072 */
073 public void release() {
074 }
075
076 /**
077 * Release a group of pages that were allocated together.
078 *
079 * @param first The first page in the group of pages that were
080 * allocated together.
081 */
082 @Inline
083 public void release(Address first) {
084 ((FreeListPageResource) pr).releasePages(first);
085 }
086
087 /**
088 * Perform any required initialization of the GC portion of the header.
089 *
090 * @param object the object ref to the storage to be initialized
091 * @param alloc is this initialization occuring due to (initial) allocation
092 * (true) or due to copying (false)?
093 */
094 @Inline
095 public void initializeHeader(ObjectReference object, boolean alloc) {
096 Address cell = VM.objectModel.objectStartRef(object);
097 cells.add(DoublyLinkedList.midPayloadToNode(cell));
098 }
099
100 /****************************************************************************
101 *
102 * Object processing and tracing
103 */
104
105 /**
106 * Trace a reference to an object under a mark sweep collection
107 * policy. If the object header is not already marked, mark the
108 * object in either the bitmap or by moving it off the treadmill,
109 * and enqueue the object for subsequent processing. The object is
110 * marked as (an atomic) side-effect of checking whether already
111 * marked.
112 *
113 * @param trace The trace being conducted.
114 * @param object The object to be traced.
115 * @return The object (there is no object forwarding in this
116 * collector, so we always return the same object: this could be a
117 * void method but for compliance to a more general interface).
118 */
119 @Inline
120 public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object) {
121 return object;
122 }
123
124 /**
125 * @param object The object in question
126 * @return True if this object is known to be live (i.e. it is marked)
127 */
128 @Inline
129 public boolean isLive(ObjectReference object) {
130 return true;
131 }
132
133 /**
134 * Return the size of the per-superpage header required by this
135 * system. In this case it is just the underlying superpage header
136 * size.
137 *
138 * @return The size of the per-superpage header required by this
139 * system.
140 */
141 @Inline
142 protected int superPageHeaderSize() {
143 return DoublyLinkedList.headerSize();
144 }
145
146 /**
147 * Return the size of the per-cell header for cells of a given class
148 * size.
149 *
150 * @return The size of the per-cell header for cells of a given class
151 * size.
152 */
153 @Inline
154 protected int cellHeaderSize() { return 0; }
155
156 /**
157 * Sweep through all the objects in this space.
158 *
159 * @param sweeper The sweeper callback to use.
160 */
161 @Inline
162 public void sweep(Sweeper sweeper) {
163 Address cell = cells.getHead();
164 while (!cell.isZero()) {
165 Address next = cells.getNext(cell);
166 ObjectReference obj = VM.objectModel.getObjectFromStartAddress(cell.plus(DoublyLinkedList.headerSize()));
167 if (sweeper.sweepLargeObject(obj)) {
168 free(obj);
169 }
170 cell = next;
171 }
172 }
173
174 /**
175 * Free an object
176 *
177 * @param object The object to be freed.
178 */
179 @Inline
180 public void free(ObjectReference object) {
181 Address cell = getSuperPage(VM.objectModel.refToAddress(object));
182 cells.remove(cell);
183 release(cell);
184 }
185
186 /**
187 * A callback used to perform sweeping of the large object space.
188 */
189 @Uninterruptible
190 public abstract static class Sweeper {
191 public abstract boolean sweepLargeObject(ObjectReference object);
192 }
193 }