< prev index next >

src/java.base/share/classes/java/nio/MappedByteBuffer.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2013, 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


  73     // This works because DirectByteBuffer is a package-private class.
  74 
  75     // For mapped buffers, a FileDescriptor that may be used for mapping
  76     // operations if valid; null if the buffer is not mapped.
  77     private final FileDescriptor fd;
  78 
  79     // This should only be invoked by the DirectByteBuffer constructors
  80     //
  81     MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
  82                      FileDescriptor fd)
  83     {
  84         super(mark, pos, lim, cap);
  85         this.fd = fd;
  86     }
  87 
  88     MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
  89         super(mark, pos, lim, cap);
  90         this.fd = null;
  91     }
  92 
  93     private void checkMapped() {
  94         if (fd == null)
  95             // Can only happen if a luser explicitly casts a direct byte buffer
  96             throw new UnsupportedOperationException();
  97     }
  98 
  99     // Returns the distance (in bytes) of the buffer from the page aligned address
 100     // of the mapping. Computed each time to avoid storing in every direct buffer.
 101     private long mappingOffset() {
 102         int ps = Bits.pageSize();
 103         long offset = address % ps;
 104         return (offset >= 0) ? offset : (ps + offset);
 105     }
 106 
 107     private long mappingAddress(long mappingOffset) {
 108         return address - mappingOffset;
 109     }
 110 
 111     private long mappingLength(long mappingOffset) {
 112         return (long)capacity() + mappingOffset;
 113     }
 114 
 115     /**
 116      * Tells whether or not this buffer's content is resident in physical
 117      * memory.
 118      *
 119      * <p> A return value of {@code true} implies that it is highly likely
 120      * that all of the data in this buffer is resident in physical memory and
 121      * may therefore be accessed without incurring any virtual-memory page
 122      * faults or I/O operations.  A return value of {@code false} does not
 123      * necessarily imply that the buffer's content is not resident in physical
 124      * memory.
 125      *
 126      * <p> The returned value is a hint, rather than a guarantee, because the
 127      * underlying operating system may have paged out some of the buffer's data
 128      * by the time that an invocation of this method returns.  </p>
 129      *
 130      * @return  {@code true} if it is likely that this buffer's content
 131      *          is resident in physical memory
 132      */
 133     public final boolean isLoaded() {
 134         checkMapped();


 135         if ((address == 0) || (capacity() == 0))
 136             return true;
 137         long offset = mappingOffset();
 138         long length = mappingLength(offset);
 139         return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length));
 140     }
 141 
 142     // not used, but a potential target for a store, see load() for details.
 143     private static byte unused;
 144 
 145     /**
 146      * Loads this buffer's content into physical memory.
 147      *
 148      * <p> This method makes a best effort to ensure that, when it returns,
 149      * this buffer's content is resident in physical memory.  Invoking this
 150      * method may cause some number of page faults and I/O operations to
 151      * occur. </p>
 152      *
 153      * @return  This buffer
 154      */
 155     public final MappedByteBuffer load() {
 156         checkMapped();


 157         if ((address == 0) || (capacity() == 0))
 158             return this;
 159         long offset = mappingOffset();
 160         long length = mappingLength(offset);
 161         load0(mappingAddress(offset), length);
 162 
 163         // Read a byte from each page to bring it into memory. A checksum
 164         // is computed as we go along to prevent the compiler from otherwise
 165         // considering the loop as dead code.
 166         Unsafe unsafe = Unsafe.getUnsafe();
 167         int ps = Bits.pageSize();
 168         int count = Bits.pageCount(length);
 169         long a = mappingAddress(offset);
 170         byte x = 0;
 171         for (int i=0; i<count; i++) {
 172             x ^= unsafe.getByte(a);
 173             a += ps;
 174         }
 175         if (unused != 0)
 176             unused = x;


 180 
 181     /**
 182      * Forces any changes made to this buffer's content to be written to the
 183      * storage device containing the mapped file.
 184      *
 185      * <p> If the file mapped into this buffer resides on a local storage
 186      * device then when this method returns it is guaranteed that all changes
 187      * made to the buffer since it was created, or since this method was last
 188      * invoked, will have been written to that device.
 189      *
 190      * <p> If the file does not reside on a local device then no such guarantee
 191      * is made.
 192      *
 193      * <p> If this buffer was not mapped in read/write mode ({@link
 194      * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this
 195      * method has no effect. </p>
 196      *
 197      * @return  This buffer
 198      */
 199     public final MappedByteBuffer force() {
 200         checkMapped();


 201         if ((address != 0) && (capacity() != 0)) {
 202             long offset = mappingOffset();
 203             force0(fd, mappingAddress(offset), mappingLength(offset));
 204         }
 205         return this;
 206     }
 207 
 208     private native boolean isLoaded0(long address, long length, int pageCount);
 209     private native void load0(long address, long length);
 210     private native void force0(FileDescriptor fd, long address, long length);
 211 
 212     // -- Covariant return type overrides
 213 
 214     /**
 215      * {@inheritDoc}
 216      */
 217     @Override
 218     public final MappedByteBuffer position(int newPosition) {
 219         super.position(newPosition);
 220         return this;


   1 /*
   2  * Copyright (c) 2000, 2018, 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


  73     // This works because DirectByteBuffer is a package-private class.
  74 
  75     // For mapped buffers, a FileDescriptor that may be used for mapping
  76     // operations if valid; null if the buffer is not mapped.
  77     private final FileDescriptor fd;
  78 
  79     // This should only be invoked by the DirectByteBuffer constructors
  80     //
  81     MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
  82                      FileDescriptor fd)
  83     {
  84         super(mark, pos, lim, cap);
  85         this.fd = fd;
  86     }
  87 
  88     MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
  89         super(mark, pos, lim, cap);
  90         this.fd = null;
  91     }
  92 






  93     // Returns the distance (in bytes) of the buffer from the page aligned address
  94     // of the mapping. Computed each time to avoid storing in every direct buffer.
  95     private long mappingOffset() {
  96         int ps = Bits.pageSize();
  97         long offset = address % ps;
  98         return (offset >= 0) ? offset : (ps + offset);
  99     }
 100 
 101     private long mappingAddress(long mappingOffset) {
 102         return address - mappingOffset;
 103     }
 104 
 105     private long mappingLength(long mappingOffset) {
 106         return (long)capacity() + mappingOffset;
 107     }
 108 
 109     /**
 110      * Tells whether or not this buffer's content is resident in physical
 111      * memory.
 112      *
 113      * <p> A return value of {@code true} implies that it is highly likely
 114      * that all of the data in this buffer is resident in physical memory and
 115      * may therefore be accessed without incurring any virtual-memory page
 116      * faults or I/O operations.  A return value of {@code false} does not
 117      * necessarily imply that the buffer's content is not resident in physical
 118      * memory.
 119      *
 120      * <p> The returned value is a hint, rather than a guarantee, because the
 121      * underlying operating system may have paged out some of the buffer's data
 122      * by the time that an invocation of this method returns.  </p>
 123      *
 124      * @return  {@code true} if it is likely that this buffer's content
 125      *          is resident in physical memory
 126      */
 127     public final boolean isLoaded() {
 128         if (fd == null) {
 129             return true;
 130         }
 131         if ((address == 0) || (capacity() == 0))
 132             return true;
 133         long offset = mappingOffset();
 134         long length = mappingLength(offset);
 135         return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length));
 136     }
 137 
 138     // not used, but a potential target for a store, see load() for details.
 139     private static byte unused;
 140 
 141     /**
 142      * Loads this buffer's content into physical memory.
 143      *
 144      * <p> This method makes a best effort to ensure that, when it returns,
 145      * this buffer's content is resident in physical memory.  Invoking this
 146      * method may cause some number of page faults and I/O operations to
 147      * occur. </p>
 148      *
 149      * @return  This buffer
 150      */
 151     public final MappedByteBuffer load() {
 152         if (fd == null) {
 153             return this;
 154         }
 155         if ((address == 0) || (capacity() == 0))
 156             return this;
 157         long offset = mappingOffset();
 158         long length = mappingLength(offset);
 159         load0(mappingAddress(offset), length);
 160 
 161         // Read a byte from each page to bring it into memory. A checksum
 162         // is computed as we go along to prevent the compiler from otherwise
 163         // considering the loop as dead code.
 164         Unsafe unsafe = Unsafe.getUnsafe();
 165         int ps = Bits.pageSize();
 166         int count = Bits.pageCount(length);
 167         long a = mappingAddress(offset);
 168         byte x = 0;
 169         for (int i=0; i<count; i++) {
 170             x ^= unsafe.getByte(a);
 171             a += ps;
 172         }
 173         if (unused != 0)
 174             unused = x;


 178 
 179     /**
 180      * Forces any changes made to this buffer's content to be written to the
 181      * storage device containing the mapped file.
 182      *
 183      * <p> If the file mapped into this buffer resides on a local storage
 184      * device then when this method returns it is guaranteed that all changes
 185      * made to the buffer since it was created, or since this method was last
 186      * invoked, will have been written to that device.
 187      *
 188      * <p> If the file does not reside on a local device then no such guarantee
 189      * is made.
 190      *
 191      * <p> If this buffer was not mapped in read/write mode ({@link
 192      * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this
 193      * method has no effect. </p>
 194      *
 195      * @return  This buffer
 196      */
 197     public final MappedByteBuffer force() {
 198         if (fd == null) {
 199             return this;
 200         }
 201         if ((address != 0) && (capacity() != 0)) {
 202             long offset = mappingOffset();
 203             force0(fd, mappingAddress(offset), mappingLength(offset));
 204         }
 205         return this;
 206     }
 207 
 208     private native boolean isLoaded0(long address, long length, int pageCount);
 209     private native void load0(long address, long length);
 210     private native void force0(FileDescriptor fd, long address, long length);
 211 
 212     // -- Covariant return type overrides
 213 
 214     /**
 215      * {@inheritDoc}
 216      */
 217     @Override
 218     public final MappedByteBuffer position(int newPosition) {
 219         super.position(newPosition);
 220         return this;


< prev index next >