42
42
43
43
import com .oracle .graal .python .PythonLanguage ;
44
44
import com .oracle .graal .python .builtins .objects .cext .hpy .GraalHPyContext ;
45
+ import com .oracle .graal .python .runtime .native_memory .NativeBuffer ;
45
46
import com .oracle .graal .python .runtime .sequence .storage .NativeIntSequenceStorage ;
46
47
import com .oracle .graal .python .runtime .sequence .storage .NativePrimitiveSequenceStorage ;
47
48
import com .oracle .graal .python .util .PythonUtils ;
59
60
public class NativeBufferContext {
60
61
private static final Unsafe unsafe = PythonUtils .initUnsafe ();
61
62
62
- @ CompilationFinal private ReferenceQueue <NativePrimitiveSequenceStorage > referenceQueue ;
63
+ private ReferenceQueue <NativePrimitiveSequenceStorage > referenceQueue ;
63
64
// We need to keep around the references since Phantom References are one way bound
64
65
// Key: MemoryAddr, Value: PhantomReference
65
- private ConcurrentHashMap <Long , NativePrimitiveReference > phantomReferences ;
66
+ private ConcurrentHashMap <NativePrimitiveReference , NativePrimitiveReference > phantomReferences ;
66
67
67
68
private Thread nativeBufferReferenceCleanerThread ;
68
69
@@ -81,37 +82,11 @@ public void initReferenceQueue() {
81
82
}
82
83
}
83
84
84
- public long allocateNativeMemory (long capacityInBytes ) {
85
- assert capacityInBytes >= 0 ;
86
- return unsafe .allocateMemory (capacityInBytes );
87
- }
88
-
89
- public void copyMemory (long fromAddress , long toAddress , long capacityInBytes ) {
90
- assert capacityInBytes >= 0 ;
91
- unsafe .copyMemory (fromAddress , toAddress , capacityInBytes );
92
- }
93
-
94
85
@ TruffleBoundary
95
- public void releaseMemory (long memoryAddr ) {
96
- NativePrimitiveReference ref = phantomReferences .remove (memoryAddr );
97
- ref .release (unsafe );
98
- }
99
-
100
- @ TruffleBoundary
101
- public void setNewValueAddrToStorage (NativePrimitiveSequenceStorage storage , long valueAddr , long capacityInBytes ) {
102
- assert capacityInBytes >= 0 ;
103
- releaseMemory (storage .getValueBufferAddr ());
104
- storage .setValueBufferAddr (valueAddr , capacityInBytes );
86
+ public NativeIntSequenceStorage createNativeIntStorage (NativeBuffer valueBuffer , int length ) {
87
+ var storage = new NativeIntSequenceStorage (valueBuffer , length );
105
88
var phantomRef = new NativePrimitiveReference (storage , getReferenceQueue ());
106
- phantomReferences .put (valueAddr , phantomRef );
107
- }
108
-
109
- @ TruffleBoundary
110
- public NativeIntSequenceStorage wrapToIntStorage (long valueBufferAddr , long capacityInBytes , int length ) {
111
- assert capacityInBytes >= 0 ;
112
- var storage = new NativeIntSequenceStorage (valueBufferAddr , capacityInBytes , length );
113
- var phantomRef = new NativePrimitiveReference (storage , getReferenceQueue ());
114
- phantomReferences .put (storage .getValueBufferAddr (), phantomRef );
89
+ phantomReferences .put (phantomRef , phantomRef );
115
90
116
91
return storage ;
117
92
}
@@ -132,10 +107,10 @@ public void finalizeContext() {
132
107
133
108
public NativeIntSequenceStorage toNativeIntStorage (int [] arr ) {
134
109
long sizeInBytes = (long ) arr .length * (long ) Integer .BYTES ;
135
- long addr = allocateNativeMemory (sizeInBytes );
110
+ NativeBuffer nativeBuffer = NativeBuffer . allocateNew (sizeInBytes );
136
111
137
- unsafe .copyMemory (arr , Unsafe .ARRAY_INT_BASE_OFFSET , null , addr , sizeInBytes );
138
- return wrapToIntStorage ( addr , sizeInBytes , arr .length );
112
+ unsafe .copyMemory (arr , Unsafe .ARRAY_INT_BASE_OFFSET , null , nativeBuffer . getMemoryAddress () , sizeInBytes );
113
+ return createNativeIntStorage ( nativeBuffer , arr .length );
139
114
}
140
115
141
116
private ReferenceQueue <NativePrimitiveSequenceStorage > getReferenceQueue () {
@@ -151,13 +126,11 @@ private ReferenceQueue<NativePrimitiveSequenceStorage> getReferenceQueue() {
151
126
static final class NativeBufferDeallocatorRunnable implements Runnable {
152
127
private static final TruffleLogger LOGGER = GraalHPyContext .getLogger (NativeBufferDeallocatorRunnable .class );
153
128
154
- private static final Unsafe unsafe = PythonUtils .initUnsafe ();
155
-
156
129
private final ReferenceQueue <NativePrimitiveSequenceStorage > referenceQueue ;
157
- private final ConcurrentHashMap <Long , NativePrimitiveReference > references ;
130
+ private final ConcurrentHashMap <NativePrimitiveReference , NativePrimitiveReference > references ;
158
131
159
132
public NativeBufferDeallocatorRunnable (ReferenceQueue <NativePrimitiveSequenceStorage > referenceQueue ,
160
- ConcurrentHashMap <Long , NativePrimitiveReference > references ) {
133
+ ConcurrentHashMap <NativePrimitiveReference , NativePrimitiveReference > references ) {
161
134
this .referenceQueue = referenceQueue ;
162
135
this .references = references ;
163
136
}
@@ -170,8 +143,8 @@ public void run() {
170
143
while (!pythonContext .getThreadState (language ).isShuttingDown ()) {
171
144
try {
172
145
NativePrimitiveReference phantomRef = (NativePrimitiveReference ) referenceQueue .remove ();
173
- phantomRef .release (unsafe );
174
- references .remove (phantomRef . getMemoryAddress () );
146
+ phantomRef .release ();
147
+ references .remove (phantomRef );
175
148
} catch (InterruptedException e ) {
176
149
Thread .currentThread ().interrupt ();
177
150
LOGGER .fine ("Native buffer reference cleaner thread was interrupted and is exiting" );
@@ -184,23 +157,15 @@ public void run() {
184
157
185
158
static final class NativePrimitiveReference extends PhantomReference <NativePrimitiveSequenceStorage > {
186
159
187
- private final long memoryAddress ;
188
- private boolean released = false ;
160
+ private final NativeBuffer buffer ;
189
161
190
162
public NativePrimitiveReference (NativePrimitiveSequenceStorage referent , ReferenceQueue <NativePrimitiveSequenceStorage > q ) {
191
163
super (referent , q );
192
- this .memoryAddress = referent .getValueBufferAddr ();
193
- }
194
-
195
- public void release (Unsafe unsafe ) {
196
- if (!released ) {
197
- unsafe .freeMemory (memoryAddress );
198
- released = true ;
199
- }
164
+ this .buffer = referent .getValueBuffer ();
200
165
}
201
166
202
- public long getMemoryAddress () {
203
- return memoryAddress ;
167
+ public void release () {
168
+ buffer . release () ;
204
169
}
205
170
}
206
171
}
0 commit comments