/*
* Copyright (c) 2010, 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;
import java.lang.management.*;
import java.util.*;
import com.sun.max.unsafe.*;
/**
* Description of an extent of memory in the VM.
* <p>
* A described region may not yet be <em>allocated</em>, in which
* case it starts at {@linkplain Address#zero() address zero} and
* has zero length.
* <p>
* An <em>allocated</em> region has non-zero length and <em>may not</em>
* start at {@linkplain Address#zero() address zero}.
*/
public interface MaxMemoryRegion {
/**
* @return the VM
*/
MaxVM vm();
/**
* @return a short human-readable name for this memory region
* that helps explain the role it plays; suitable for appearance
* in a table cell or as the name of a menu item.
*/
String regionName();
/**
* @return memory address of the first location in the region.
*/
Address start();
/**
* @return number of bytes in the region.
*/
long nBytes();
/**
* @return address just past the last location in the region.
*/
Address end();
/**
* @return whether this region describes a legitimately allocated
* span of memory: positive length and not starting at zero.
*/
boolean isAllocated();
/**
* @return a description of the memory usage for this region,
* NULL_USAGE if not allocated or no information available.
*/
MemoryUsage getUsage();
/**
* @return does the region contain the address.
*/
boolean contains(Address address);
/**
* @return the next location to be allocated in the region; {@code null} if not linearly allocated.
*/
Address mark();
/**
* Checks whether a VM memory address is within the allocated
* area of a VM memory region. If the VM memory region has no
* notion of internal allocation, or if internal allocation cannot
* reasonably be determined, then this is equivalent to {@link #contains(Address)}.
*
* @param address a VM memory location
* @return whether the location is within the allocated part of this VM
* memory region.
*/
boolean containsInAllocated(Address address);
/**
* @return does the region have any locations in common with another region.
*/
boolean overlaps(MaxMemoryRegion memoryRegion);
/**
* @return does the region have the same bounds as another region.
* @see Util#equal(MaxMemoryRegion, MaxMemoryRegion)
*/
boolean sameAs(MaxMemoryRegion memoryRegion);
public static final class Util {
public static MemoryUsage NULL_MEMORY_USAGE = new MemoryUsage(-1L, 0L, 0L, -1L);
private static final Comparator<MaxMemoryRegion> START_COMPARATOR = new Comparator<MaxMemoryRegion>() {
public int compare(MaxMemoryRegion mr1, MaxMemoryRegion mr2) {
return mr1.start().compareTo(mr2.start());
}
};
/**
* @return a comparator that operates on the start location of two non-null memory regions
*/
public static Comparator<MaxMemoryRegion> startComparator() {
return START_COMPARATOR;
}
private static final Comparator<MaxMemoryRegion> NAME_COMPARATOR = new Comparator<MaxMemoryRegion>() {
public int compare(MaxMemoryRegion mr1, MaxMemoryRegion mr2) {
return mr1.regionName().compareTo(mr2.regionName());
}
};
/**
* @return a comparator that operates on the start location of two non-null memory regions
*/
public static Comparator<MaxMemoryRegion> nameComparator() {
return NAME_COMPARATOR;
}
/**
* @return whether the VM memory region describes a legitimate allocation
*/
public static boolean isAllocated(MaxMemoryRegion memoryRegion) {
return memoryRegion.start().isNotZero() && memoryRegion.nBytes() > 0;
}
/**
* @return whether the VM memory region contains a specific address
*/
public static boolean contains(MaxMemoryRegion memoryRegion, Address address) {
return address.greaterEqual(memoryRegion.start()) && address.lessThan(memoryRegion.end());
}
/**
* @return whether two VM memory regions contain any location in common
*/
public static boolean overlaps(MaxMemoryRegion left, MaxMemoryRegion right) {
return left.start().lessThan(right.end()) && right.start().lessThan(left.end());
}
/**
* @return whether two descriptions describe the exact same region of VM memory
*/
public static boolean equal(MaxMemoryRegion left, MaxMemoryRegion right) {
if (left == null) {
return right == null;
}
if (right == null) {
return false;
}
return left.start().equals(right.start()) && left.nBytes() == right.nBytes();
}
/**
* Gets a default description of usage information for a fixed size region,
* is presumed to be fully utilized, and for which {@link MemoryUsage#getInit()} and
* {@link MemoryUsage#getMax()} are "undefined".
*
* @param nBytes the number of bytes in the region
* @return a default usage descriptor of a fully utilized region of the specified size.
*/
public static MemoryUsage defaultUsage(long nBytes) {
return nBytes == 0L ? NULL_MEMORY_USAGE : new MemoryUsage(-1L, nBytes, nBytes, -1L);
}
/**
* Gets a default description of usage information for the region, in which the region
* is presumed to be fully utilized, and for which {@link MemoryUsage#getInit()} and
* {@link MemoryUsage#getMax()} are "undefined".
*
* @param memoryRegion a region of VM memory
* @return a default usage descriptor indicating full utilization fo the region
*/
public static MemoryUsage defaultUsage(MaxMemoryRegion memoryRegion) {
return defaultUsage(memoryRegion.nBytes());
}
/**
* Gets a string representation for a memory region composed of its {@linkplain MaxMemoryRegion#regionName() description}
* and {@linkplain MaxMemoryRegion#start()} - {@linkplain MaxMemoryRegion#end()} address range.
*/
public static String asString(MaxMemoryRegion memoryRegion) {
if (memoryRegion == null) {
return "null";
}
final StringBuilder sb = new StringBuilder();
if (memoryRegion.regionName() != null) {
sb.append(memoryRegion.regionName()).append(":");
}
sb.append("[").append(memoryRegion.start().toHexString()).append(" - ").append(memoryRegion.end().minus(1).toHexString()).append("]");
return sb.toString();
}
}
}