< prev index next >

src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template

Print this page




  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 #warn This file is preprocessed before being compiled
  27 
  28 package java.nio;
  29 
  30 import java.io.FileDescriptor;
  31 import jdk.internal.misc.Unsafe;
  32 import jdk.internal.misc.VM;
  33 import jdk.internal.ref.Cleaner;

  34 import sun.nio.ch.DirectBuffer;
  35 
  36 
  37 class Direct$Type$Buffer$RW$$BO$
  38 #if[rw]
  39     extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
  40 #else[rw]
  41     extends Direct$Type$Buffer$BO$
  42 #end[rw]
  43     implements DirectBuffer
  44 {
  45 
  46 #if[rw]
  47 
  48     // Cached unsafe-access object
  49     protected static final Unsafe unsafe = Bits.unsafe();
  50 
  51     // Cached array base offset
  52     private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
  53 
  54     // Cached unaligned-access capability
  55     protected static final boolean unaligned = Bits.unaligned();
  56 
  57     // Base address, used in all indexing calculations
  58     // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
  59     //    protected long address;
  60 
  61     // An object attached to this buffer. If this buffer is a view of another
  62     // buffer then we use this field to keep a reference to that buffer to
  63     // ensure that its memory isn't freed before we are done with it.
  64     private final Object att;
  65 
  66     public Object attachment() {
  67         return att;
  68     }
  69 
  70 #if[byte]
  71 






























  72     private static class Deallocator
  73         implements Runnable
  74     {
  75 
  76         private static Unsafe unsafe = Unsafe.getUnsafe();
  77 
  78         private long address;
  79         private long size;
  80         private int capacity;
  81 
  82         private Deallocator(long address, long size, int capacity) {
  83             assert (address != 0);
  84             this.address = address;
  85             this.size = size;
  86             this.capacity = capacity;
  87         }
  88 
  89         public void run() {
  90             if (address == 0) {
  91                 // Paranoia
  92                 return;
  93             }
  94             unsafe.freeMemory(address);
  95             address = 0;
  96             Bits.unreserveMemory(size, capacity);
  97         }
  98 
  99     }
 100 
 101     private final Cleaner cleaner;
 102 
 103     public Cleaner cleaner() { return cleaner; }
 104 
 105 #else[byte]
 106 
 107     public Cleaner cleaner() { return null; }
 108 
 109 #end[byte]
 110 
 111 #end[rw]
 112 
 113 #if[byte]
 114 
 115     // Primary constructor
 116     //
 117     Direct$Type$Buffer$RW$(int cap) {                   // package-private
 118 #if[rw]
 119         super(-1, 0, cap, cap);
 120         boolean pa = VM.isDirectMemoryPageAligned();
 121         int ps = Bits.pageSize();
 122         long size = Math.max(1L, (long)cap + (pa ? ps : 0));
 123         Bits.reserveMemory(size, cap);
 124 
 125         long base = 0;
 126         try {
 127             base = unsafe.allocateMemory(size);
 128         } catch (OutOfMemoryError x) {
 129             Bits.unreserveMemory(size, cap);
 130             throw x;
 131         }
 132         unsafe.setMemory(base, size, (byte) 0);
 133         if (pa && (base % ps != 0)) {
 134             // Round up to page boundary
 135             address = base + ps - (base & (ps - 1));
 136         } else {
 137             address = base;
 138         }
 139         cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
 140         att = null;
 141 #else[rw]
 142         super(cap);
 143 #end[rw]
 144     }
 145 
 146 #if[rw]
 147 
 148     // Invoked to construct a direct ByteBuffer referring to the block of
 149     // memory. A given arbitrary object may also be attached to the buffer.
 150     //
 151     Direct$Type$Buffer(long addr, int cap, Object ob) {
 152         super(-1, 0, cap, cap);
 153         address = addr;
 154         cleaner = null;
 155         att = ob;
 156     }
 157 
 158 
 159     // Invoked only by JNI: NewDirectByteBuffer(void*, long)
 160     //
 161     private Direct$Type$Buffer(long addr, int cap) {
 162         super(-1, 0, cap, cap);
 163         address = addr;
 164         cleaner = null;
 165         att = null;
 166     }
 167 
 168 #end[rw]
 169 
 170     // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
 171     //
 172     protected Direct$Type$Buffer$RW$(int cap, long addr,
 173                                      FileDescriptor fd,
 174                                      Runnable unmapper)
 175     {
 176 #if[rw]
 177         super(-1, 0, cap, cap, fd);
 178         address = addr;
 179         cleaner = Cleaner.create(this, unmapper);


 180         att = null;
 181 #else[rw]
 182         super(cap, addr, fd, unmapper);
 183 #end[rw]
 184     }
 185 
 186 #end[byte]
 187 
 188     // For duplicates and slices
 189     //
 190     Direct$Type$Buffer$RW$$BO$(DirectBuffer db,         // package-private
 191                                int mark, int pos, int lim, int cap,
 192                                int off)
 193     {
 194 #if[rw]
 195         super(mark, pos, lim, cap);
 196         address = db.address() + off;
 197 #if[byte]
 198         cleaner = null;
 199 #end[byte]




  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 #warn This file is preprocessed before being compiled
  27 
  28 package java.nio;
  29 
  30 import java.io.FileDescriptor;
  31 import jdk.internal.misc.Unsafe;
  32 import jdk.internal.misc.VM;
  33 import java.lang.ref.Cleaner;
  34 import jdk.internal.ref.CleanerFactory;
  35 import sun.nio.ch.DirectBuffer;
  36 
  37 
  38 class Direct$Type$Buffer$RW$$BO$
  39 #if[rw]
  40     extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
  41 #else[rw]
  42     extends Direct$Type$Buffer$BO$
  43 #end[rw]
  44     implements DirectBuffer
  45 {
  46 
  47 #if[rw]
  48 
  49     // Cached unsafe-access object
  50     protected static final Unsafe unsafe = Bits.unsafe();
  51 
  52     // Cached array base offset
  53     private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
  54 
  55     // Cached unaligned-access capability
  56     protected static final boolean unaligned = Bits.unaligned();
  57 
  58     // Base address, used in all indexing calculations
  59     // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
  60     //    protected long address;
  61 
  62     // An object attached to this buffer. If this buffer is a view of another
  63     // buffer then we use this field to keep a reference to that buffer to
  64     // ensure that its memory isn't freed before we are done with it.
  65     private final Object att;
  66 
  67     public Object attachment() {
  68         return att;
  69     }
  70 
  71 #if[byte]
  72 
  73     private static class Allocator
  74         implements Supplier<Long>
  75     {
  76         private static final Unsafe unsafe = Unsafe.getUnsafe();
  77 
  78         private final long size;
  79         private final int capacity;
  80 
  81         Allocator(long size, int capacity) {
  82             this.size = size;
  83             this.capacity = capacity;
  84         }
  85 
  86         @Override
  87         public Long get() {
  88             if (!Bits.tryReserveMemory(size, capacity)) {
  89                 return null;
  90             }
  91             long address;
  92             try {
  93                 address = unsafe.allocateMemory(size);
  94             } catch (OutOfMemoryError x) {
  95                 Bits.unreserveMemory(size, capacity);
  96                 return null;
  97             }
  98             unsafe.setMemory(address, size, (byte) 0);
  99             return address;
 100         }
 101     }
 102 
 103     private static class Deallocator
 104         implements Runnable
 105     {
 106 
 107         private static Unsafe unsafe = Unsafe.getUnsafe();
 108 
 109         private long address;
 110         private long size;
 111         private int capacity;
 112 
 113         private Deallocator(long address, long size, int capacity) {
 114             assert (address != 0);
 115             this.address = address;
 116             this.size = size;
 117             this.capacity = capacity;
 118         }
 119 
 120         public void run() {
 121             if (address == 0) {
 122                 // Paranoia
 123                 return;
 124             }
 125             unsafe.freeMemory(address);
 126             address = 0;
 127             Bits.unreserveMemory(size, capacity);
 128         }
 129 
 130     }
 131 
 132     private final Cleaner.Cleanable cleaner;
 133 
 134     public Cleaner.Cleanable cleaner() { return cleaner; }
 135 
 136 #else[byte]
 137 
 138     public Cleaner.Cleanable cleaner() { return null; }
 139 
 140 #end[byte]
 141 
 142 #end[rw]
 143 
 144 #if[byte]
 145 
 146     // Primary constructor
 147     //
 148     Direct$Type$Buffer$RW$(int cap) {                   // package-private
 149 #if[rw]
 150         super(-1, 0, cap, cap);
 151         boolean pa = VM.isDirectMemoryPageAligned();
 152         int ps = Bits.pageSize();
 153         long size = Math.max(1L, (long)cap + (pa ? ps : 0));

 154 
 155         Long base = CleanerFactory.dbbCleaner().retryWhileHelpingClean(new Allocator(size, cap));
 156         if (base == null) {
 157             throw new OutOfMemoryError("Direct buffer memory");



 158         }
 159 
 160         if (pa && (base % ps != 0)) {
 161             // Round up to page boundary
 162             address = base + ps - (base & (ps - 1));
 163         } else {
 164             address = base;
 165         }
 166         cleaner = CleanerFactory.dbbCleaner().register(this, new Deallocator(base, size, cap));
 167         att = null;
 168 #else[rw]
 169         super(cap);
 170 #end[rw]
 171     }
 172 
 173 #if[rw]
 174 
 175     // Invoked to construct a direct ByteBuffer referring to the block of
 176     // memory. A given arbitrary object may also be attached to the buffer.
 177     //
 178     Direct$Type$Buffer(long addr, int cap, Object ob) {
 179         super(-1, 0, cap, cap);
 180         address = addr;
 181         cleaner = null;
 182         att = ob;
 183     }
 184 
 185 
 186     // Invoked only by JNI: NewDirectByteBuffer(void*, long)
 187     //
 188     private Direct$Type$Buffer(long addr, int cap) {
 189         super(-1, 0, cap, cap);
 190         address = addr;
 191         cleaner = null;
 192         att = null;
 193     }
 194 
 195 #end[rw]
 196 
 197     // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
 198     //
 199     protected Direct$Type$Buffer$RW$(int cap, long addr,
 200                                      FileDescriptor fd,
 201                                      Runnable unmapper)
 202     {
 203 #if[rw]
 204         super(-1, 0, cap, cap, fd);
 205         address = addr;
 206         cleaner = (unmapper == null)
 207                   ? null
 208                   : CleanerFactory.dbbCleaner().register(this, unmapper);
 209         att = null;
 210 #else[rw]
 211         super(cap, addr, fd, unmapper);
 212 #end[rw]
 213     }
 214 
 215 #end[byte]
 216 
 217     // For duplicates and slices
 218     //
 219     Direct$Type$Buffer$RW$$BO$(DirectBuffer db,         // package-private
 220                                int mark, int pos, int lim, int cap,
 221                                int off)
 222     {
 223 #if[rw]
 224         super(mark, pos, lim, cap);
 225         address = db.address() + off;
 226 #if[byte]
 227         cleaner = null;
 228 #end[byte]


< prev index next >