Skip to content

Commit 07d748e

Browse files
committed
bulk release shared finalizers rather than queueing many shared actions
1 parent 3b64523 commit 07d748e

File tree

1 file changed

+39
-11
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime

1 file changed

+39
-11
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.lang.ref.Reference;
4545
import java.lang.ref.ReferenceQueue;
4646
import java.lang.ref.WeakReference;
47+
import java.util.ArrayList;
4748
import java.util.Arrays;
4849
import java.util.concurrent.ConcurrentHashMap;
4950
import java.util.concurrent.ConcurrentMap;
@@ -363,10 +364,10 @@ public final void markReleased() {
363364
* This implements the proper way to free the allocated resources associated with the
364365
* reference.
365366
*/
366-
public abstract AsyncHandler.AsyncAction release();
367+
public abstract AsyncAction release();
367368
}
368369

369-
static class SharedFinalizerErrorCallback implements AsyncHandler.AsyncAction {
370+
static class SharedFinalizerErrorCallback implements AsyncAction {
370371

371372
private final Exception exception;
372373
private final FinalizableReference referece; // problematic reference
@@ -382,6 +383,24 @@ public void execute(PythonContext context) {
382383
}
383384
}
384385

386+
private static final class AsyncActionsList implements AsyncAction {
387+
private final AsyncAction[] array;
388+
389+
public AsyncActionsList(AsyncAction[] array) {
390+
this.array = array;
391+
}
392+
393+
public void execute(PythonContext context) {
394+
for (AsyncAction action : array) {
395+
try {
396+
action.execute(context);
397+
} catch (RuntimeException e) {
398+
ExceptionUtils.printPythonLikeStackTrace(e);
399+
}
400+
}
401+
}
402+
}
403+
385404
/**
386405
* We register the Async action once on the first encounter of a creation of
387406
* {@link FinalizableReference}. This will reduce unnecessary Async thread load when there
@@ -395,17 +414,26 @@ public void registerAsyncAction() {
395414
} catch (InterruptedException e) {
396415
Thread.currentThread().interrupt();
397416
}
398-
if (reference instanceof FinalizableReference) {
399-
FinalizableReference object = (FinalizableReference) reference;
400-
try {
401-
liveReferencesSet.remove(object);
402-
if (object.isReleased()) {
403-
return null;
417+
ArrayList<AsyncAction> actions = new ArrayList<>();
418+
do {
419+
if (reference instanceof FinalizableReference) {
420+
FinalizableReference object = (FinalizableReference) reference;
421+
try {
422+
liveReferencesSet.remove(object);
423+
if (!object.isReleased()) {
424+
AsyncAction action = object.release();
425+
if (action != null) {
426+
actions.add(action);
427+
}
428+
}
429+
} catch (Exception e) {
430+
actions.add(new SharedFinalizerErrorCallback(object, e));
404431
}
405-
return object.release();
406-
} catch (Exception e) {
407-
return new SharedFinalizerErrorCallback(object, e);
408432
}
433+
reference = queue.poll();
434+
} while (reference != null);
435+
if (!actions.isEmpty()) {
436+
return new AsyncActionsList(actions.toArray(new AsyncAction[0]));
409437
}
410438
return null;
411439
});

0 commit comments

Comments
 (0)