< prev index next >

src/java.base/share/classes/java/lang/invoke/VarHandles.java

Print this page




   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.lang.invoke;
  27 





  28 import java.lang.reflect.Field;
  29 import java.lang.reflect.Modifier;


  30 
  31 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  32 
  33 final class VarHandles {
  34 







  35     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
  36         if (!f.isStatic()) {
  37             long foffset = MethodHandleNatives.objectFieldOffset(f);
  38             if (!type.isPrimitive()) {
  39                 return f.isFinal() && !isWriteAllowedOnFinalFields
  40                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  41                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type);
  42             }
  43             else if (type == boolean.class) {
  44                 return f.isFinal() && !isWriteAllowedOnFinalFields
  45                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
  46                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
  47             }
  48             else if (type == byte.class) {
  49                 return f.isFinal() && !isWriteAllowedOnFinalFields
  50                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
  51                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
  52             }
  53             else if (type == short.class) {
  54                 return f.isFinal() && !isWriteAllowedOnFinalFields


 260         if (viewComponentType == long.class) {
 261             return new VarHandleByteArrayAsLongs.ByteBufferHandle(be);
 262         }
 263         else if (viewComponentType == int.class) {
 264             return new VarHandleByteArrayAsInts.ByteBufferHandle(be);
 265         }
 266         else if (viewComponentType == short.class) {
 267             return new VarHandleByteArrayAsShorts.ByteBufferHandle(be);
 268         }
 269         else if (viewComponentType == char.class) {
 270             return new VarHandleByteArrayAsChars.ByteBufferHandle(be);
 271         }
 272         else if (viewComponentType == double.class) {
 273             return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
 274         }
 275         else if (viewComponentType == float.class) {
 276             return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
 277         }
 278 
 279         throw new UnsupportedOperationException();






























 280     }
 281 
 282 //    /**
 283 //     * A helper program to generate the VarHandleGuards class with a set of
 284 //     * static guard methods each of which corresponds to a particular shape and
 285 //     * performs a type check of the symbolic type descriptor with the VarHandle
 286 //     * type descriptor before linking/invoking to the underlying operation as
 287 //     * characterized by the operation member name on the VarForm of the
 288 //     * VarHandle.
 289 //     * <p>
 290 //     * The generated class essentially encapsulates pre-compiled LambdaForms,
 291 //     * one for each method, for the most set of common method signatures.
 292 //     * This reduces static initialization costs, footprint costs, and circular
 293 //     * dependencies that may arise if a class is generated per LambdaForm.
 294 //     * <p>
 295 //     * A maximum of L*T*S methods will be generated where L is the number of
 296 //     * access modes kinds (or unique operation signatures) and T is the number
 297 //     * of variable types and S is the number of shapes (such as instance field,
 298 //     * static field, or array access).
 299 //     * If there are 4 unique operation signatures, 5 basic types (Object, int,




   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.lang.invoke;
  27 
  28 import jdk.internal.foreign.LayoutPathsImpl;
  29 
  30 import java.foreign.layout.Layout;
  31 import java.foreign.layout.LayoutPath;
  32 import java.foreign.layout.Value;
  33 import java.lang.reflect.Field;
  34 import java.lang.reflect.Modifier;
  35 import java.util.Map;
  36 import java.util.concurrent.ConcurrentHashMap;
  37 
  38 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  39 
  40 final class VarHandles {
  41 
  42     static ClassValue<Map<Integer, MethodHandle>> addressFactories = new ClassValue<Map<Integer, MethodHandle>>() {
  43         @Override
  44         protected Map<Integer, MethodHandle> computeValue(Class<?> type) {
  45             return new ConcurrentHashMap<>();
  46         }
  47     };
  48 
  49     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
  50         if (!f.isStatic()) {
  51             long foffset = MethodHandleNatives.objectFieldOffset(f);
  52             if (!type.isPrimitive()) {
  53                 return f.isFinal() && !isWriteAllowedOnFinalFields
  54                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  55                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type);
  56             }
  57             else if (type == boolean.class) {
  58                 return f.isFinal() && !isWriteAllowedOnFinalFields
  59                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
  60                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
  61             }
  62             else if (type == byte.class) {
  63                 return f.isFinal() && !isWriteAllowedOnFinalFields
  64                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
  65                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
  66             }
  67             else if (type == short.class) {
  68                 return f.isFinal() && !isWriteAllowedOnFinalFields


 274         if (viewComponentType == long.class) {
 275             return new VarHandleByteArrayAsLongs.ByteBufferHandle(be);
 276         }
 277         else if (viewComponentType == int.class) {
 278             return new VarHandleByteArrayAsInts.ByteBufferHandle(be);
 279         }
 280         else if (viewComponentType == short.class) {
 281             return new VarHandleByteArrayAsShorts.ByteBufferHandle(be);
 282         }
 283         else if (viewComponentType == char.class) {
 284             return new VarHandleByteArrayAsChars.ByteBufferHandle(be);
 285         }
 286         else if (viewComponentType == double.class) {
 287             return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
 288         }
 289         else if (viewComponentType == float.class) {
 290             return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
 291         }
 292 
 293         throw new UnsupportedOperationException();
 294     }
 295 
 296     static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, LayoutPath path) {
 297         if (carrier.isArray())
 298             throw new IllegalArgumentException("Illegal array carrier: " + carrier);
 299 
 300         Layout layout = path.layout();
 301 
 302         if (!(layout instanceof Value)) {
 303             throw new IllegalArgumentException("Not a value layout: " + layout);
 304         }
 305 
 306         long offset = path.offset() / 8;
 307         long length = layout.bitsSize() / 8;
 308         boolean be = ((Value)layout).endianness() == Value.Endianness.BIG_ENDIAN;
 309 
 310         long[] strides = ((LayoutPathsImpl.LayoutPathImpl)path).enclosingSequences().stream()
 311                 .mapToLong(seq -> seq.element().bitsSize() / 8)
 312                 .toArray();
 313 
 314         Map<Integer, MethodHandle> carrierFactory = addressFactories.get(carrier);
 315         MethodHandle fac = carrierFactory.computeIfAbsent(strides.length,
 316                 dims -> new AddressVarHandleGenerator(carrier, dims)
 317                             .generateHandleFactory());
 318         
 319         try {
 320             return (VarHandle)fac.invoke(be, length, offset, strides);
 321         } catch (Throwable ex) {
 322             throw new IllegalStateException(ex);
 323         }
 324     }
 325 
 326 //    /**
 327 //     * A helper program to generate the VarHandleGuards class with a set of
 328 //     * static guard methods each of which corresponds to a particular shape and
 329 //     * performs a type check of the symbolic type descriptor with the VarHandle
 330 //     * type descriptor before linking/invoking to the underlying operation as
 331 //     * characterized by the operation member name on the VarForm of the
 332 //     * VarHandle.
 333 //     * <p>
 334 //     * The generated class essentially encapsulates pre-compiled LambdaForms,
 335 //     * one for each method, for the most set of common method signatures.
 336 //     * This reduces static initialization costs, footprint costs, and circular
 337 //     * dependencies that may arise if a class is generated per LambdaForm.
 338 //     * <p>
 339 //     * A maximum of L*T*S methods will be generated where L is the number of
 340 //     * access modes kinds (or unique operation signatures) and T is the number
 341 //     * of variable types and S is the number of shapes (such as instance field,
 342 //     * static field, or array access).
 343 //     * If there are 4 unique operation signatures, 5 basic types (Object, int,


< prev index next >