FileDocCategorySizeDatePackage
HeapSegment.javaAPI DocAndroid 1.5 API14704Wed May 06 22:41:08 BST 2009com.android.ddmlib

HeapSegment

public final class HeapSegment extends Object implements Comparable
Describes the types and locations of objects in a segment of a heap.

Fields Summary
protected int
mHeapId
protected int
mAllocationUnitSize
protected long
mStartAddress
protected int
mOffset
protected int
mAllocationUnitCount
protected ByteBuffer
mUsageData
private static final long
INVALID_START_ADDRESS
Constructors Summary
public HeapSegment(ByteBuffer hpsgData)
Create a new HeapSegment based on the raw contents of an HPSG chunk.

param
hpsgData The raw data from an HPSG chunk.
throws
BufferUnderflowException if hpsgData is too small to hold the HPSG chunk header data.


                                                                              
         
        /* Read the HPSG chunk header.
         * These get*() calls may throw a BufferUnderflowException
         * if the underlying data isn't big enough.
         */
        hpsgData.order(ByteOrder.BIG_ENDIAN);
        mHeapId = hpsgData.getInt();
        mAllocationUnitSize = (int) hpsgData.get();
        mStartAddress = (long) hpsgData.getInt() & 0x00000000ffffffffL;
        mOffset = hpsgData.getInt();
        mAllocationUnitCount = hpsgData.getInt();

        // Hold onto the remainder of the data.
        mUsageData = hpsgData.slice();
        mUsageData.order(ByteOrder.BIG_ENDIAN);   // doesn't actually matter

        // Validate the data.
//xxx do it
//xxx make sure the number of elements matches mAllocationUnitCount.
//xxx make sure the last element doesn't have P set
    
Methods Summary
public booleanappend(com.android.ddmlib.HeapSegment other)
Append the contents of other to this segment if it describes the segment immediately after this one.

param
other The segment to append to this segment, if possible. If appended, other will be invalid when this method returns.
return
true if other was successfully appended to this segment.

        if (canAppend(other)) {
            /* Preserve the position.  The mark is not preserved,
             * but we don't use it anyway.
             */
            int pos = mUsageData.position();

            // Guarantee that we have enough room for the new data.
            if (mUsageData.capacity() - mUsageData.limit() <
                    other.mUsageData.limit()) {
                /* Grow more than necessary in case another append()
                 * is about to happen.
                 */
                int newSize = mUsageData.limit() + other.mUsageData.limit();
                ByteBuffer newData = ByteBuffer.allocate(newSize * 2);

                mUsageData.rewind();
                newData.put(mUsageData);
                mUsageData = newData;
            }

            // Copy the data from the other segment and restore the position.
            other.mUsageData.rewind();
            mUsageData.put(other.mUsageData);
            mUsageData.position(pos);

            // Fix this segment's header to cover the new data.
            mAllocationUnitCount += other.mAllocationUnitCount;

            // Mark the other segment as invalid.
            other.mStartAddress = INVALID_START_ADDRESS;
            other.mUsageData = null;

            return true;
        } else {
            return false;
        }
    
public booleancanAppend(com.android.ddmlib.HeapSegment other)
See if other comes immediately after this segment.

param
other The HeapSegment to check.
return
true if other comes immediately after this segment.

        return isValid() && other.isValid() && mHeapId == other.mHeapId &&
                mAllocationUnitSize == other.mAllocationUnitSize &&
                getEndAddress() == other.getStartAddress();
    
public intcompareTo(com.android.ddmlib.HeapSegment other)

        if (mHeapId != other.mHeapId) {
            return mHeapId < other.mHeapId ? -1 : 1;
        }
        if (getStartAddress() != other.getStartAddress()) {
            return getStartAddress() < other.getStartAddress() ? -1 : 1;
        }

        /* If two segments have the same start address, the rest of
         * the fields should be equal.  Go through the motions, though.
         * Note that we re-check the components of getStartAddress()
         * (mStartAddress and mOffset) to make sure that all fields in
         * an equal segment are equal.
         */

        if (mAllocationUnitSize != other.mAllocationUnitSize) {
            return mAllocationUnitSize < other.mAllocationUnitSize ? -1 : 1;
        }
        if (mStartAddress != other.mStartAddress) {
            return mStartAddress < other.mStartAddress ? -1 : 1;
        }
        if (mOffset != other.mOffset) {
            return mOffset < other.mOffset ? -1 : 1;
        }
        if (mAllocationUnitCount != other.mAllocationUnitCount) {
            return mAllocationUnitCount < other.mAllocationUnitCount ? -1 : 1;
        }
        if (mUsageData != other.mUsageData) {
            return mUsageData.compareTo(other.mUsageData);
        }
        return 0;
    
public booleanequals(java.lang.Object o)

        if (o instanceof HeapSegment) {
            return compareTo((HeapSegment) o) == 0;
        }
        return false;
    
public longgetEndAddress()

        return getStartAddress() + getLength();
    
public intgetLength()

        return mAllocationUnitSize * mAllocationUnitCount;
    
public com.android.ddmlib.HeapSegment$HeapSegmentElementgetNextElement(com.android.ddmlib.HeapSegment$HeapSegmentElement reuse)

        try {
            if (reuse != null) {
                return reuse.set(this);
            } else {
                return new HeapSegmentElement(this);
            }
        } catch (BufferUnderflowException ex) {
            /* Normal "end of buffer" situation.
             */
        } catch (ParseException ex) {
            /* Malformed data.
             */
//TODO: we should catch this in the constructor
        }
        return null;
    
public longgetStartAddress()

        return mStartAddress + mOffset;
    
public inthashCode()

        return mHeapId * 31 +
                mAllocationUnitSize * 31 +
                (int) mStartAddress * 31 +
                mOffset * 31 +
                mAllocationUnitCount * 31 +
                mUsageData.hashCode();
    
public booleanisValid()
See if this segment still contains data, and has not been appended to another segment.

return
true if this segment has not been appended to another segment.

        return mStartAddress != INVALID_START_ADDRESS;
    
public voidrewindElements()

        if (mUsageData != null) {
            mUsageData.rewind();
        }
    
public java.lang.StringtoString()

        StringBuilder str = new StringBuilder();

        str.append("HeapSegment { heap ").append(mHeapId)
                .append(", start 0x")
                .append(Integer.toHexString((int) getStartAddress()))
                .append(", length ").append(getLength())
                .append(" }");

        return str.toString();