1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 // BEGIN android-note 19 // address length was changed from long to int for performance reasons. 20 // END android-note 21 22 package org.apache.harmony.luni.platform; 23 24 import java.nio.ByteOrder; 25 26 /** 27 * The platform address class is an unsafe virtualization of an OS memory block. 28 */ 29 public class PlatformAddress implements Comparable { 30 public static final int SIZEOF_JBYTE = 1; 31 public static final int SIZEOF_JSHORT = 2; 32 public static final int SIZEOF_JINT = 4; 33 public static final int SIZEOF_JSIZE = 4; 34 public static final int SIZEOF_JFLOAT = 4; 35 public static final int SIZEOF_JLONG = 8; 36 public static final int SIZEOF_JDOUBLE = 8; 37 38 /** 39 * This final field defines the sentinel for an unknown address value. 40 */ 41 static final int UNKNOWN = -1; 42 43 /** 44 * NULL is the canonical address with address value zero. 45 */ 46 public static final PlatformAddress NULL = new PlatformAddress(0, 0); 47 48 /** 49 * INVALID is the canonical address with an invalid value 50 * (i.e. a non-address). 51 */ 52 public static final PlatformAddress INVALID = new PlatformAddress(UNKNOWN, UNKNOWN); 53 54 public static final RuntimeMemorySpy memorySpy = new RuntimeMemorySpy(); 55 56 final int osaddr; 57 58 final long size; 59 60 PlatformAddress(int address, long size) { 61 super(); 62 osaddr = address; 63 this.size = size; 64 } 65 66 /** 67 * Sending auto free to an address means that, when this subsystem has 68 * allocated the memory, it will automatically be freed when this object is 69 * collected by the garbage collector if the memory has not already been 70 * freed explicitly. 71 * 72 */ 73 public final void autoFree() { 74 memorySpy.autoFree(this); 75 } 76 77 public PlatformAddress duplicate() { 78 return PlatformAddressFactory.on(osaddr, size); 79 } 80 81 public PlatformAddress offsetBytes(int offset) { 82 return PlatformAddressFactory.on(osaddr + offset, size - offset); 83 } 84 85 public final void moveTo(PlatformAddress dst, long numBytes) { 86 OSMemory.memmove(dst.osaddr, osaddr, numBytes); 87 } 88 89 public final boolean equals(Object other) { 90 return (other instanceof PlatformAddress) 91 && (((PlatformAddress) other).osaddr == osaddr); 92 } 93 94 public final int hashCode() { 95 return (int) osaddr; 96 } 97 98 public final boolean isNULL() { 99 return this == NULL; 100 } 101 102 public void free() { 103 // Memory spys can veto the basic free if they determine the memory was 104 // not allocated. 105 if (memorySpy.free(this)) { 106 OSMemory.free(osaddr); 107 } 108 } 109 110 public final void setAddress(int offset, PlatformAddress address) { 111 OSMemory.setAddress(osaddr + offset, address.osaddr); 112 } 113 114 public final PlatformAddress getAddress(int offset) { 115 int addr = getInt(offset); 116 return PlatformAddressFactory.on(addr); 117 } 118 119 public final void setByte(int offset, byte value) { 120 memorySpy.rangeCheck(this, offset, SIZEOF_JBYTE); 121 OSMemory.setByte(osaddr + offset, value); 122 } 123 124 public final void setByteArray(int offset, byte[] bytes, int bytesOffset, 125 int length) { 126 memorySpy.rangeCheck(this, offset, length * SIZEOF_JBYTE); 127 OSMemory.setByteArray(osaddr + offset, bytes, bytesOffset, length); 128 } 129 130 // BEGIN android-added 131 public final void setShortArray(int offset, short[] shorts, 132 int shortsOffset, int length, boolean swap) { 133 memorySpy.rangeCheck(this, offset, length * SIZEOF_JSHORT); 134 OSMemory.setShortArray(osaddr + offset, shorts, shortsOffset, length, 135 swap); 136 } 137 138 public final void setIntArray(int offset, int[] ints, 139 int intsOffset, int length, boolean swap) { 140 memorySpy.rangeCheck(this, offset, length * SIZEOF_JINT); 141 OSMemory.setIntArray(osaddr + offset, ints, intsOffset, length, swap); 142 } 143 144 public final void setFloatArray(int offset, float[] floats, 145 int floatsOffset, int length, boolean swap) { 146 memorySpy.rangeCheck(this, offset, length * SIZEOF_JFLOAT); 147 OSMemory.setFloatArray( 148 osaddr + offset, floats, floatsOffset, length, swap); 149 } 150 // END android-added 151 152 public final byte getByte(int offset) { 153 memorySpy.rangeCheck(this, offset, SIZEOF_JBYTE); 154 return OSMemory.getByte(osaddr + offset); 155 } 156 157 public final void getByteArray(int offset, byte[] bytes, int bytesOffset, 158 int length) { 159 memorySpy.rangeCheck(this, offset, length * SIZEOF_JBYTE); 160 OSMemory.getByteArray(osaddr + offset, bytes, bytesOffset, length); 161 } 162 163 public final void setShort(int offset, short value, ByteOrder order) { 164 memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT); 165 OSMemory.setShort(osaddr + offset, value, order); 166 } 167 168 public final void setShort(int offset, short value) { 169 memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT); 170 OSMemory.setShort(osaddr + offset, value); 171 } 172 173 public final short getShort(int offset, ByteOrder order) { 174 memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT); 175 return OSMemory.getShort(osaddr + offset, order); 176 } 177 178 public final short getShort(int offset) { 179 memorySpy.rangeCheck(this, offset, SIZEOF_JSHORT); 180 return OSMemory.getShort(osaddr + offset); 181 } 182 183 public final void setInt(int offset, int value, ByteOrder order) { 184 memorySpy.rangeCheck(this, offset, SIZEOF_JINT); 185 OSMemory.setInt(osaddr + offset, value, order); 186 } 187 188 public final void setInt(int offset, int value) { 189 memorySpy.rangeCheck(this, offset, SIZEOF_JINT); 190 OSMemory.setInt(osaddr + offset, value); 191 } 192 193 public final int getInt(int offset, ByteOrder order) { 194 memorySpy.rangeCheck(this, offset, SIZEOF_JINT); 195 return OSMemory.getInt(osaddr + offset, order); 196 } 197 198 public final int getInt(int offset) { 199 memorySpy.rangeCheck(this, offset, SIZEOF_JINT); 200 return OSMemory.getInt(osaddr + offset); 201 } 202 203 public final void setLong(int offset, long value, ByteOrder order) { 204 memorySpy.rangeCheck(this, offset, SIZEOF_JLONG); 205 OSMemory.setLong(osaddr + offset, value, order); 206 } 207 208 public final void setLong(int offset, long value) { 209 memorySpy.rangeCheck(this, offset, SIZEOF_JLONG); 210 OSMemory.setLong(osaddr + offset, value); 211 } 212 213 public final long getLong(int offset, ByteOrder order) { 214 memorySpy.rangeCheck(this, offset, SIZEOF_JLONG); 215 return OSMemory.getLong(osaddr + offset, order); 216 } 217 218 public final long getLong(int offset) { 219 memorySpy.rangeCheck(this, offset, SIZEOF_JLONG); 220 return OSMemory.getLong(osaddr + offset); 221 } 222 223 public final void setFloat(int offset, float value, ByteOrder order) { 224 memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT); 225 OSMemory.setFloat(osaddr + offset, value, order); 226 } 227 228 public final void setFloat(int offset, float value) { 229 memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT); 230 OSMemory.setFloat(osaddr + offset, value); 231 } 232 233 public final float getFloat(int offset, ByteOrder order) { 234 memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT); 235 return OSMemory.getFloat(osaddr + offset, order); 236 } 237 238 public final float getFloat(int offset) { 239 memorySpy.rangeCheck(this, offset, SIZEOF_JFLOAT); 240 return OSMemory.getFloat(osaddr + offset); 241 } 242 243 public final void setDouble(int offset, double value, ByteOrder order) { 244 memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE); 245 OSMemory.setDouble(osaddr + offset, value, order); 246 } 247 248 public final void setDouble(int offset, double value) { 249 memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE); 250 OSMemory.setDouble(osaddr + offset, value); 251 } 252 253 public final double getDouble(int offset, ByteOrder order) { 254 memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE); 255 return OSMemory.getDouble(osaddr + offset, order); 256 } 257 258 public final double getDouble(int offset) { 259 memorySpy.rangeCheck(this, offset, SIZEOF_JDOUBLE); 260 return OSMemory.getDouble(osaddr + offset); 261 } 262 263 // BEGIN android-added 264 public final int toInt() { 265 return osaddr; 266 } 267 // END android-added 268 269 public final long toLong() { 270 return osaddr; 271 } 272 273 public final String toString() { 274 return "PlatformAddress[" + osaddr + "]"; 275 } 276 277 public final long getSize() { 278 return size; 279 } 280 281 public final int compareTo(Object other) { 282 if (other == null) { 283 throw new NullPointerException(); // per spec. 284 } 285 if (other instanceof PlatformAddress) { 286 int otherPA = ((PlatformAddress) other).osaddr; 287 if (osaddr == otherPA) { 288 return 0; 289 } 290 return osaddr < otherPA ? -1 : 1; 291 } 292 293 throw new ClassCastException(); // per spec. 294 } 295 } 296