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 }