1 /* 2 * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 */ 28 29 package sun.nio.ch; // Formerly in sun.misc 30 31 import java.nio.ByteOrder; 32 import sun.misc.Unsafe; 33 34 35 // ## In the fullness of time, this class will be eliminated 36 37 /** 38 * Proxies for objects that reside in native memory. 39 */ 40 41 class NativeObject { // package-private 42 43 protected static final Unsafe unsafe = Unsafe.getUnsafe(); 44 45 // Native allocation address; 46 // may be smaller than the base address due to page-size rounding 47 // 48 protected long allocationAddress; 49 50 // Native base address 51 // 52 private final long address; 53 54 /** 55 * Creates a new native object that is based at the given native address. 56 */ NativeObject(long address)57 NativeObject(long address) { 58 this.allocationAddress = address; 59 this.address = address; 60 } 61 62 /** 63 * Creates a new native object allocated at the given native address but 64 * whose base is at the additional offset. 65 */ NativeObject(long address, long offset)66 NativeObject(long address, long offset) { 67 this.allocationAddress = address; 68 this.address = address + offset; 69 } 70 71 // Invoked only by AllocatedNativeObject 72 // NativeObject(int size, boolean pageAligned)73 protected NativeObject(int size, boolean pageAligned) { 74 if (!pageAligned) { 75 this.allocationAddress = unsafe.allocateMemory(size); 76 this.address = this.allocationAddress; 77 } else { 78 int ps = pageSize(); 79 long a = unsafe.allocateMemory(size + ps); 80 this.allocationAddress = a; 81 this.address = a + ps - (a & (ps - 1)); 82 } 83 } 84 85 /** 86 * Returns the native base address of this native object. 87 * 88 * @return The native base address 89 */ address()90 long address() { 91 return address; 92 } 93 allocationAddress()94 long allocationAddress() { 95 return allocationAddress; 96 } 97 98 /** 99 * Creates a new native object starting at the given offset from the base 100 * of this native object. 101 * 102 * @param offset 103 * The offset from the base of this native object that is to be 104 * the base of the new native object 105 * 106 * @return The newly created native object 107 */ subObject(int offset)108 NativeObject subObject(int offset) { 109 return new NativeObject(offset + address); 110 } 111 112 /** 113 * Reads an address from this native object at the given offset and 114 * constructs a native object using that address. 115 * 116 * @param offset 117 * The offset of the address to be read. Note that the size of an 118 * address is implementation-dependent. 119 * 120 * @return The native object created using the address read from the 121 * given offset 122 */ getObject(int offset)123 NativeObject getObject(int offset) { 124 long newAddress = 0L; 125 switch (addressSize()) { 126 case 8: 127 newAddress = unsafe.getLong(offset + address); 128 break; 129 case 4: 130 newAddress = unsafe.getInt(offset + address) & 0x00000000FFFFFFFF; 131 break; 132 default: 133 throw new InternalError("Address size not supported"); 134 } 135 136 return new NativeObject(newAddress); 137 } 138 139 /** 140 * Writes the base address of the given native object at the given offset 141 * of this native object. 142 * 143 * @param offset 144 * The offset at which the address is to be written. Note that the 145 * size of an address is implementation-dependent. 146 * 147 * @param ob 148 * The native object whose address is to be written 149 */ putObject(int offset, NativeObject ob)150 void putObject(int offset, NativeObject ob) { 151 switch (addressSize()) { 152 case 8: 153 putLong(offset, ob.address); 154 break; 155 case 4: 156 putInt(offset, (int)(ob.address & 0x00000000FFFFFFFF)); 157 break; 158 default: 159 throw new InternalError("Address size not supported"); 160 } 161 } 162 163 164 /* -- Value accessors: No range checking! -- */ 165 166 /** 167 * Reads a byte starting at the given offset from base of this native 168 * object. 169 * 170 * @param offset 171 * The offset at which to read the byte 172 * 173 * @return The byte value read 174 */ getByte(int offset)175 final byte getByte(int offset) { 176 return unsafe.getByte(offset + address); 177 } 178 179 /** 180 * Writes a byte at the specified offset from this native object's 181 * base address. 182 * 183 * @param offset 184 * The offset at which to write the byte 185 * 186 * @param value 187 * The byte value to be written 188 */ putByte(int offset, byte value)189 final void putByte(int offset, byte value) { 190 unsafe.putByte(offset + address, value); 191 } 192 193 /** 194 * Reads a short starting at the given offset from base of this native 195 * object. 196 * 197 * @param offset 198 * The offset at which to read the short 199 * 200 * @return The short value read 201 */ getShort(int offset)202 final short getShort(int offset) { 203 return unsafe.getShort(offset + address); 204 } 205 206 /** 207 * Writes a short at the specified offset from this native object's 208 * base address. 209 * 210 * @param offset 211 * The offset at which to write the short 212 * 213 * @param value 214 * The short value to be written 215 */ putShort(int offset, short value)216 final void putShort(int offset, short value) { 217 unsafe.putShort(offset + address, value); 218 } 219 220 /** 221 * Reads a char starting at the given offset from base of this native 222 * object. 223 * 224 * @param offset 225 * The offset at which to read the char 226 * 227 * @return The char value read 228 */ getChar(int offset)229 final char getChar(int offset) { 230 return unsafe.getChar(offset + address); 231 } 232 233 /** 234 * Writes a char at the specified offset from this native object's 235 * base address. 236 * 237 * @param offset 238 * The offset at which to write the char 239 * 240 * @param value 241 * The char value to be written 242 */ putChar(int offset, char value)243 final void putChar(int offset, char value) { 244 unsafe.putChar(offset + address, value); 245 } 246 247 /** 248 * Reads an int starting at the given offset from base of this native 249 * object. 250 * 251 * @param offset 252 * The offset at which to read the int 253 * 254 * @return The int value read 255 */ getInt(int offset)256 final int getInt(int offset) { 257 return unsafe.getInt(offset + address); 258 } 259 260 /** 261 * Writes an int at the specified offset from this native object's 262 * base address. 263 * 264 * @param offset 265 * The offset at which to write the int 266 * 267 * @param value 268 * The int value to be written 269 */ putInt(int offset, int value)270 final void putInt(int offset, int value) { 271 unsafe.putInt(offset + address, value); 272 } 273 274 /** 275 * Reads a long starting at the given offset from base of this native 276 * object. 277 * 278 * @param offset 279 * The offset at which to read the long 280 * 281 * @return The long value read 282 */ getLong(int offset)283 final long getLong(int offset) { 284 return unsafe.getLong(offset + address); 285 } 286 287 /** 288 * Writes a long at the specified offset from this native object's 289 * base address. 290 * 291 * @param offset 292 * The offset at which to write the long 293 * 294 * @param value 295 * The long value to be written 296 */ putLong(int offset, long value)297 final void putLong(int offset, long value) { 298 unsafe.putLong(offset + address, value); 299 } 300 301 /** 302 * Reads a float starting at the given offset from base of this native 303 * object. 304 * 305 * @param offset 306 * The offset at which to read the float 307 * 308 * @return The float value read 309 */ getFloat(int offset)310 final float getFloat(int offset) { 311 return unsafe.getFloat(offset + address); 312 } 313 314 /** 315 * Writes a float at the specified offset from this native object's 316 * base address. 317 * 318 * @param offset 319 * The offset at which to write the float 320 * 321 * @param value 322 * The float value to be written 323 */ putFloat(int offset, float value)324 final void putFloat(int offset, float value) { 325 unsafe.putFloat(offset + address, value); 326 } 327 328 /** 329 * Reads a double starting at the given offset from base of this native 330 * object. 331 * 332 * @param offset 333 * The offset at which to read the double 334 * 335 * @return The double value read 336 */ getDouble(int offset)337 final double getDouble(int offset) { 338 return unsafe.getDouble(offset + address); 339 } 340 341 /** 342 * Writes a double at the specified offset from this native object's 343 * base address. 344 * 345 * @param offset 346 * The offset at which to write the double 347 * 348 * @param value 349 * The double value to be written 350 */ putDouble(int offset, double value)351 final void putDouble(int offset, double value) { 352 unsafe.putDouble(offset + address, value); 353 } 354 355 /** 356 * Returns the native architecture's address size in bytes. 357 * 358 * @return The address size of the native architecture 359 */ addressSize()360 static int addressSize() { 361 return unsafe.addressSize(); 362 } 363 364 // Cache for byte order 365 private static ByteOrder byteOrder = null; 366 367 /** 368 * Returns the byte order of the underlying hardware. 369 * 370 * @return An instance of {@link java.nio.ByteOrder} 371 */ byteOrder()372 static ByteOrder byteOrder() { 373 if (byteOrder != null) 374 return byteOrder; 375 long a = unsafe.allocateMemory(8); 376 try { 377 unsafe.putLong(a, 0x0102030405060708L); 378 byte b = unsafe.getByte(a); 379 switch (b) { 380 case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break; 381 case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break; 382 default: 383 assert false; 384 } 385 } finally { 386 unsafe.freeMemory(a); 387 } 388 return byteOrder; 389 } 390 391 // Cache for page size 392 private static int pageSize = -1; 393 394 /** 395 * Returns the page size of the underlying hardware. 396 * 397 * @return The page size, in bytes 398 */ pageSize()399 static int pageSize() { 400 if (pageSize == -1) 401 pageSize = unsafe.pageSize(); 402 return pageSize; 403 } 404 405 } 406