2727import java .util .concurrent .atomic .AtomicLong ;
2828
2929import com .oracle .svm .core .annotate .Alias ;
30+ import com .oracle .svm .core .annotate .InjectAccessors ;
3031import com .oracle .svm .core .annotate .RecomputeFieldValue ;
3132import com .oracle .svm .core .annotate .RecomputeFieldValue .Kind ;
3233import com .oracle .svm .core .annotate .TargetClass ;
34+ import com .oracle .svm .core .heap .PhysicalMemory ;
3335
3436@ TargetClass (className = "java.nio.Bits" )
3537final class Target_java_nio_Bits {
@@ -40,9 +42,9 @@ final class Target_java_nio_Bits {
4042 private static int PAGE_SIZE = -1 ;
4143
4244 @ Alias @ RecomputeFieldValue (kind = Kind .FromAlias ) //
43- private static boolean MEMORY_LIMIT_SET = false ;
44- @ Alias @ RecomputeFieldValue ( kind = Kind . FromAlias ) //
45- private static long MAX_MEMORY = - 1 ;
45+ private static boolean MEMORY_LIMIT_SET = true ;
46+ @ Alias @ InjectAccessors ( MaxMemoryAccessor . class ) //
47+ private static long MAX_MEMORY ;
4648
4749 @ Alias @ RecomputeFieldValue (kind = Kind .FromAlias ) //
4850 private static AtomicLong RESERVED_MEMORY = new AtomicLong ();
@@ -53,3 +55,23 @@ final class Target_java_nio_Bits {
5355
5456 // Checkstyle: resume
5557}
58+
59+ /**
60+ * {@code java.nio.Bits} caches the max. direct memory size in the field {@code MAX_MEMORY}. We
61+ * disable this cache and always call {@link DirectMemoryAccessors#getDirectMemory()} instead, which
62+ * uses our own cache. Otherwise, it could happen that {@code MAX_MEMORY} caches a temporary value
63+ * that is used during early VM startup, before {@link PhysicalMemory} is fully initialized.
64+ */
65+ final class MaxMemoryAccessor {
66+ // Checkstyle: stop
67+
68+ static long getMAX_MEMORY () {
69+ return DirectMemoryAccessors .getDirectMemory ();
70+ }
71+
72+ static void setMAX_MEMORY (long value ) {
73+ /* Nothing to do. */
74+ }
75+
76+ // Checkstyle: resume
77+ }
0 commit comments