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