Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/Page.java
41161 views
/*1* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.debugger;2526/** A class representing an arbitrary-sized page which can be linked27into a list. Used by the PageCache. */2829public class Page {30private long baseAddress;31private byte[] data;32private Page prev;33private Page next;34private long unmappedPageLength;3536/** The length of the data[] array implicitly defines the size of the37page. */38public Page(long baseAddress, byte[] data) {39this.baseAddress = baseAddress;40this.data = data;41}4243/** This constructor creates an "unmapped" page of the specified44length. Fetches from this page will cause -1 to be inserted into45the destination buffer. */46public Page(long baseAddress, long unmappedPageLength) {47this.baseAddress = baseAddress;48this.unmappedPageLength = unmappedPageLength;49}5051public long getBaseAddress() {52return baseAddress;53}5455public long getSize() {56if (data != null) {57return data.length;58} else {59return unmappedPageLength;60}61}6263/** Indicates whether this page is mapped in the remote process's64address space */65public boolean isMapped() {66return (data != null);67}6869public Page getPrev() {70return prev;71}7273public void setPrev(Page prev) {74this.prev = prev;75}7677public Page getNext() {78return next;79}8081public void setNext(Page next) {82this.next = next;83}8485/** Throws IndexOutOfBoundsException if the number of bytes86requested is greater than the page size, or if the start address87doesn't fall within the page. There are no guarantees on whether88any data was actually fetched if an IndexOutOfBoundsException is89thrown. If this page is unmapped, -1 is returned for all90addresses on this page. */91public void getData(long startAddress, long numBytes,92int[] destBuf, long destBufOffset)93throws IndexOutOfBoundsException {94int startOffset = (int) (startAddress - baseAddress);95if ((data == null) &&96((startOffset < 0) || ((startOffset + numBytes) > (baseAddress + unmappedPageLength)))) {97throw new IndexOutOfBoundsException("startAddress = " + startAddress +98", baseAddress = " + baseAddress +99", unmappedPageLength = " + unmappedPageLength);100}101for (int i = 0; i < (int) numBytes; ++i) {102if (data != null) {103destBuf[i + (int) destBufOffset] = ((int) (data[i + startOffset]) & 0x000000FF);104} else {105destBuf[i + (int) destBufOffset] = -1;106}107}108}109110/** Throws IndexOutOfBoundsException if the number of bytes111requested is greater than the page size, or if the start address112doesn't fall within the page. There are no guarantees on whether113any data was actually fetched if an IndexOutOfBoundsException is114thrown. If this page is unmapped, throws a RuntimeException;115this should be watched for at higher levels. */116public void getDataAsBytes(long startAddress, long numBytes,117byte[] destBuf, long destBufOffset)118throws IndexOutOfBoundsException {119long startOffset = startAddress - baseAddress;120if (data == null) {121throw new RuntimeException("Bug in PageCache; should not fetch from unmapped pages using getDataAsBytes");122}123System.arraycopy(data, (int) startOffset, destBuf, (int) destBufOffset, (int) numBytes);124}125126public boolean getBoolean(long address) {127return (getByte(address) != 0);128}129130public byte getByte(long address) {131return data[(int) address - (int) baseAddress];132}133134public short getShort(long address, boolean bigEndian) {135int start = (int) address - (int) baseAddress;136if (bigEndian) {137return (short)138(((data[start + 1] & 0xFF)) |139((data[start] & 0xFF) << 8));140} else {141return (short)142(((data[start + 1] & 0xFF) << 8) |143((data[start] & 0xFF)));144}145}146147public char getChar(long address, boolean bigEndian) {148return (char) getShort(address, bigEndian);149}150151public int getInt(long address, boolean bigEndian) {152int start = (int) address - (int) baseAddress;153if (bigEndian) {154return155((data[start + 3] & 0xFF)) |156((data[start + 2] & 0xFF) << 8) |157((data[start + 1] & 0xFF) << 16) |158((data[start] & 0xFF) << 24);159} else {160return161((data[start + 3] & 0xFF) << 24) |162((data[start + 2] & 0xFF) << 16) |163((data[start + 1] & 0xFF) << 8) |164((data[start] & 0xFF));165}166}167168public long getLong(long address, boolean bigEndian) {169int start = (int) address - (int) baseAddress;170if (bigEndian) {171return172((data[start + 7] & 0xFFL)) |173((data[start + 6] & 0xFFL) << 8) |174((data[start + 5] & 0xFFL) << 16) |175((data[start + 4] & 0xFFL) << 24) |176((data[start + 3] & 0xFFL) << 32) |177((data[start + 2] & 0xFFL) << 40) |178((data[start + 1] & 0xFFL) << 48) |179((data[start] & 0xFFL) << 56);180} else {181return182((data[start + 7] & 0xFFL) << 56) |183((data[start + 6] & 0xFFL) << 48) |184((data[start + 5] & 0xFFL) << 40) |185((data[start + 4] & 0xFFL) << 32) |186((data[start + 3] & 0xFFL) << 24) |187((data[start + 2] & 0xFFL) << 16) |188((data[start + 1] & 0xFFL) << 8) |189((data[start] & 0xFFL));190}191}192193public float getFloat(long address, boolean bigEndian) {194return Float.intBitsToFloat(getInt(address, bigEndian));195}196197public double getDouble(long address, boolean bigEndian) {198return Double.longBitsToDouble(getLong(address, bigEndian));199}200}201202203