/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java

https://github.com/openjdk/valhalla · Java · 152 lines · 99 code · 22 blank · 31 comment · 14 complexity · 8d200df032d130b5b112ddf90aac2a54 MD5 · raw file

  1. /*
  2. * Copyright (c) 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 jdk.internal.foreign;
  27. import jdk.incubator.foreign.MemoryAddress;
  28. import jdk.incubator.foreign.MemorySegment;
  29. import jdk.internal.reflect.CallerSensitive;
  30. import jdk.internal.reflect.Reflection;
  31. import jdk.incubator.foreign.ResourceScope;
  32. import java.util.Objects;
  33. /**
  34. * This class provides an immutable implementation for the {@code MemoryAddress} interface. This class contains information
  35. * about the segment this address is associated with, as well as an offset into such segment.
  36. */
  37. public final class MemoryAddressImpl implements MemoryAddress {
  38. private final AbstractMemorySegmentImpl segment;
  39. private final long offset;
  40. public MemoryAddressImpl(AbstractMemorySegmentImpl segment, long offset) {
  41. this.segment = segment;
  42. this.offset = offset;
  43. }
  44. Object base() {
  45. return segment != null ? segment.base() : null;
  46. }
  47. long offset() {
  48. return segment != null ?
  49. segment.min() + offset : offset;
  50. }
  51. // MemoryAddress methods
  52. @Override
  53. public ResourceScope scope() {
  54. return segment != null ?
  55. segment.scope() : ResourceScope.globalScope();
  56. }
  57. @Override
  58. public MemoryAddress addOffset(long offset) {
  59. return new MemoryAddressImpl(segment, this.offset + offset);
  60. }
  61. @Override
  62. public long segmentOffset(MemorySegment segment) {
  63. Objects.requireNonNull(segment);
  64. AbstractMemorySegmentImpl segmentImpl = (AbstractMemorySegmentImpl)segment;
  65. if (segmentImpl.base() != base()) {
  66. throw new IllegalArgumentException("Incompatible segment: " + segment);
  67. }
  68. return offset() - segmentImpl.min();
  69. }
  70. @Override
  71. public boolean isNative() {
  72. return base() == null;
  73. }
  74. @Override
  75. public long toRawLongValue() {
  76. if (segment != null) {
  77. if (segment.base() != null) {
  78. throw new UnsupportedOperationException("Not a native address");
  79. }
  80. segment.checkValidState();
  81. }
  82. return offset();
  83. }
  84. // Object methods
  85. @Override
  86. public int hashCode() {
  87. return Objects.hash(base(), offset());
  88. }
  89. @Override
  90. public boolean equals(Object that) {
  91. if (that instanceof MemoryAddressImpl) {
  92. MemoryAddressImpl addr = (MemoryAddressImpl)that;
  93. return Objects.equals(base(), addr.base()) &&
  94. offset() == addr.offset();
  95. } else {
  96. return false;
  97. }
  98. }
  99. @Override
  100. public String toString() {
  101. return "MemoryAddress{ base: " + base() + " offset=0x" + Long.toHexString(offset()) + " }";
  102. }
  103. @Override
  104. @CallerSensitive
  105. public final MemorySegment asSegment(long bytesSize, ResourceScope scope) {
  106. Reflection.ensureNativeAccess(Reflection.getCallerClass());
  107. return asSegment(bytesSize, null, scope);
  108. }
  109. @Override
  110. @CallerSensitive
  111. public final MemorySegment asSegment(long bytesSize, Runnable cleanupAction, ResourceScope scope) {
  112. Reflection.ensureNativeAccess(Reflection.getCallerClass());
  113. Objects.requireNonNull(scope);
  114. if (bytesSize <= 0) {
  115. throw new IllegalArgumentException("Invalid size : " + bytesSize);
  116. }
  117. return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(this, bytesSize,
  118. cleanupAction,
  119. (ResourceScopeImpl) scope);
  120. }
  121. public static MemorySegment ofLongUnchecked(long value) {
  122. return ofLongUnchecked(value, Long.MAX_VALUE);
  123. }
  124. public static MemorySegment ofLongUnchecked(long value, long byteSize, ResourceScopeImpl resourceScope) {
  125. return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(MemoryAddress.ofLong(value), byteSize, null, resourceScope);
  126. }
  127. public static MemorySegment ofLongUnchecked(long value, long byteSize) {
  128. return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(MemoryAddress.ofLong(value), byteSize, null, ResourceScopeImpl.GLOBAL);
  129. }
  130. }