Skip to content

Commit 0bb3852

Browse files
committed
Merge pull request 'fibers' (dart-lang#22) from fibers into main
Reviewed-on: http://git.local/dependencies/dart/pulls/22
2 parents 6735573 + 558cffc commit 0bb3852

28 files changed

+1332
-994
lines changed

build-fiber-stress.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
dart compile aot-snapshot --enable-asserts runtime/tests/vm/dart/fiber/fiber_stress.dart

build-fiber-test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
set -e
44

5-
dart --enable_mirrors=true compile aot-snapshot runtime/tests/vm/dart/fiber/fiber_test.dart
5+
dart compile aot-snapshot --enable-asserts runtime/tests/vm/dart/fiber/fiber_test.dart

runtime/tests/vm/dart/fiber/fiber_state_suite.dart

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,80 @@ import 'package:expect/expect.dart';
33

44
final tests = [
55
testRegistry,
6-
testStateLink,
76
testProcessor,
8-
testInvariant,
97
];
108

119
void testRegistry() {
1210
Fiber.launch(() => Expect.equals(2, Fiber.registry.length));
11+
Expect.equals(0, Fiber.registry.length);
12+
13+
Fiber.launch(() {
14+
for (var i = 0; i < 32; i++) {
15+
Fiber.spawn(Fiber.reschedule);
16+
}
17+
Expect.equals(2 + 32, Fiber.registry.length);
18+
19+
var index = 0;
20+
for (var fiber in Fiber.registry) {
21+
Expect.equals(fiber.index, index);
22+
index++;
23+
}
24+
});
25+
Expect.equals(0, Fiber.registry.length);
26+
27+
Fiber.launch(() {
28+
for (var i = 0; i < 65; i++) {
29+
Fiber.spawn(Fiber.reschedule);
30+
}
31+
final currentHash = Fiber.registry.hashCode;
32+
for (var i = 0; i < 65; i++) {
33+
Fiber.reschedule();
34+
}
35+
Expect.notEquals(currentHash, Fiber.registry.hashCode);
36+
});
1337
}
1438

15-
void testStateLink() {}
39+
void testProcessor() {
40+
Expect.isTrue(Fiber.launch(() {}).state.disposed);
41+
Expect.isTrue(Fiber.launch(() => Fiber.spawn(Fiber.reschedule)).state.disposed);
42+
43+
Expect.throws<StateError>(
44+
() => Fiber.launch(() => Fiber.spawn(Fiber.suspend), idle: () {}),
45+
(error) => error.message == "There are no scheduled fibers after idle",
46+
);
1647

17-
void testProcessor() {}
48+
Fiber.launch(() {
49+
final fibers = <Fiber, int>{};
50+
var next = 0;
51+
fibers[Fiber.child(() {
52+
Fiber.reschedule();
53+
Expect.equals(next++, fibers[Fiber.current]);
54+
})] = 0;
55+
fibers[Fiber.child(() {
56+
Fiber.reschedule();
57+
Expect.equals(next++, fibers[Fiber.current]);
58+
})] = 1;
59+
fibers[Fiber.child(() {
60+
Fiber.reschedule();
61+
Expect.equals(next++, fibers[Fiber.current]);
62+
})] = 2;
63+
fibers[Fiber.child(() {
64+
Fiber.reschedule();
65+
Expect.equals(next++, fibers[Fiber.current]);
66+
})] = 3;
67+
fibers[Fiber.child(() {
68+
Fiber.reschedule();
69+
Expect.equals(next++, fibers[Fiber.current]);
70+
})] = 4;
1871

19-
void testInvariant() {}
72+
fibers.forEach((fiber, value) => Fiber.fork(fiber));
73+
74+
Fiber.suspend();
75+
Fiber.suspend();
76+
Fiber.suspend();
77+
Fiber.suspend();
78+
Fiber.suspend();
79+
80+
Expect.equals(5, next);
81+
});
82+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import 'dart:fiber';
2+
import 'dart:typed_data';
3+
4+
void main() {
5+
Fiber.launch(() {
6+
final iterations = 100000;
7+
final delta = iterations * 0.1;
8+
var percents = 0;
9+
for (var i = 0; i < iterations; i++) {
10+
print(i.toString());
11+
Fiber.spawn(work1);
12+
Fiber.spawn(work1);
13+
Fiber.spawn(work1);
14+
15+
Fiber.reschedule();
16+
Fiber.reschedule();
17+
Fiber.reschedule();
18+
}
19+
print("exit");
20+
});
21+
}
22+
23+
@pragma("vm:never-inline")
24+
void work1() {
25+
Fiber.reschedule();
26+
work2();
27+
Fiber.spawn(work2);
28+
}
29+
30+
@pragma("vm:never-inline")
31+
void work2() {
32+
work3();
33+
}
34+
35+
@pragma("vm:never-inline")
36+
void work3() {
37+
work4();
38+
}
39+
40+
@pragma("vm:never-inline")
41+
void work4() {
42+
work5();
43+
}
44+
45+
@pragma("vm:never-inline")
46+
void work5() {
47+
Uint8List.new(1 * 1024 * 1024);
48+
}

runtime/tests/vm/dart/fiber/fiber_stress_suite.dart

Lines changed: 0 additions & 35 deletions
This file was deleted.

runtime/tests/vm/dart/fiber/fiber_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// VMOptions=--coroutines_registry_shrink_capacity=64
2+
13
import 'dart:fiber';
24
import 'dart:async';
35
import 'package:expect/expect.dart';
@@ -16,7 +18,7 @@ final suites = {
1618
"flow": flow.tests,
1719
"exceptions": exceptions.tests,
1820
};
19-
21+
2022
void main(List<String> arguments) {
2123
if (arguments.isEmpty) {
2224
for (var suite in suites.entries) {
@@ -36,7 +38,7 @@ void main(List<String> arguments) {
3638
print("Processing suite: ${arguments[0]}");
3739
for (var test in suite!) {
3840
final function = RegExp(r"Function 'test(.+)'").firstMatch(test.toString())!.group(1);
39-
if (arguments.length == 2 || function == arguments[1].toLowerCase()) {
41+
if (arguments.length == 1 || function!.toLowerCase() == arguments[1].toLowerCase()) {
4042
print("Processing test: test${function}");
4143
test();
4244
print("Test: test${function} finished");

runtime/vm/compiler/backend/il.cc

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8600,43 +8600,9 @@ LocationSummary* CoroutineTransferInstr::MakeLocationSummary(Zone* zone,
86008600
}
86018601

86028602
void CoroutineTransferInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
8603-
const Register kFromCoroutine = CoroutineTransferABI::kFromCoroutineReg;
8604-
const Register kToCoroutine = CoroutineTransferABI::kToCoroutineReg;
8605-
const Register kToStackLimit = CoroutineTransferABI::kToStackLimitReg;
8606-
8607-
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64)
8608-
SPILLS_LR_TO_FRAME({});
8609-
#endif
8610-
__ LoadFieldFromOffset(TMP, kFromCoroutine, Coroutine::attributes_offset());
8611-
__ AndImmediate(TMP, ~Coroutine::CoroutineAttributes::running);
8612-
__ OrImmediate(TMP, Coroutine::CoroutineAttributes::suspended);
8613-
__ StoreFieldToOffset(TMP, kFromCoroutine, Coroutine::attributes_offset());
8614-
8615-
__ LoadFieldFromOffset(TMP, kToCoroutine, Coroutine::attributes_offset());
8616-
__ AndImmediate(TMP, ~Coroutine::CoroutineAttributes::suspended);
8617-
__ OrImmediate(TMP, Coroutine::CoroutineAttributes::running);
8618-
__ StoreFieldToOffset(TMP, kToCoroutine, Coroutine::attributes_offset());
8619-
8620-
__ PushRegister(FPREG);
8621-
__ StoreFieldToOffset(SPREG, kFromCoroutine, Coroutine::stack_base_offset());
8622-
8623-
__ LoadFieldFromOffset(SPREG, kToCoroutine, Coroutine::stack_base_offset());
8624-
__ PopRegister(FPREG);
8625-
if (!FLAG_precompiled_mode) __ RestoreCodePointer();
8626-
if (FLAG_precompiled_mode)
8627-
__ movq(PP, compiler::Address(THR, Thread::global_object_pool_offset()));
8628-
8629-
__ LoadFieldFromOffset(kToStackLimit, kToCoroutine,
8630-
Coroutine::overflow_stack_limit_offset());
8631-
__ StoreToOffset(kToCoroutine, THR, Thread::coroutine_offset());
8632-
__ StoreToOffset(kToStackLimit, THR, Thread::saved_stack_limit_offset());
8633-
8634-
compiler::Label scheduled_interrupts;
8635-
__ LoadFromOffset(TMP, THR, Thread::stack_limit_offset());
8636-
__ testq(TMP, compiler::Immediate(Thread::kInterruptsMask));
8637-
__ BranchIf(ZERO, &scheduled_interrupts);
8638-
__ StoreToOffset(kToStackLimit, THR, Thread::stack_limit_offset());
8639-
__ Bind(&scheduled_interrupts);
8603+
compiler->GenerateStubCall(source(), StubCode::CoroutineTransfer(),
8604+
UntaggedPcDescriptors::kOther, locs(), deopt_id(),
8605+
env());
86408606
}
86418607

86428608
Definition* SuspendInstr::Canonicalize(FlowGraph* flow_graph) {

runtime/vm/compiler/backend/slot.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class ParsedFunction;
9292
V(Coroutine, UntaggedCoroutine, processor, Dynamic, VAR) \
9393
V(Coroutine, UntaggedCoroutine, to_processor_next, Dynamic, VAR) \
9494
V(Coroutine, UntaggedCoroutine, to_processor_previous, Dynamic, VAR) \
95+
V(Coroutine, UntaggedCoroutine, to_state, Dynamic, VAR) \
9596
V(Coroutine, UntaggedCoroutine, caller, Coroutine, VAR) \
9697
V(Coroutine, UntaggedCoroutine, scheduler, Coroutine, VAR) \
9798
V(Coroutine, UntaggedCoroutine, argument, Dynamic, VAR)

0 commit comments

Comments
 (0)