blob: 8729f7c616dc3af386f387a3560de602194d3423 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2002 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26/*
27 */
28
29package sun.nio.ch; // Formerly in sun.misc
30
31import java.nio.ByteOrder;
32import 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
41class 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 */
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 */
66 NativeObject(long address, long offset) {
67 this.allocationAddress = address;
68 this.address = address + offset;
69 }
70
71 // Invoked only by AllocatedNativeObject
72 //
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 */
90 long address() {
91 return address;
92 }
93
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
399 static int pageSize() {
400 if (pageSize == -1)
401 pageSize = unsafe.pageSize();
402 return pageSize;
403 }
404
405}