1 /* 2 * Copyright (c) 2000, 2019, 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 package java.nio; 27 28 import java.io.FileDescriptor; 29 import java.lang.ref.Reference; 30 import java.util.Objects; 31 import jdk.internal.misc.Unsafe; 32 33 34 /** 35 * A direct byte buffer whose content is a memory-mapped region of a file. 36 * 37 * <p> Mapped byte buffers are created via the {@link 38 * java.nio.channels.FileChannel#map FileChannel.map} method. This class 39 * extends the {@link ByteBuffer} class with operations that are specific to 40 * memory-mapped file regions. 41 * 42 * <p> A mapped byte buffer and the file mapping that it represents remain 43 * valid until the buffer itself is garbage-collected. 44 * 45 * <p> The content of a mapped byte buffer can change at any time, for example 46 * if the content of the corresponding region of the mapped file is changed by 47 * this program or another. Whether or not such changes occur, and when they 48 * occur, is operating-system dependent and therefore unspecified. 49 * 50 * <a id="inaccess"></a><p> All or part of a mapped byte buffer may become 51 * inaccessible at any time, for example if the mapped file is truncated. An 52 * attempt to access an inaccessible region of a mapped byte buffer will not 53 * change the buffer's content and will cause an unspecified exception to be 54 * thrown either at the time of the access or at some later time. It is 55 * therefore strongly recommended that appropriate precautions be taken to 56 * avoid the manipulation of a mapped file by this program, or by a 57 * concurrently running program, except to read or write the file's content. 58 * 59 * <p> Mapped byte buffers otherwise behave no differently than ordinary direct 60 * byte buffers. </p> 61 * 62 * 63 * @author Mark Reinhold 64 * @author JSR-51 Expert Group 65 * @since 1.4 66 */ 67 68 public abstract class MappedByteBuffer 69 extends ByteBuffer 70 { 71 72 // This is a little bit backwards: By rights MappedByteBuffer should be a 73 // subclass of DirectByteBuffer, but to keep the spec clear and simple, and 74 // for optimization purposes, it's easier to do it the other way around. 75 // This works because DirectByteBuffer is a package-private class. 76 77 // For mapped buffers, a FileDescriptor that may be used for mapping 78 // operations if valid; null if the buffer is not mapped. 79 private final FileDescriptor fd; 80 81 // A flag true if this buffer is mapped against non-volatile 82 // memory using one of the extended FileChannel.MapMode modes, 83 // MapMode.READ_ONLY_SYNC or MapMode.READ_WRITE_SYNC and false if 84 // it is mapped using any of the other modes. This flag only 85 // determines the behavior of force operations. 86 private final boolean isSync; 87 88 // This should only be invoked by the DirectByteBuffer constructors 89 // 90 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private 91 FileDescriptor fd, boolean isSync) { 92 super(mark, pos, lim, cap); 93 this.fd = fd; 94 this.isSync = isSync; 95 } 96 97 MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private 98 boolean isSync) { 99 super(mark, pos, lim, cap); 100 this.fd = null; 101 this.isSync = isSync; 102 } 103 104 MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private 105 super(mark, pos, lim, cap); 106 this.fd = null; 107 this.isSync = false; 108 } 109 110 // Returns the distance (in bytes) of the buffer start from the 111 // largest page aligned address of the mapping less than or equal 112 // to the start address. 113 private long mappingOffset() { 114 return mappingOffset(0); 115 } 116 117 // Returns the distance (in bytes) of the buffer element 118 // identified by index from the largest page aligned address of 119 // the mapping less than or equal to the element address. Computed 120 // each time to avoid storing in every direct buffer. 121 private long mappingOffset(int index) { 122 int ps = Bits.pageSize(); 123 long indexAddress = address + index; 124 long baseAddress = alignDown(indexAddress, ps); 125 return indexAddress - baseAddress; 126 } 127 128 // Given an offset previously obtained from calling 129 // mappingOffset() returns the largest page aligned address of the 130 // mapping less than or equal to the buffer start address. 131 private long mappingAddress(long mappingOffset) { 132 return mappingAddress(mappingOffset, 0); 133 } 134 135 // Given an offset previously otained from calling 136 // mappingOffset(index) returns the largest page aligned address 137 // of the mapping less than or equal to the address of the buffer 138 // element identified by index. 139 private long mappingAddress(long mappingOffset, long index) { 140 long indexAddress = address + index; 141 return indexAddress - mappingOffset; 142 } 143 144 // given a mappingOffset previously otained from calling 145 // mappingOffset() return that offset added to the buffer 146 // capacity. 147 private long mappingLength(long mappingOffset) { 148 return mappingLength(mappingOffset, (long)capacity()); 149 } 150 151 // given a mappingOffset previously otained from calling 152 // mappingOffset(index) return that offset added to the supplied 153 // length. 154 private long mappingLength(long mappingOffset, long length) { 155 return length + mappingOffset; 156 } 157 158 // align address down to page size 159 private static long alignDown(long address, int pageSize) { 160 // pageSize must be a power of 2 161 return address & ~(pageSize - 1); 162 } 163 164 /** 165 * Tells whether this buffer was mapped against a non-volatile 166 * memory device by passing one of the sync map modes {@link 167 * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC 168 * ExtendedMapModeMapMode#READ_ONLY_SYNC} or {@link 169 * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC 170 * ExtendedMapMode#READ_WRITE_SYNC} in the call to {@link 171 * java.nio.channels.FileChannel#map FileChannel.map} or was 172 * mapped by passing one of the other map modes. 173 * 174 * @return true if the file was mapped using one of the sync map 175 * modes, otherwise false. 176 */ 177 private boolean isSync() { 178 return isSync; 179 } 180 181 /** 182 * Tells whether or not this buffer's content is resident in physical 183 * memory. 184 * 185 * <p> A return value of {@code true} implies that it is highly likely 186 * that all of the data in this buffer is resident in physical memory and 187 * may therefore be accessed without incurring any virtual-memory page 188 * faults or I/O operations. A return value of {@code false} does not 189 * necessarily imply that the buffer's content is not resident in physical 190 * memory. 191 * 192 * <p> The returned value is a hint, rather than a guarantee, because the 193 * underlying operating system may have paged out some of the buffer's data 194 * by the time that an invocation of this method returns. </p> 195 * 196 * @return {@code true} if it is likely that this buffer's content 197 * is resident in physical memory 198 */ 199 public final boolean isLoaded() { 200 if (fd == null) { 201 return true; 202 } 203 // a sync mapped buffer is always loaded 204 if (isSync()) { 205 return true; 206 } 207 if ((address == 0) || (capacity() == 0)) 208 return true; 209 long offset = mappingOffset(); 210 long length = mappingLength(offset); 211 return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); 212 } 213 214 // not used, but a potential target for a store, see load() for details. 215 private static byte unused; 216 217 /** 218 * Loads this buffer's content into physical memory. 219 * 220 * <p> This method makes a best effort to ensure that, when it returns, 221 * this buffer's content is resident in physical memory. Invoking this 222 * method may cause some number of page faults and I/O operations to 223 * occur. </p> 224 * 225 * @return This buffer 226 */ 227 public final MappedByteBuffer load() { 228 if (fd == null) { 229 return this; 230 } 231 // no need to load a sync mapped buffer 232 if (isSync()) { 233 return this; 234 } 235 if ((address == 0) || (capacity() == 0)) 236 return this; 237 long offset = mappingOffset(); 238 long length = mappingLength(offset); 239 load0(mappingAddress(offset), length); 240 241 // Read a byte from each page to bring it into memory. A checksum 242 // is computed as we go along to prevent the compiler from otherwise 243 // considering the loop as dead code. 244 Unsafe unsafe = Unsafe.getUnsafe(); 245 int ps = Bits.pageSize(); 246 int count = Bits.pageCount(length); 247 long a = mappingAddress(offset); 248 byte x = 0; 249 try { 250 for (int i=0; i<count; i++) { 251 // TODO consider changing to getByteOpaque thus avoiding 252 // dead code elimination and the need to calculate a checksum 253 x ^= unsafe.getByte(a); 254 a += ps; 255 } 256 } finally { 257 Reference.reachabilityFence(this); 258 } 259 if (unused != 0) 260 unused = x; 261 262 return this; 263 } 264 265 /** 266 * Forces any changes made to this buffer's content to be written to the 267 * storage device containing the mapped file. 268 * 269 * <p> If the file mapped into this buffer resides on a local storage 270 * device then when this method returns it is guaranteed that all changes 271 * made to the buffer since it was created, or since this method was last 272 * invoked, will have been written to that device. 273 * 274 * <p> If the file does not reside on a local device then no such guarantee 275 * is made. 276 * 277 * <p> If this buffer was not mapped in read/write mode ({@link 278 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then 279 * invoking this method may have no effect. In particular, the 280 * method has no effect for buffers mapped in read-only or private 281 * mapping modes. This method may or may not have an effect for 282 * implementation-specific mapping modes. </p> 283 * 284 * @return This buffer 285 */ 286 public final MappedByteBuffer force() { 287 if (fd == null) { 288 return this; 289 } 290 if (isSync) { 291 return force(0, limit()); 292 } 293 if ((address != 0) && (capacity() != 0)) { 294 long offset = mappingOffset(); 295 force0(fd, mappingAddress(offset), mappingLength(offset)); 296 } 297 return this; 298 } 299 300 /** 301 * Forces any changes made to a region of this buffer's content to 302 * be written to the storage device containing the mapped 303 * file. The region starts at the given {@code index} in this 304 * buffer and is {@code length} bytes. 305 * 306 * <p> If the file mapped into this buffer resides on a local 307 * storage device then when this method returns it is guaranteed 308 * that all changes made to the selected region buffer since it 309 * was created, or since this method was last invoked, will have 310 * been written to that device. The force operation is free to 311 * write bytes that lie outside the specified region, for example 312 * to ensure that data blocks of some device-specific granularity 313 * are transferred in their entirety. 314 * 315 * <p> If the file does not reside on a local device then no such 316 * guarantee is made. 317 * 318 * <p> If this buffer was not mapped in read/write mode ({@link 319 * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then 320 * invoking this method may have no effect. In particular, the 321 * method has no effect for buffers mapped in read-only or private 322 * mapping modes. This method may or may not have an effect for 323 * implementation-specific mapping modes. </p> 324 * 325 * @param index 326 * The index of the first byte in the buffer region that is 327 * to be written back to storage; must be non-negative 328 * and less than limit() 329 * 330 * @param length 331 * The length of the region in bytes; must be non-negative 332 * and no larger than limit() - index 333 * 334 * @throws IndexOutOfBoundsException 335 * if the preconditions on the index and length do not 336 * hold. 337 * 338 * @return This buffer 339 * 340 * @since 13 341 */ 342 public final MappedByteBuffer force(int index, int length) { 343 if (fd == null) { 344 return this; 345 } 346 if ((address != 0) && (limit() != 0)) { 347 // check inputs 348 Objects.checkFromIndexSize(index, length, limit()); 349 if (isSync) { 350 // simply force writeback of associated cache lines 351 Unsafe.getUnsafe().writebackMemory(address + index, length); 352 } else { 353 // force writeback via file descriptor 354 long offset = mappingOffset(index); 355 force0(fd, mappingAddress(offset, index), mappingLength(offset, length)); 356 } 357 } 358 return this; 359 } 360 361 private native boolean isLoaded0(long address, long length, int pageCount); 362 private native void load0(long address, long length); 363 private native void force0(FileDescriptor fd, long address, long length); 364 365 // -- Covariant return type overrides 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override 371 public final MappedByteBuffer position(int newPosition) { 372 super.position(newPosition); 373 return this; 374 } 375 376 /** 377 * {@inheritDoc} 378 */ 379 @Override 380 public final MappedByteBuffer limit(int newLimit) { 381 super.limit(newLimit); 382 return this; 383 } 384 385 /** 386 * {@inheritDoc} 387 */ 388 @Override 389 public final MappedByteBuffer mark() { 390 super.mark(); 391 return this; 392 } 393 394 /** 395 * {@inheritDoc} 396 */ 397 @Override 398 public final MappedByteBuffer reset() { 399 super.reset(); 400 return this; 401 } 402 403 /** 404 * {@inheritDoc} 405 */ 406 @Override 407 public final MappedByteBuffer clear() { 408 super.clear(); 409 return this; 410 } 411 412 /** 413 * {@inheritDoc} 414 */ 415 @Override 416 public final MappedByteBuffer flip() { 417 super.flip(); 418 return this; 419 } 420 421 /** 422 * {@inheritDoc} 423 */ 424 @Override 425 public final MappedByteBuffer rewind() { 426 super.rewind(); 427 return this; 428 } 429 }