Path: blob/master/src/java.base/share/classes/sun/nio/ch/NativeObject.java
41159 views
/*1* Copyright (c) 2000, 2002, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26*/2728package sun.nio.ch; // Formerly in sun.misc2930import java.nio.ByteOrder;31import jdk.internal.misc.Unsafe;323334// ## In the fullness of time, this class will be eliminated3536/**37* Proxies for objects that reside in native memory.38*/3940class NativeObject { // package-private4142protected static final Unsafe unsafe = Unsafe.getUnsafe();4344// Native allocation address;45// may be smaller than the base address due to page-size rounding46//47protected long allocationAddress;4849// Native base address50//51private final long address;5253/**54* Creates a new native object that is based at the given native address.55*/56NativeObject(long address) {57this.allocationAddress = address;58this.address = address;59}6061/**62* Creates a new native object allocated at the given native address but63* whose base is at the additional offset.64*/65NativeObject(long address, long offset) {66this.allocationAddress = address;67this.address = address + offset;68}6970// Invoked only by AllocatedNativeObject71//72protected NativeObject(int size, boolean pageAligned) {73if (!pageAligned) {74this.allocationAddress = unsafe.allocateMemory(size);75this.address = this.allocationAddress;76} else {77int ps = pageSize();78long a = unsafe.allocateMemory(size + ps);79this.allocationAddress = a;80this.address = a + ps - (a & (ps - 1));81}82}8384/**85* Returns the native base address of this native object.86*87* @return The native base address88*/89long address() {90return address;91}9293long allocationAddress() {94return allocationAddress;95}9697/**98* Creates a new native object starting at the given offset from the base99* of this native object.100*101* @param offset102* The offset from the base of this native object that is to be103* the base of the new native object104*105* @return The newly created native object106*/107NativeObject subObject(int offset) {108return new NativeObject(offset + address);109}110111/**112* Reads an address from this native object at the given offset and113* constructs a native object using that address.114*115* @param offset116* The offset of the address to be read. Note that the size of an117* address is implementation-dependent.118*119* @return The native object created using the address read from the120* given offset121*/122NativeObject getObject(int offset) {123long newAddress = 0L;124switch (addressSize()) {125case 8:126newAddress = unsafe.getLong(offset + address);127break;128case 4:129newAddress = unsafe.getInt(offset + address) & 0x00000000FFFFFFFF;130break;131default:132throw new InternalError("Address size not supported");133}134135return new NativeObject(newAddress);136}137138/**139* Writes the base address of the given native object at the given offset140* of this native object.141*142* @param offset143* The offset at which the address is to be written. Note that the144* size of an address is implementation-dependent.145*146* @param ob147* The native object whose address is to be written148*/149void putObject(int offset, NativeObject ob) {150switch (addressSize()) {151case 8:152putLong(offset, ob.address);153break;154case 4:155putInt(offset, (int)(ob.address & 0x00000000FFFFFFFF));156break;157default:158throw new InternalError("Address size not supported");159}160}161162163/* -- Value accessors: No range checking! -- */164165/**166* Reads a byte starting at the given offset from base of this native167* object.168*169* @param offset170* The offset at which to read the byte171*172* @return The byte value read173*/174final byte getByte(int offset) {175return unsafe.getByte(offset + address);176}177178/**179* Writes a byte at the specified offset from this native object's180* base address.181*182* @param offset183* The offset at which to write the byte184*185* @param value186* The byte value to be written187*/188final void putByte(int offset, byte value) {189unsafe.putByte(offset + address, value);190}191192/**193* Reads a short starting at the given offset from base of this native194* object.195*196* @param offset197* The offset at which to read the short198*199* @return The short value read200*/201final short getShort(int offset) {202return unsafe.getShort(offset + address);203}204205/**206* Writes a short at the specified offset from this native object's207* base address.208*209* @param offset210* The offset at which to write the short211*212* @param value213* The short value to be written214*/215final void putShort(int offset, short value) {216unsafe.putShort(offset + address, value);217}218219/**220* Reads a char starting at the given offset from base of this native221* object.222*223* @param offset224* The offset at which to read the char225*226* @return The char value read227*/228final char getChar(int offset) {229return unsafe.getChar(offset + address);230}231232/**233* Writes a char at the specified offset from this native object's234* base address.235*236* @param offset237* The offset at which to write the char238*239* @param value240* The char value to be written241*/242final void putChar(int offset, char value) {243unsafe.putChar(offset + address, value);244}245246/**247* Reads an int starting at the given offset from base of this native248* object.249*250* @param offset251* The offset at which to read the int252*253* @return The int value read254*/255final int getInt(int offset) {256return unsafe.getInt(offset + address);257}258259/**260* Writes an int at the specified offset from this native object's261* base address.262*263* @param offset264* The offset at which to write the int265*266* @param value267* The int value to be written268*/269final void putInt(int offset, int value) {270unsafe.putInt(offset + address, value);271}272273/**274* Reads a long starting at the given offset from base of this native275* object.276*277* @param offset278* The offset at which to read the long279*280* @return The long value read281*/282final long getLong(int offset) {283return unsafe.getLong(offset + address);284}285286/**287* Writes a long at the specified offset from this native object's288* base address.289*290* @param offset291* The offset at which to write the long292*293* @param value294* The long value to be written295*/296final void putLong(int offset, long value) {297unsafe.putLong(offset + address, value);298}299300/**301* Reads a float starting at the given offset from base of this native302* object.303*304* @param offset305* The offset at which to read the float306*307* @return The float value read308*/309final float getFloat(int offset) {310return unsafe.getFloat(offset + address);311}312313/**314* Writes a float at the specified offset from this native object's315* base address.316*317* @param offset318* The offset at which to write the float319*320* @param value321* The float value to be written322*/323final void putFloat(int offset, float value) {324unsafe.putFloat(offset + address, value);325}326327/**328* Reads a double starting at the given offset from base of this native329* object.330*331* @param offset332* The offset at which to read the double333*334* @return The double value read335*/336final double getDouble(int offset) {337return unsafe.getDouble(offset + address);338}339340/**341* Writes a double at the specified offset from this native object's342* base address.343*344* @param offset345* The offset at which to write the double346*347* @param value348* The double value to be written349*/350final void putDouble(int offset, double value) {351unsafe.putDouble(offset + address, value);352}353354/**355* Returns the native architecture's address size in bytes.356*357* @return The address size of the native architecture358*/359static int addressSize() {360return unsafe.addressSize();361}362363// Cache for byte order364private static ByteOrder byteOrder = null;365366/**367* Returns the byte order of the underlying hardware.368*369* @return An instance of {@link java.nio.ByteOrder}370*/371static ByteOrder byteOrder() {372if (byteOrder != null)373return byteOrder;374long a = unsafe.allocateMemory(8);375try {376unsafe.putLong(a, 0x0102030405060708L);377byte b = unsafe.getByte(a);378switch (b) {379case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;380case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;381default:382assert false;383}384} finally {385unsafe.freeMemory(a);386}387return byteOrder;388}389390/**391* Cache for page size.392* Lazily initialized via a data race; safe because ints are atomic.393*/394private static int pageSize = -1;395396/**397* Returns the page size of the underlying hardware.398*399* @return The page size, in bytes400*/401static int pageSize() {402int value = pageSize;403if (value == -1)404pageSize = value = unsafe.pageSize();405return value;406}407408}409410411