kernel: Integrate lexical regions
046eddc2e8a03dc1e9cdee94c56fcef61d4d76c08e01648219c38792d564ad1d
1 parent
807886ea
Makefile
+90 -3
| 7 | 7 | TEST_FIXTURE_STD := -pkg std $(patsubst %,-mod %,$(TEST_FIXTURE_STD_LIB)) |
|
| 8 | 8 | ||
| 9 | 9 | # Full standard library with test modules. |
|
| 10 | 10 | STD_TEST := $(STD) $(patsubst %,-mod %,$(shell cat std.lib.test)) |
|
| 11 | 11 | ||
| 12 | + | # Standard library support for tests in another package. |
|
| 13 | + | STD_TEST_SUPPORT := $(STD) -mod lib/std/testing.rad |
|
| 14 | + | ||
| 12 | 15 | # Source files. |
|
| 13 | 16 | STD_LIB := $(shell find lib -name '*.rad') |
|
| 14 | 17 | BIN_DIR := bin |
|
| 15 | 18 | RAD_BIN := $(BIN_DIR)/radiance.rv64.dev |
|
| 16 | 19 | ||
| 17 | 20 | # Emulator command used to invoke the self-hosted compiler. |
|
| 18 | 21 | EMU := $(or $(RAD_EMULATOR),emulator) |
|
| 19 | 22 | EMU_FLAGS := -memory-size=385024 \ |
|
| 20 | 23 | -data-size=348160 \ |
|
| 21 | - | -stack-size=512 \ |
|
| 24 | + | -stack-size=1024 \ |
|
| 22 | 25 | -count-instructions |
|
| 23 | 26 | RADIANCE := $(EMU) $(EMU_FLAGS) -run $(RAD_BIN) |
|
| 24 | 27 | ||
| 25 | 28 | # Verify the emulator binary exists. |
|
| 26 | 29 | EMU_PATH := $(shell command -v $(EMU) 2>/dev/null) |
|
| 27 | 30 | ||
| 28 | 31 | default: emulator $(RAD_BIN) |
|
| 29 | - | test: emulator seed-test std-test bin-test |
|
| 32 | + | test: emulator seed-test std-test bin-test kernel-test package-test machine-test kernel-acceptance kernel-size-check |
|
| 30 | 33 | ||
| 31 | 34 | seed-test: |
|
| 32 | 35 | @seed/test |
|
| 33 | 36 | ||
| 34 | 37 | # Emulator command check |
| 67 | 70 | @rm -f lib/std.test.rv64 \ |
|
| 68 | 71 | lib/std.test.rv64.debug \ |
|
| 69 | 72 | lib/std.test.rv64.s \ |
|
| 70 | 73 | lib/std.test.rv64.o |
|
| 71 | 74 | ||
| 75 | + | # Kernel modules and tests use a separate package and test entry point. |
|
| 76 | + | KERNEL_SRC := kernel/kernel.rad $(shell find kernel/kernel -name '*.rad' ! -name 'tests.rad' ! -path '*/tests/*' 2>/dev/null) |
|
| 77 | + | KERNEL_ASM := kernel/kernel/boot.ras kernel/kernel/sync.ras kernel/kernel/trap.ras kernel/kernel/pages.ras kernel/kernel/loader.ras kernel/kernel/instances.ras kernel/kernel/domains.ras kernel/kernel/dispatch.ras kernel/kernel/calls.ras kernel/kernel/plic.ras |
|
| 78 | + | KERNEL_TEST_SRC := kernel/kernel/tests.rad $(shell find kernel/kernel/tests -name '*.rad' 2>/dev/null) |
|
| 79 | + | KERNEL := -pkg kernel $(patsubst %,-mod %,$(sort $(KERNEL_SRC))) |
|
| 80 | + | KERNEL_TEST := $(BIN_DIR)/kernel.test.rv64 |
|
| 81 | + | ||
| 82 | + | kernel-test: emulator $(KERNEL_TEST) |
|
| 83 | + | @$(EMU) $(EMU_FLAGS) -run $(KERNEL_TEST) |
|
| 84 | + | @sh test/slots/run "$(EMU)" $(STD_TEST_SUPPORT) $(KERNEL) $(patsubst %,-mod %,$(KERNEL_TEST_SRC)) |
|
| 85 | + | ||
| 86 | + | $(KERNEL_TEST): $(KERNEL_SRC) $(KERNEL_TEST_SRC) $(KERNEL_ASM) $(STD_LIB) $(RAD_BIN) |
|
| 87 | + | @echo "radiance kernel tests => $@" |
|
| 88 | + | @$(RADIANCE) -test $(STD_TEST_SUPPORT) $(KERNEL) $(patsubst %,-mod %,$(KERNEL_TEST_SRC) $(KERNEL_ASM)) -entry kernel -o $@ |
|
| 89 | + | ||
| 90 | + | $(BIN_DIR)/kernel.ril $(BIN_DIR)/std.ril &: $(KERNEL_SRC) $(STD_LIB) $(RAD_BIN) |
|
| 91 | + | @$(RADIANCE) $(STD) $(KERNEL) -entry kernel -ril $(BIN_DIR) |
|
| 92 | + | ||
| 93 | + | $(BIN_DIR)/kernel.build.rv64: kernel/tools/build.rad $(STD_LIB) $(RAD_BIN) |
|
| 94 | + | @$(RADIANCE) $(STD) -pkg build -mod $< -entry build -o $@ |
|
| 95 | + | ||
| 96 | + | # User packages share the ABI source through a staged package module tree. |
|
| 97 | + | $(BIN_DIR)/root.ril $(BIN_DIR)/scheduler.ril &: kernel/root.rad kernel/scheduler.rad kernel/mmio.rad kernel/kernel/abi.rad kernel/kernel/sys.rad $(RAD_BIN) |
|
| 98 | + | @mkdir -p $(BIN_DIR)/user/root $(BIN_DIR)/user/scheduler |
|
| 99 | + | @cp kernel/root.rad kernel/scheduler.rad $(BIN_DIR)/user/ |
|
| 100 | + | @cp kernel/kernel/abi.rad kernel/kernel/sys.rad $(BIN_DIR)/user/root/ |
|
| 101 | + | @cp kernel/kernel/abi.rad kernel/kernel/sys.rad kernel/mmio.rad $(BIN_DIR)/user/scheduler/ |
|
| 102 | + | @$(RADIANCE) -pkg root -mod $(BIN_DIR)/user/root.rad -mod $(BIN_DIR)/user/root/abi.rad -mod $(BIN_DIR)/user/root/sys.rad -entry root -ril $(BIN_DIR) |
|
| 103 | + | @$(RADIANCE) -pkg scheduler -mod $(BIN_DIR)/user/scheduler.rad -mod $(BIN_DIR)/user/scheduler/abi.rad -mod $(BIN_DIR)/user/scheduler/sys.rad -mod $(BIN_DIR)/user/scheduler/mmio.rad -entry scheduler -ril $(BIN_DIR) |
|
| 104 | + | ||
| 105 | + | $(BIN_DIR)/kernel.rv64: $(BIN_DIR)/root.ril $(BIN_DIR)/scheduler.ril $(BIN_DIR)/std.ril $(BIN_DIR)/kernel.ril $(BIN_DIR)/kernel.build.rv64 $(KERNEL_ASM) |
|
| 106 | + | @cat $(KERNEL_ASM) > $(BIN_DIR)/kernel.ras |
|
| 107 | + | @$(EMU) $(EMU_FLAGS) -run $(BIN_DIR)/kernel.build.rv64 -- $(BIN_DIR)/std.ril $(BIN_DIR)/kernel.ril $(BIN_DIR)/kernel.ras $@ $(BIN_DIR)/root.ril $(BIN_DIR)/scheduler.ril |
|
| 108 | + | ||
| 109 | + | # Separate binary package emission, linkage, and decode checks. |
|
| 110 | + | package-test: emulator $(BIN_DIR)/packages.check.rv64 $(BIN_DIR)/shared.build.rv64 |
|
| 111 | + | @sh test/packages/run |
|
| 112 | + | @RAD_EMULATOR="$(EMU)" test/shared/run |
|
| 113 | + | ||
| 114 | + | $(BIN_DIR)/packages.check.rv64: test/packages/check.rad $(STD_LIB) $(RAD_BIN) |
|
| 115 | + | @$(RADIANCE) $(STD) -pkg check -mod $< -entry check -o $@ |
|
| 116 | + | ||
| 117 | + | $(BIN_DIR)/native.build.rv64: test/native/build.rad $(STD_LIB) $(RAD_BIN) |
|
| 118 | + | @$(RADIANCE) $(STD) -pkg build -mod $< -entry build -o $@ |
|
| 119 | + | ||
| 120 | + | $(BIN_DIR)/native.fixture.rv64: $(BIN_DIR)/native.build.rv64 |
|
| 121 | + | @$(EMU) -run $< -- $@ |
|
| 122 | + | ||
| 123 | + | $(BIN_DIR)/shared.build.rv64: test/shared/build.rad $(STD_LIB) $(RAD_BIN) |
|
| 124 | + | @$(RADIANCE) $(STD) -pkg build -mod $< -entry build -o $@ |
|
| 125 | + | ||
| 126 | + | # Native architecture and machine-boundary checks. |
|
| 127 | + | machine-test: emulator $(BIN_DIR)/native.fixture.rv64 $(BIN_DIR)/sync.build.rv64 |
|
| 128 | + | @$(EMU) -machine -run $(BIN_DIR)/native.fixture.rv64 |
|
| 129 | + | @RAD_EMULATOR="$(EMU)" test/sync/run |
|
| 130 | + | @RAD_EMULATOR="$(EMU)" sh test/trap/run |
|
| 131 | + | @RAD_EMULATOR="$(EMU)" sh test/pages/run |
|
| 132 | + | ||
| 133 | + | $(BIN_DIR)/sync.build.rv64: test/sync/build.rad $(STD_LIB) $(RAD_BIN) |
|
| 134 | + | @$(RADIANCE) $(STD) -pkg build -mod $< -entry build -o $@ |
|
| 135 | + | ||
| 72 | 136 | # Binary Tests |
|
| 73 | 137 | ||
| 74 | 138 | BIN_TEST_DIR := test/tests |
|
| 75 | 139 | # Only tests with `//! returns:` are compiled to binaries and executed. |
|
| 76 | 140 | BIN_TEST_EXE_SRC := $(shell grep -rl '^//! returns:' $(BIN_TEST_DIR)) |
| 130 | 194 | clean: clean-std-test clean-bin-test clean-rad |
|
| 131 | 195 | ||
| 132 | 196 | t: test |
|
| 133 | 197 | c: clean |
|
| 134 | 198 | ||
| 135 | - | .PHONY: test clean default seed-test std-test bin-test seed \ |
|
| 199 | + | .PHONY: test clean default seed-test std-test bin-test kernel-test package-test machine-test kernel-acceptance \ |
|
| 200 | + | kernel-size-check acceptance seed \ |
|
| 136 | 201 | clean-std-test clean-bin-test clean-rad emulator |
|
| 137 | 202 | .SUFFIXES: |
|
| 138 | 203 | .DELETE_ON_ERROR: |
|
| 139 | 204 | .SILENT: |
|
| 205 | + | ||
| 206 | + | # Full-kernel scenarios that require native execution or distinct fixture images. |
|
| 207 | + | kernel-acceptance: emulator $(RAD_BIN) $(BIN_DIR)/kernel.build.rv64 $(BIN_DIR)/kernel.rv64 |
|
| 208 | + | @RAD_EMULATOR="$(EMU)" sh test/boot/run |
|
| 209 | + | @RAD_EMULATOR="$(EMU)" sh test/loader/run |
|
| 210 | + | @RAD_EMULATOR="$(EMU)" sh test/dispatch/run |
|
| 211 | + | @RAD_EMULATOR="$(EMU)" sh test/dispatch/run smp "1 2 8" 7 |
|
| 212 | + | @RAD_EMULATOR="$(EMU)" sh test/dispatch/run termination |
|
| 213 | + | @RAD_EMULATOR="$(EMU)" sh test/runtime/run |
|
| 214 | + | @RAD_EMULATOR="$(EMU)" sh test/bootstrap/run |
|
| 215 | + | @RAD_EMULATOR="$(EMU)" sh test/dispatch/run mmio |
|
| 216 | + | @RAD_EMULATOR="$(EMU)" sh test/cycles/run |
|
| 217 | + | @RAD_EMULATOR="$(EMU)" sh test/scheduling/run |
|
| 218 | + | ||
| 219 | + | # Physical source-line limits and fixed native image memory. |
|
| 220 | + | .PHONY: kernel-size-check |
|
| 221 | + | kernel-size-check: $(BIN_DIR)/kernel.rv64 |
|
| 222 | + | @python3 test/acceptance/sizes |
|
| 223 | + | ||
| 224 | + | # Full sibling-emulator validation with retained acceptance reports. |
|
| 225 | + | acceptance: |
|
| 226 | + | @sh test/acceptance/run |
kernel/kernel/backing.rad
+6 -8
| 76 | 76 | set store.used = object.index + 1; |
|
| 77 | 77 | } |
|
| 78 | 78 | set store.records[object.index].run = run; |
|
| 79 | 79 | set store.records[object.index].pages = 1; |
|
| 80 | 80 | set store.records[object.index].exposed = 1; |
|
| 81 | - | let mut bits = bitset::init(&mut store.records[object.index].exposures[..]); |
|
| 82 | - | bitset::put(&mut bits, origin.index); |
|
| 81 | + | bitset::clearAll(&mut store.records[object.index].exposures[..]); |
|
| 82 | + | bitset::put(&mut store.records[object.index].exposures[..], origin.index); |
|
| 83 | 83 | return try! slots::commit(&mut store.slots[..], reservation); |
|
| 84 | 84 | } |
|
| 85 | 85 | ||
| 86 | 86 | /// Require a live generation-bearing backing reference. |
|
| 87 | 87 | fn require(store: &Store, object: abi::Ref) throws (abi::Error) { |
| 106 | 106 | export unsafe fn expose(store: &mut Store, object: abi::Ref, domain: abi::Ref) throws (abi::Error) { |
|
| 107 | 107 | try require(store, object); |
|
| 108 | 108 | if store.records[object.index].pages == 0 or not domainLive(store, domain) { |
|
| 109 | 109 | throw abi::Error::BadHandle; |
|
| 110 | 110 | } |
|
| 111 | - | let mut bits = bitset::new(&mut store.records[object.index].exposures[..]); |
|
| 112 | - | if bitset::contains(&bits, domain.index) { |
|
| 111 | + | if bitset::contains(&store.records[object.index].exposures[..], domain.index) { |
|
| 113 | 112 | return; |
|
| 114 | 113 | } |
|
| 115 | - | bitset::put(&mut bits, domain.index); |
|
| 114 | + | bitset::put(&mut store.records[object.index].exposures[..], domain.index); |
|
| 116 | 115 | set store.records[object.index].exposed += 1; |
|
| 117 | 116 | } |
|
| 118 | 117 | ||
| 119 | 118 | /// Reclaim only when no page object and no domain exposure remains. |
|
| 120 | 119 | fn reclaim(store: &mut Store, object: abi::Ref, release: fn(&mut frames::Pool, frames::Run) throws (abi::Error)) { |
| 169 | 168 | let next = first + count; |
|
| 170 | 169 | for i in first..next { |
|
| 171 | 170 | if store.slots[i].state <> slots::State::Live { |
|
| 172 | 171 | continue; |
|
| 173 | 172 | } |
|
| 174 | - | let mut bits = bitset::new(&mut store.records[i].exposures[..]); |
|
| 175 | - | if not bitset::contains(&bits, domain.index) { |
|
| 173 | + | if not bitset::contains(&store.records[i].exposures[..], domain.index) { |
|
| 176 | 174 | continue; |
|
| 177 | 175 | } |
|
| 178 | - | bitset::clear(&mut bits, domain.index); |
|
| 176 | + | bitset::clear(&mut store.records[i].exposures[..], domain.index); |
|
| 179 | 177 | set store.records[i].exposed -= 1; |
|
| 180 | 178 | reclaim(store, abi::Ref { index: i, generation: store.slots[i].generation }, release); |
|
| 181 | 179 | } |
|
| 182 | 180 | if next < store.used { |
|
| 183 | 181 | set store.ending[domain.index] = next + 1; |
kernel/tools/build.rad
+4 -2
| 96 | 96 | emit::loadImm(&mut e, rv64::A3, ro as i64); |
|
| 97 | 97 | emit::loadImm(&mut e, rv64::A4, count as i64); |
|
| 98 | 98 | emit::loadImm(&mut e, rv64::T0, kernel as i64); |
|
| 99 | 99 | emit::emit(&mut e, encode::jalr(rv64::ZERO, rv64::T0, 0)); |
|
| 100 | 100 | assert e.codeLen <= 1024; |
|
| 101 | - | for word, i in emit::getCode(&e) { |
|
| 102 | - | set NATIVE[i] = word; |
|
| 101 | + | let codeEmitter: 'code = &e in { |
|
| 102 | + | for word, i in emit::getCode 'code (codeEmitter) { |
|
| 103 | + | set NATIVE[i] = word; |
|
| 104 | + | } |
|
| 103 | 105 | } |
|
| 104 | 106 | } |
|
| 105 | 107 | ||
| 106 | 108 | /// Link shared boot packages, retain their catalog, and instantiate the kernel graph. |
|
| 107 | 109 | @default unsafe fn main(env: *sys::Env) -> i32 { |
test/modules/run
deleted
+0 -21
| 1 | - | #!/bin/sh |
|
| 2 | - | # Resolve and execute references beyond module index 127. |
|
| 3 | - | set -eu |
|
| 4 | - | emulator=${RAD_EMULATOR:-emulator} |
|
| 5 | - | work=$(mktemp -d) |
|
| 6 | - | trap 'rm -rf "$work"' EXIT HUP INT TERM |
|
| 7 | - | mkdir "$work/capacity" |
|
| 8 | - | set -- -pkg capacity -mod "$work/capacity.rad" |
|
| 9 | - | index=0 |
|
| 10 | - | while [ "$index" -lt 127 ]; do |
|
| 11 | - | printf 'export mod m%s;\n' "$index" >> "$work/capacity.rad" |
|
| 12 | - | printf '/// Return this module index.\nexport fn value() -> u64 { return %s; }\n' "$index" > "$work/capacity/m$index.rad" |
|
| 13 | - | set -- "$@" -mod "$work/capacity/m$index.rad" |
|
| 14 | - | index=$((index + 1)) |
|
| 15 | - | done |
|
| 16 | - | printf 'use capacity::m126;\n/// Check a package root beyond module index 127.\n@default fn main() -> u64 { assert m126::value() == 126; return 0; }\n' > "$work/entry.rad" |
|
| 17 | - | set -- "$@" -pkg entry -mod "$work/entry.rad" |
|
| 18 | - | "$emulator" -memory-size=385024 -data-size=348160 -stack-size=1024 \ |
|
| 19 | - | -run bin/radiance.rv64.dev "$@" -entry entry -o "$work/capacity.rv64" |
|
| 20 | - | "$emulator" -run "$work/capacity.rv64" |
|
| 21 | - | printf 'module scopes: references beyond index 127 passed\n' |
test/native/build.rad
+1 -1
| 74 | 74 | }, |
|
| 75 | 75 | ]; |
|
| 76 | 76 | unsafe static symbols: [data::DataSym; 2] = undefined; |
|
| 77 | 77 | let mut ro: [u8; 8] = [0; 8]; |
|
| 78 | 78 | let mut rw: [u8; 8] = [0; 8]; |
|
| 79 | - | let result = try! rv64::finishProgram(&mut generator, globals, |
|
| 79 | + | let result = try! rv64::finishProgram(generator, globals, |
|
| 80 | 80 | rv64::Storage { dataSyms: &mut symbols[..], dataSymEntries: &mut ENTRIES[..] }, |
|
| 81 | 81 | &[], &mut ro[..], &mut rw[..]); |
|
| 82 | 82 | let header = try! image::header(result.layout); |
|
| 83 | 83 | let code = @sliceOf(result.code.ptr as *u8, result.code.len * 4); |
|
| 84 | 84 | let fd = unix::openOpts(env.args[1], unix::OpenFlags(*unix::O_WRONLY | *unix::O_CREAT | *unix::O_TRUNC), 420); |
test/shared/build.rad
+4 -2
| 133 | 133 | } |
|
| 134 | 134 | for i in 0..TEXT.len { |
|
| 135 | 135 | set TEXT[i] = encode::nop(); |
|
| 136 | 136 | } |
|
| 137 | 137 | assert e.codeLen <= 1024; |
|
| 138 | - | for word, i in emit::getCode(&e) { |
|
| 139 | - | set TEXT[i] = word; |
|
| 138 | + | let codeEmitter: 'code = &e in { |
|
| 139 | + | for word, i in emit::getCode 'code (codeEmitter) { |
|
| 140 | + | set TEXT[i] = word; |
|
| 141 | + | } |
|
| 140 | 142 | } |
|
| 141 | 143 | for package, i in &catalog[..] { |
|
| 142 | 144 | assert package.code.len <= 1024; |
|
| 143 | 145 | for word, j in package.code { |
|
| 144 | 146 | set TEXT[1024 + i * 1024 + j] = word; |