From 731beb5cd5a5405ae99add41b5e943fbca881a8c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 13 Mar 2019 18:47:30 +0300 Subject: [PATCH] Fix bugs in threading in C backend --- .../java/org/teavm/classlib/java/lang/TThread.java | 4 ++-- .../java/org/teavm/model/optimization/Inlining.java | 12 +++++++++--- .../src/main/java/org/teavm/runtime/EventQueue.java | 13 +++++++++++-- core/src/main/java/org/teavm/runtime/Fiber.java | 9 ++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 670509fd6..fe49701d6 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -190,8 +190,8 @@ public class TThread extends TObject implements TRunnable { @Async public static native void sleep(long millis) throws TInterruptedException; - private static void sleep(long millis, final AsyncCallback callback) { - final TThread current = currentThread(); + private static void sleep(long millis, AsyncCallback callback) { + TThread current = currentThread(); SleepHandler handler = new SleepHandler(current, callback); if (PlatformDetector.isLowLevel()) { handler.scheduleId = EventQueue.offer(handler, System.currentTimeMillis() + millis); diff --git a/core/src/main/java/org/teavm/model/optimization/Inlining.java b/core/src/main/java/org/teavm/model/optimization/Inlining.java index 0d6339504..69cacdaf6 100644 --- a/core/src/main/java/org/teavm/model/optimization/Inlining.java +++ b/core/src/main/java/org/teavm/model/optimization/Inlining.java @@ -58,6 +58,7 @@ import org.teavm.model.util.BasicBlockMapper; import org.teavm.model.util.InstructionVariableMapper; import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.TransitionExtractor; +import org.teavm.runtime.Fiber; public class Inlining { private IntArrayList depthsByBlock; @@ -177,7 +178,7 @@ public class Inlining { if (step == null) { return false; } - List plan = buildPlan(program, -1, step); + List plan = buildPlan(program, -1, step, method); if (plan.isEmpty()) { return false; } @@ -328,7 +329,7 @@ public class Inlining { execPlan(program, planEntry.innerPlan, firstInlineBlock.getIndex()); } - private List buildPlan(Program program, int depth, InliningStep step) { + private List buildPlan(Program program, int depth, InliningStep step, MethodReference method) { List plan = new ArrayList<>(); int originalDepth = depth; @@ -355,6 +356,11 @@ public class Inlining { continue; } + if (invoke.getMethod().getClassName().equals(Fiber.class.getName()) + != method.getClassName().equals(Fiber.class.getName())) { + continue; + } + MethodReader invokedMethod = getMethod(invoke.getMethod()); if (invokedMethod == null || invokedMethod.getProgram() == null || invokedMethod.getProgram().basicBlockCount() == 0 @@ -376,7 +382,7 @@ public class Inlining { entry.targetBlock = block.getIndex(); entry.targetInstruction = insn; entry.program = invokedProgram; - entry.innerPlan.addAll(buildPlan(invokedProgram, depth + 1, innerStep)); + entry.innerPlan.addAll(buildPlan(invokedProgram, depth + 1, innerStep, invokedMethod.getReference())); entry.depth = depth; entry.method = invokedMethod.getReference(); plan.add(entry); diff --git a/core/src/main/java/org/teavm/runtime/EventQueue.java b/core/src/main/java/org/teavm/runtime/EventQueue.java index f8bbb6ff6..eb36ec316 100644 --- a/core/src/main/java/org/teavm/runtime/EventQueue.java +++ b/core/src/main/java/org/teavm/runtime/EventQueue.java @@ -64,7 +64,7 @@ public final class EventQueue { } public static void process() { - while (!finished) { + while (size > 0 && !finished) { next(); } } @@ -86,7 +86,16 @@ public final class EventQueue { } private static void remove(int index) { - Node item = data[size - 1]; + --size; + if (index < size) { + data[index] = data[size]; + update(index); + } + data[size] = null; + } + + private static void update(int index) { + Node item = data[index]; while (true) { int left = index * 2 + 1; int right = left + 1; diff --git a/core/src/main/java/org/teavm/runtime/Fiber.java b/core/src/main/java/org/teavm/runtime/Fiber.java index fabaa2b3d..9ba5a71c2 100644 --- a/core/src/main/java/org/teavm/runtime/Fiber.java +++ b/core/src/main/java/org/teavm/runtime/Fiber.java @@ -211,12 +211,7 @@ public class Fiber { } static void startMain() { - start(() -> { - runMain(); - if (!current().isSuspending()) { - EventQueue.stop(); - } - }); + start(Fiber::runMain); } static native void runMain(); @@ -228,7 +223,7 @@ public class Fiber { current = former; } - private void resume() { + void resume() { state = STATE_RESUMING; start(); }