Skip to content

Commit 39183ff

Browse files
committed
[GR-44810] Add an isolate data section
PullRequest: graal/13796
2 parents a869fe5 + 9e6eb42 commit 39183ff

File tree

16 files changed

+424
-189
lines changed

16 files changed

+424
-189
lines changed

substratevm/mx.substratevm/suite.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@
455455
],
456456
"jdk.internal.vm.ci" : [
457457
"jdk.vm.ci.code",
458+
"jdk.vm.ci.meta",
458459
],
459460
},
460461
"checkstyle": "com.oracle.svm.core",
@@ -477,6 +478,7 @@
477478
"requiresConcealed" : {
478479
"jdk.internal.vm.ci" : [
479480
"jdk.vm.ci.code",
481+
"jdk.vm.ci.meta",
480482
],
481483
},
482484
"checkstyle": "com.oracle.svm.core",

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinVMSemaphoreFeature.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ final class DarwinVMSemaphoreFeature implements InternalFeature {
4949
private final ClassInstanceReplacer<VMSemaphore, VMSemaphore> semaphoreReplacer = new ClassInstanceReplacer<>(VMSemaphore.class) {
5050
@Override
5151
protected VMSemaphore createReplacement(VMSemaphore source) {
52-
return new DarwinVMSemaphore();
52+
return new DarwinVMSemaphore(source.getName());
5353
}
5454
};
5555

@@ -105,7 +105,8 @@ public DarwinVMSemaphore[] getSemaphores() {
105105
final class DarwinVMSemaphore extends VMSemaphore {
106106

107107
@Platforms(Platform.HOSTED_ONLY.class)
108-
DarwinVMSemaphore() {
108+
DarwinVMSemaphore(String name) {
109+
super(name);
109110
}
110111

111112
@Override

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxVMSemaphoreFeature.java

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,16 @@
2424
*/
2525
package com.oracle.svm.core.posix.linux;
2626

27-
import org.graalvm.compiler.core.common.NumUtil;
28-
import org.graalvm.compiler.word.Word;
2927
import org.graalvm.nativeimage.ImageSingletons;
3028
import org.graalvm.nativeimage.Platform;
3129
import org.graalvm.nativeimage.Platforms;
32-
import org.graalvm.nativeimage.c.struct.SizeOf;
33-
import org.graalvm.word.UnsignedWord;
3430
import org.graalvm.word.WordFactory;
3531

36-
import com.oracle.svm.core.BuildPhaseProvider.ReadyForCompilation;
3732
import com.oracle.svm.core.SubstrateOptions;
3833
import com.oracle.svm.core.Uninterruptible;
39-
import com.oracle.svm.core.config.ConfigurationValues;
40-
import com.oracle.svm.core.config.ObjectLayout;
34+
import com.oracle.svm.core.BuildPhaseProvider.ReadyForCompilation;
35+
import com.oracle.svm.core.c.CIsolateData;
36+
import com.oracle.svm.core.c.CIsolateDataFactory;
4137
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4238
import com.oracle.svm.core.feature.InternalFeature;
4339
import com.oracle.svm.core.heap.UnknownObjectField;
@@ -47,8 +43,6 @@
4743
import com.oracle.svm.core.posix.headers.Semaphore;
4844
import com.oracle.svm.core.posix.pthread.PthreadVMLockSupport;
4945

50-
import jdk.vm.ci.meta.JavaKind;
51-
5246
/**
5347
* Support of {@link VMSemaphore} in multithreaded environments on LINUX.
5448
*/
@@ -58,7 +52,7 @@ final class LinuxVMSemaphoreFeature implements InternalFeature {
5852
private final ClassInstanceReplacer<VMSemaphore, VMSemaphore> semaphoreReplacer = new ClassInstanceReplacer<>(VMSemaphore.class) {
5953
@Override
6054
protected VMSemaphore createReplacement(VMSemaphore source) {
61-
return new LinuxVMSemaphore();
55+
return new LinuxVMSemaphore(source.getName());
6256
}
6357
};
6458

@@ -75,53 +69,18 @@ public void duringSetup(DuringSetupAccess access) {
7569

7670
@Override
7771
public void beforeCompilation(BeforeCompilationAccess access) {
78-
final int wordSize = ConfigurationValues.getTarget().wordSize;
79-
80-
// `alignment` should actually be: `max(alignof(pthread_mutex_t), alignof(pthread_cond_t))`.
81-
//
82-
// Until `alignof()` can be queried from the C compiler, we hard-code this alignment to:
83-
// - One word on 64-bit architectures.
84-
// - Two words on 32-bit architectures.
85-
//
86-
// This split is arbitrary. Actual alignment requirements depend on the architecture,
87-
// the Pthread library implementation, and the C compiler.
88-
// These hard-coded values will need to be adjusted to higher values if we find out
89-
// that `pthread_mutex_t` or `pthread_cond_t` have higher alignment requirements on some
90-
// particular architecture.
91-
assert wordSize == 8 || wordSize == 4 : "Unsupported architecture bit width";
92-
final int alignment = (wordSize == 8) ? wordSize : (2 * wordSize);
93-
94-
ObjectLayout layout = ConfigurationValues.getObjectLayout();
95-
final int baseOffset = layout.getArrayBaseOffset(JavaKind.Byte);
96-
97-
// Align the first element to word boundary.
98-
int nextIndex = NumUtil.roundUp(baseOffset, alignment) - baseOffset;
99-
10072
LinuxVMSemaphore[] semaphores = semaphoreReplacer.getReplacements().toArray(new LinuxVMSemaphore[0]);
101-
int semaphoreSize = NumUtil.roundUp(SizeOf.get(Semaphore.sem_t.class), alignment);
102-
for (LinuxVMSemaphore semaphore : semaphores) {
103-
long offset = layout.getArrayElementOffset(JavaKind.Byte, nextIndex);
104-
assert offset % alignment == 0;
105-
semaphore.structOffset = WordFactory.unsigned(offset);
106-
nextIndex += semaphoreSize;
107-
}
10873

10974
LinuxVMSemaphoreSupport semaphoreSupport = (LinuxVMSemaphoreSupport) PosixVMSemaphoreSupport.singleton();
11075
semaphoreSupport.semaphores = semaphores;
111-
semaphoreSupport.semaphoreStructs = new byte[nextIndex];
11276
}
11377
}
11478

11579
final class LinuxVMSemaphoreSupport extends PosixVMSemaphoreSupport {
11680

11781
/** All semaphores, so that we can initialize them at run time when the VM starts. */
118-
@UnknownObjectField(availability = ReadyForCompilation.class) LinuxVMSemaphore[] semaphores;
119-
120-
/**
121-
* Raw memory for the semaphore lock structures. The offset into this array is stored in
122-
* {@link LinuxVMSemaphore#structOffset}.
123-
*/
124-
@UnknownObjectField(availability = ReadyForCompilation.class) byte[] semaphoreStructs;
82+
@UnknownObjectField(availability = ReadyForCompilation.class) //
83+
LinuxVMSemaphore[] semaphores;
12584

12685
@Override
12786
@Uninterruptible(reason = "Called from uninterruptible code. Too early for safepoints.")
@@ -150,16 +109,17 @@ public LinuxVMSemaphore[] getSemaphores() {
150109
}
151110

152111
final class LinuxVMSemaphore extends VMSemaphore {
153-
UnsignedWord structOffset;
112+
private final CIsolateData<Semaphore.sem_t> structPointer;
154113

155114
@Platforms(Platform.HOSTED_ONLY.class)
156-
LinuxVMSemaphore() {
115+
LinuxVMSemaphore(String name) {
116+
super(name);
117+
structPointer = CIsolateDataFactory.createStruct("linuxSemaphore_" + name, Semaphore.sem_t.class);
157118
}
158119

159120
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
160121
private Semaphore.sem_t getStructPointer() {
161-
LinuxVMSemaphoreSupport semaphoreSupport = (LinuxVMSemaphoreSupport) PosixVMSemaphoreSupport.singleton();
162-
return (Semaphore.sem_t) Word.objectToUntrackedPointer(semaphoreSupport.semaphoreStructs).add(structOffset);
122+
return structPointer.get();
163123
}
164124

165125
@Override

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/pthread/PthreadVMLockSupport.java

Lines changed: 17 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,23 @@
2626

2727
import static com.oracle.svm.core.heap.RestrictHeapAccess.Access.NO_ALLOCATION;
2828

29-
import com.oracle.svm.core.heap.UnknownPrimitiveField;
3029
import org.graalvm.compiler.api.replacements.Fold;
31-
import org.graalvm.compiler.core.common.NumUtil;
32-
import org.graalvm.compiler.word.Word;
3330
import org.graalvm.nativeimage.ImageSingletons;
3431
import org.graalvm.nativeimage.LogHandler;
3532
import org.graalvm.nativeimage.Platform;
3633
import org.graalvm.nativeimage.Platforms;
37-
import org.graalvm.nativeimage.c.struct.SizeOf;
38-
import org.graalvm.word.UnsignedWord;
3934
import org.graalvm.word.WordFactory;
4035

41-
import com.oracle.svm.core.BuildPhaseProvider.ReadyForCompilation;
4236
import com.oracle.svm.core.SubstrateOptions;
4337
import com.oracle.svm.core.Uninterruptible;
44-
import com.oracle.svm.core.config.ConfigurationValues;
45-
import com.oracle.svm.core.config.ObjectLayout;
38+
import com.oracle.svm.core.BuildPhaseProvider.ReadyForCompilation;
39+
import com.oracle.svm.core.c.CIsolateData;
40+
import com.oracle.svm.core.c.CIsolateDataFactory;
4641
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4742
import com.oracle.svm.core.feature.InternalFeature;
4843
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
4944
import com.oracle.svm.core.heap.RestrictHeapAccess;
45+
5046
import com.oracle.svm.core.heap.UnknownObjectField;
5147
import com.oracle.svm.core.jdk.UninterruptibleUtils;
5248
import com.oracle.svm.core.locks.ClassInstanceReplacer;
@@ -62,8 +58,6 @@
6258
import com.oracle.svm.core.stack.StackOverflowCheck;
6359
import com.oracle.svm.core.thread.VMThreads.SafepointBehavior;
6460

65-
import jdk.vm.ci.meta.JavaKind;
66-
6761
/**
6862
* Support of {@link VMMutex} and {@link VMCondition} in multi-threaded environments. Locking is
6963
* implemented via pthreads.
@@ -81,7 +75,7 @@ protected VMMutex createReplacement(VMMutex source) {
8175
private final ClassInstanceReplacer<VMCondition, VMCondition> conditionReplacer = new ClassInstanceReplacer<>(VMCondition.class) {
8276
@Override
8377
protected VMCondition createReplacement(VMCondition source) {
84-
return new PthreadVMCondition((PthreadVMMutex) mutexReplacer.apply(source.getMutex()));
78+
return new PthreadVMCondition((PthreadVMMutex) mutexReplacer.apply(source.getMutex()), source.getConditionName());
8579
}
8680
};
8781

@@ -100,67 +94,23 @@ public void duringSetup(DuringSetupAccess access) {
10094

10195
@Override
10296
public void beforeCompilation(BeforeCompilationAccess access) {
103-
final int wordSize = ConfigurationValues.getTarget().wordSize;
104-
105-
// `alignment` should actually be: `max(alignof(pthread_mutex_t), alignof(pthread_cond_t))`.
106-
//
107-
// Until `alignof()` can be queried from the C compiler, we hard-code this alignment to:
108-
// - One word on 64-bit architectures.
109-
// - Two words on 32-bit architectures.
110-
//
111-
// This split is arbitrary. Actual alignment requirements depend on the architecture,
112-
// the Pthread library implementation, and the C compiler.
113-
// These hard-coded values will need to be adjusted to higher values if we find out
114-
// that `pthread_mutex_t` or `pthread_cond_t` have higher alignment requirements on some
115-
// particular architecture.
116-
assert wordSize == 8 || wordSize == 4 : "Unsupported architecture bit width";
117-
final int alignment = (wordSize == 8) ? wordSize : (2 * wordSize);
118-
119-
ObjectLayout layout = ConfigurationValues.getObjectLayout();
120-
final int baseOffset = layout.getArrayBaseOffset(JavaKind.Byte);
121-
122-
// Align the first element to word boundary.
123-
int nextIndex = NumUtil.roundUp(baseOffset, alignment) - baseOffset;
124-
12597
PthreadVMMutex[] mutexes = mutexReplacer.getReplacements().toArray(new PthreadVMMutex[0]);
126-
int mutexSize = NumUtil.roundUp(SizeOf.get(Pthread.pthread_mutex_t.class), alignment);
127-
for (PthreadVMMutex mutex : mutexes) {
128-
long offset = layout.getArrayElementOffset(JavaKind.Byte, nextIndex);
129-
assert offset % alignment == 0;
130-
mutex.structOffset = WordFactory.unsigned(offset);
131-
nextIndex += mutexSize;
132-
}
133-
13498
PthreadVMCondition[] conditions = conditionReplacer.getReplacements().toArray(new PthreadVMCondition[0]);
135-
int conditionSize = NumUtil.roundUp(SizeOf.get(Pthread.pthread_cond_t.class), alignment);
136-
for (PthreadVMCondition condition : conditions) {
137-
long offset = layout.getArrayElementOffset(JavaKind.Byte, nextIndex);
138-
assert offset % alignment == 0;
139-
condition.structOffset = WordFactory.unsigned(offset);
140-
nextIndex += conditionSize;
141-
}
14299

143100
PthreadVMLockSupport lockSupport = PthreadVMLockSupport.singleton();
144101
lockSupport.mutexes = mutexes;
145102
lockSupport.conditions = conditions;
146-
lockSupport.pthreadStructs = new byte[nextIndex];
147103
}
148104
}
149105

150106
public final class PthreadVMLockSupport extends VMLockSupport {
151107
/** All mutexes, so that we can initialize them at run time when the VM starts. */
152-
@UnknownObjectField(availability = ReadyForCompilation.class) PthreadVMMutex[] mutexes;
108+
@UnknownObjectField(availability = ReadyForCompilation.class) //
109+
PthreadVMMutex[] mutexes;
153110

154111
/** All conditions, so that we can initialize them at run time when the VM starts. */
155-
@UnknownObjectField(availability = ReadyForCompilation.class) PthreadVMCondition[] conditions;
156-
157-
/**
158-
* Raw memory for the pthread lock structures. Since we know that native image objects are never
159-
* moved, we can safely hand out pointers into the middle of this array to C code. The offset
160-
* into this array is stored in {@link PthreadVMMutex#structOffset} and
161-
* {@link PthreadVMCondition#structOffset}.
162-
*/
163-
@UnknownObjectField(availability = ReadyForCompilation.class) byte[] pthreadStructs;
112+
@UnknownObjectField(availability = ReadyForCompilation.class) //
113+
PthreadVMCondition[] conditions;
164114

165115
@Fold
166116
public static PthreadVMLockSupport singleton() {
@@ -227,17 +177,17 @@ public VMSemaphore[] getSemaphores() {
227177

228178
final class PthreadVMMutex extends VMMutex {
229179

230-
@UnknownPrimitiveField(availability = ReadyForCompilation.class)//
231-
UnsignedWord structOffset;
180+
private final CIsolateData<Pthread.pthread_mutex_t> structPointer;
232181

233182
@Platforms(Platform.HOSTED_ONLY.class)
234183
PthreadVMMutex(String name) {
235184
super(name);
185+
structPointer = CIsolateDataFactory.createStruct("pthreadMutex_" + name, Pthread.pthread_mutex_t.class);
236186
}
237187

238188
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
239189
Pthread.pthread_mutex_t getStructPointer() {
240-
return (Pthread.pthread_mutex_t) Word.objectToUntrackedPointer(PthreadVMLockSupport.singleton().pthreadStructs).add(structOffset);
190+
return structPointer.get();
241191
}
242192

243193
@Override
@@ -280,17 +230,16 @@ public void unlockNoTransitionUnspecifiedOwner() {
280230

281231
final class PthreadVMCondition extends VMCondition {
282232

283-
@UnknownPrimitiveField(availability = ReadyForCompilation.class)//
284-
UnsignedWord structOffset;
233+
private final CIsolateData<Pthread.pthread_cond_t> structPointer;
285234

286-
@Platforms(Platform.HOSTED_ONLY.class)
287-
PthreadVMCondition(PthreadVMMutex mutex) {
288-
super(mutex);
235+
PthreadVMCondition(PthreadVMMutex mutex, String name) {
236+
super(mutex, name);
237+
structPointer = CIsolateDataFactory.createStruct("pthreadCondition_" + getName(), Pthread.pthread_cond_t.class);
289238
}
290239

291240
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
292241
Pthread.pthread_cond_t getStructPointer() {
293-
return (Pthread.pthread_cond_t) Word.objectToUntrackedPointer(PthreadVMLockSupport.singleton().pthreadStructs).add(structOffset);
242+
return structPointer.get();
294243
}
295244

296245
@Override

0 commit comments

Comments
 (0)