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