Closed twitchyliquid64 closed 5 years ago
Merging #105 into master will decrease coverage by
3.14%
. The diff coverage is63.02%
.
@@ Coverage Diff @@
## master #105 +/- ##
==========================================
- Coverage 68.9% 65.76% -3.15%
==========================================
Files 33 40 +7
Lines 3345 3867 +522
==========================================
+ Hits 2305 2543 +238
- Misses 783 1058 +275
- Partials 257 266 +9
Impacted Files | Coverage Δ | |
---|---|---|
exec/internal/compile/compile.go | 0% <0%> (ø) |
|
exec/internal/compile/scanner.go | 0% <0%> (ø) |
|
wasm/operators/op.go | 75% <0%> (ø) |
:arrow_up: |
exec/func.go | 76% <100%> (+0.48%) |
:arrow_up: |
exec/internal/compile/native_exec.go | 100% <100%> (ø) |
|
exec/native_compile_nogae.go | 100% <100%> (ø) |
|
exec/native_compile.go | 65.9% <65.9%> (ø) |
|
exec/vm.go | 85.01% <71.42%> (-1.76%) |
:arrow_down: |
exec/internal/compile/amd64.go | 79.5% <79.5%> (ø) |
|
exec/internal/compile/allocator.go | 81.81% <81.81%> (ø) |
|
... and 7 more |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update a76146c...b8b6d63. Read the comment docs.
On second thought, hold off on reviewing this. I need to think about a better way to structure this.
@sbinet, can you look at this and give me your thoughts? I'm not done, but getting close. This PR is mostly boilerplate, but usefully implements AOT compilation for i64.const
, i64.add
, & i64.sub
.
Changes to the disasm
package to track the encoded size of each instruction it reads. I'm not using this anymore, but the code + tests are written. Let me know if you want me to leave it in or delete the code.
Changes to exec/exec_test.go
to run each test suite twice - once with AOT compilation disabled & once enabled, all in parallel.
Changes to exec/internal/compile/compile.go
to track instruction metadata and jump targets. Compile()
now additionally returns a compile.BytecodeMetadata
object to track information about the compiled bytecode. I use it a little now (mostly to avoid the overhead I would otherwise need to disassemble again), but it will be really invaluable for when we implement a JIT (as opposed to just AOT).
Changes to exec/func.go
: A slice of emitted native code sections is kept for each function (compiledFunction.asm
).
exec/internal/compile/allocator.go
: Implements a naive executable page allocator. I know this is very leaky for the moment.
exec/internal/compile/amd64.go
: Implements the backend for the amd64 architecture. This is very simplistic ATM and only supports 3 opcodes, but this is a good start. There are lots of easy optimizations we can make here too - tracking if a register already has stack information or what would be pushed to the stack is a good start. Peephole optimizations and dead-instruction deletion would also be great too.
exec/internal/compile/amd64_test.go
: Test suite for the amd64 backend. Of particular note is the TestSliceMemoryLayoutAMD64
function, which confirms that the memory layout of the slice (which is critical for the emitted instructions to work).
exec/internal/compile/scanner.go
: Implements a generic scanner which any backend can use. This calculates heuristics about the instructions (used for deciding whether to native-compile them or not, not very useful now but will be for a JIT) as well as working out which subsets have only instructions which are fully supported by the backend.
exec/native_compile.go
: Abstracts access to the native backend, as well as having the main logic for AOT compilation & actually executing native code.
wasm/operators/wagon_internal.go
: I've added a new interpreter opcode to symbolize execution of a sequence of native code.
Ive addressed the comments, PTAL.
Friendly ping @sbinet :)
Done :) PTAL.
Apologies for the additional commit - I was intending for that to be a different PR, but I found a few bugs that shouldn't be left out of this PR (off-by-one in the return instruction pointer, double-allocation/overrun for vm.context.stack
).
Friendly ping @sbinet :)
Let me know if there's anything I can do to move this along. If you would like me to split some of this into separate PRs, (like the scanner in one and the execution in another) I can try. Let me know :)
Apologies for the sluggish answers. (I am on the road to the dotGo conference...)
If you can split some PRs off, then yes, by all means: smaller bites are great :)
No worries at all :) I'm sorry for being pushy, just trying to get this in before my excitement shifts to other ideas.
I'll go ahead and split this into 2-3 different PRs, and close this one.
Thanks, and enjoy dotGo! Say hi to Dave for me :smile:
This PR lays the boilerplate for supporting AOT & JIT compilation.
Use one of the unassigned opcodes to signal to the interpreter to execute a native code section. Modify the disassembler to throw an error if this opcode is used, so any collision years down the line is detected & can be trivially fixed.
Implement interfaces to abstract different stages, specifically:
sequenceScanner
)pageAllocator
)instructionBuilder
)[]asmBlock
index. Any remaining opcodes are set toops.Unreachable
- as we dont plan to emit asm where there are inbound branches in the middle (yet), this should crash out in the event of any bugs that jump into the recompiled section.Tests for integration between the different interfaces & structures in
VM
/compiledFunction
.