/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.max.tele.object;
import java.util.*;
import com.sun.max.tele.reference.*;
import com.sun.max.vm.heap.*;
/**
* The status of an object represented in VM memory, from a remote perspective that may not have complete information
* about an object. Moreover, in some cases, notably during GC, this remote perspective may have a slightly different
* view of the object's status at certain times than does the VM itself.
* <p>
* There are two distinguished states ({@link #LIVE} and {@link #DEAD}), based on the conventional notion of object
* reachability in the VM's heap. The other states are considered <em>Quasi</em> states; they describe regions of VM
* memory formatted as objects (or nearly so) that would be interesting and useful to view as objects, but which are not
* live objects from the perspective of the VM.
*
* <ul>
* <li> {@link #LIVE}: Determined to be reachable as of the most recent collection, or <em>presumed</em> to be reachable
* during certain GC phases when its reachability has not yet been determined.</li>
* <li> {@link #FORWARDER}: A <em>Quasi-object</em> that represents the old copy of an object that has been forwarded by
* a relocating collector. Its lifetime starts when the new copy is created and ends when the GC
* {@linkplain HeapPhase#ANALYZING analyzing} phase is complete.</li>
* <li> {@link UNREACHABLE}: A <em>Quasi-object</em> that represents a formerly {@linkplain #LIVE live} object during
* a GC {@linkplain HeapPhase#RECLAIMING reclaiming} phase, when that object has been determined by the immediately
* preceding {@linkplain HeapPhase#ANALYZING analyzing phase} to be unreachable.
* <li> {@link #FREE}: A <em>Quasi-object</em> that is formatted by the GC to explicitly span a segment of unallocated
* memory that is available for allocation.</li>
* <li> {@link #DARK}: A <em>Quasi-object</em> that is formatted by the GC to explicitly span a segment of unallocated
* memory that is <em>not</em> available for allocation.</li>
* <li> {@link #DEAD}: Unreachable memory, possibly at a site that formerly held a live or quasi-object but which no
* longer does; no assumptions about memory may be made</li>
* </ul>
* <p>
* {@linkplain RemoteReference Remote references} and thus {@linkplain TeleObject remote objects} can change states in
* response to both changes by memory managers in the VM and by discovery of additional information about the status of
* VM memory management.
*/
public enum ObjectStatus {
/**
* The region of memory is either in a live allocation area (representing an object
* that was determined to be reachable as of the most recent collection) or is in a region
* where GC is underway and for which reachability has not yet been determined.
*/
LIVE("Live", "Determined to be reachable as of the most recent collection"),
/**
* A region of memory that formerly held a live object, but which has been copied by a relocating collector.
* The lifetime of this status begins when the new copy is made, and a forwarding pointer inserted into
* the old copy and ends when the GC's current {@linkplain HeapPhase#ANALYZING} is complete.
*/
FORWARDER("Forwarder", "Old copy of a forwarded object, for the duration of the GC analyzing phase"),
/**
* A region of memory that formerly held a live object, but which is now known (to the inspector, at least, if not yet
* to the GC implementation) to be unreachable and has not yet been reclaimed.
*/
UNREACHABLE("Unreachable", "A formerly live object known to be unreachable but not reclaimed"),
/**
* A region of memory corresponding to an element of the GC's free space list. It is formatted as an
* object, even though it is never reachable as an object.
*/
FREE("Free Space", "A GC-formatted quasi- object that spans a chunk of memory available for allocation"),
/**
* A region of unallocated memory that the GC chooses not to make available for allocation and so is not
* on the GC's free space list. It is formatted as an object, even though it is never reachable as an object.
*/
DARK("Dark Matter", "A GC-formatted quasi- object that spans a chunk of unallocated memory that is not available for allocation"),
/**
* The region of memory formerly represented an object or quasi-object that has been released/collected.
*/
DEAD("Dead", "The region of memory formerly represented an object that has been collected");
private final String label;
private final String description;
private ObjectStatus(String label, String description) {
this.label = label;
this.description = description;
}
public String label() {
return label;
}
public String description() {
return description;
}
/**
* Does the memory represent an object that is currently assumed to be reachable?
*
* @return {@code this == } {@link #LIVE}
*/
public boolean isLive() {
return this == LIVE;
}
/**
* Has the object represented by the memory been determined to be unreachable?
*
* @return {@code this == } {@link #DEAD}
*/
public boolean isDead() {
return this == DEAD;
}
/**
* Does the memory represent interesting information, represented in VM object format, that is not a live object?
*
* @return {@code this != } {@link #LIVE} {@code && this != } {@link #DEAD}
*/
public boolean isQuasi() {
return this != LIVE && this != DEAD;
}
/**
* Does the memory represent either a {@link #LIVE} or <em>quasi-object</em> that can be usefully viewed as
* if it were an object.
*
* @return {@code this != } {@link #DEAD}
*/
public boolean isNotDead() {
return this != DEAD;
}
/**
* Does the memory hold a <em>quasi-object</em> representing the old copy of an object being forwarded during the current GC cycle?
*
* @return {@code this ==} {@link #FORWARDER}; can only be {@code true} while the GC is {@linkplain HeapPhase#ANALYZING analyzing}.
*/
public boolean isForwarder() {
return this == FORWARDER;
}
/**
* Does the memory hold a <em>quasi-object</em> representing an object that is known to be unreachable, but which has not been reclaimed.
*
* @return {@code this ==} {@link #UNREACHABLE}; can only be {@code true} when the GC is {@linkplain HeapPhase#RECLAIMING reclaiming}.
*/
public boolean isUnreachable() {
return this == UNREACHABLE;
}
/**
* Does the memory hold a <em>quasi-object</em> formatted by the GC to represent free memory available for allocation?
*
* @return {@code this ==} {@link #FREE}
*/
public boolean isFree() {
return this == FREE;
}
/**
* Does the memory hold a <em>quasi-object</em> formatted by the GC to represent free memory <em>not</em> available for allocation?
*
* @return {@code this ==} {@link #DARK}
*/
public boolean isDark() {
return this == DARK;
}
public static final List<ObjectStatus> VALUES = Arrays.asList(values());
}