26
26
package java .lang .foreign ;
27
27
28
28
import java .lang .invoke .MethodHandle ;
29
- import java .lang .invoke .MethodHandles ;
30
- import java .lang .invoke .MethodType ;
31
29
import java .lang .invoke .VarHandle ;
32
- import java .util .EnumSet ;
33
30
import java .util .Objects ;
34
31
import java .util .Optional ;
35
- import java .util .Set ;
36
- import java .util .function .Function ;
37
32
import java .util .stream .Stream ;
38
33
39
34
import jdk .internal .foreign .LayoutPath ;
44
39
import jdk .internal .foreign .layout .SequenceLayoutImpl ;
45
40
import jdk .internal .foreign .layout .StructLayoutImpl ;
46
41
import jdk .internal .foreign .layout .UnionLayoutImpl ;
47
- import jdk .internal .vm .annotation .ForceInline ;
48
42
49
43
/**
50
44
* A memory layout describes the contents of a memory segment.
@@ -404,35 +398,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
404
398
* @throws IllegalArgumentException if {@code offset} or {@code index} is negative
405
399
* @throws ArithmeticException if either the addition or multiplication overflows
406
400
*/
407
- @ ForceInline
408
- default long scale (long offset , long index ) {
409
- if (offset < 0 ) {
410
- throw new IllegalArgumentException ("Negative offset: " + offset );
411
- }
412
- if (index < 0 ) {
413
- throw new IllegalArgumentException ("Negative index: " + index );
414
- }
415
-
416
- return Math .addExact (offset , Math .multiplyExact (byteSize (), index ));
417
- }
401
+ long scale (long offset , long index );
418
402
419
403
/**
420
404
*{@return a method handle that can be used to invoke {@link #scale(long, long)} on this layout}
421
405
*/
422
- default MethodHandle scaleHandle () {
423
- class Holder {
424
- static final MethodHandle MH_SCALE ;
425
- static {
426
- try {
427
- MH_SCALE = MethodHandles .lookup ().findVirtual (MemoryLayout .class , "scale" ,
428
- MethodType .methodType (long .class , long .class , long .class ));
429
- } catch (ReflectiveOperationException e ) {
430
- throw new ExceptionInInitializerError (e );
431
- }
432
- }
433
- }
434
- return Holder .MH_SCALE .bindTo (this );
435
- }
406
+ MethodHandle scaleHandle ();
436
407
437
408
/**
438
409
* Computes the offset, in bytes, of the layout selected by the given layout path, where the initial layout in the
@@ -444,10 +415,7 @@ class Holder {
444
415
* @throws IllegalArgumentException if the layout path contains one or more <a href=#open-path-elements>open path elements</a>.
445
416
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
446
417
*/
447
- default long byteOffset (PathElement ... elements ) {
448
- return computePathOp (LayoutPath .rootPath (this ), LayoutPath ::offset ,
449
- EnumSet .of (PathKind .SEQUENCE_ELEMENT , PathKind .SEQUENCE_RANGE , PathKind .DEREF_ELEMENT ), elements );
450
- }
418
+ long byteOffset (PathElement ... elements );
451
419
452
420
/**
453
421
* Creates a method handle that computes the offset, in bytes, of the layout selected
@@ -482,10 +450,7 @@ default long byteOffset(PathElement... elements) {
482
450
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
483
451
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
484
452
*/
485
- default MethodHandle byteOffsetHandle (PathElement ... elements ) {
486
- return computePathOp (LayoutPath .rootPath (this ), LayoutPath ::offsetHandle ,
487
- EnumSet .of (PathKind .DEREF_ELEMENT ), elements );
488
- }
453
+ MethodHandle byteOffsetHandle (PathElement ... elements );
489
454
490
455
/**
491
456
* Creates a var handle that accesses a memory segment at the offset selected by the given layout path,
@@ -577,14 +542,7 @@ default MethodHandle byteOffsetHandle(PathElement... elements) {
577
542
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
578
543
* @throws IllegalArgumentException if the layout selected by the provided path is not a {@linkplain ValueLayout value layout}.
579
544
*/
580
- default VarHandle varHandle (PathElement ... elements ) {
581
- Objects .requireNonNull (elements );
582
- if (this instanceof ValueLayout vl && elements .length == 0 ) {
583
- return vl .varHandle (); // fast path
584
- }
585
- return computePathOp (LayoutPath .rootPath (this ), LayoutPath ::dereferenceHandle ,
586
- Set .of (), elements );
587
- }
545
+ VarHandle varHandle (PathElement ... elements );
588
546
589
547
/**
590
548
* Creates a method handle which, given a memory segment, returns a {@linkplain MemorySegment#asSlice(long,long) slice}
@@ -623,10 +581,7 @@ default VarHandle varHandle(PathElement... elements) {
623
581
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
624
582
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
625
583
*/
626
- default MethodHandle sliceHandle (PathElement ... elements ) {
627
- return computePathOp (LayoutPath .rootPath (this ), LayoutPath ::sliceHandle ,
628
- Set .of (PathKind .DEREF_ELEMENT ), elements );
629
- }
584
+ MethodHandle sliceHandle (PathElement ... elements );
630
585
631
586
/**
632
587
* Returns the layout selected from the provided path, where the initial layout in the path is this layout.
@@ -638,23 +593,7 @@ default MethodHandle sliceHandle(PathElement... elements) {
638
593
* @throws IllegalArgumentException if the layout path contains one or more path elements that select one or more
639
594
* sequence element indices, such as {@link PathElement#sequenceElement(long)} and {@link PathElement#sequenceElement(long, long)}).
640
595
*/
641
- default MemoryLayout select (PathElement ... elements ) {
642
- return computePathOp (LayoutPath .rootPath (this ), LayoutPath ::layout ,
643
- EnumSet .of (PathKind .SEQUENCE_ELEMENT_INDEX , PathKind .SEQUENCE_RANGE , PathKind .DEREF_ELEMENT ), elements );
644
- }
645
-
646
- private static <Z > Z computePathOp (LayoutPath path , Function <LayoutPath , Z > finalizer ,
647
- Set <PathKind > badKinds , PathElement ... elements ) {
648
- Objects .requireNonNull (elements );
649
- for (PathElement e : elements ) {
650
- LayoutPath .PathElementImpl pathElem = (LayoutPath .PathElementImpl )Objects .requireNonNull (e );
651
- if (badKinds .contains (pathElem .kind ())) {
652
- throw new IllegalArgumentException (String .format ("Invalid %s selection in layout path" , pathElem .kind ().description ()));
653
- }
654
- path = pathElem .apply (path );
655
- }
656
- return finalizer .apply (path );
657
- }
596
+ MemoryLayout select (PathElement ... elements );
658
597
659
598
/**
660
599
* An element in a <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. There
0 commit comments