During codegen we do not yet know the indexes that will be used for
called functions. Therefore, we store the offset into the in-memory
code where the index is needed with a pointer to the Decl and use this
data to insert the proper indexes while writing the binary in the flush
function.
Before this commit the wasm backend worked similarly to elf. As
functions were generated they were written directly to the output file
and existing code was shifted around in the file as necessary. This
approach had several disadvantages:
- Large amounts of padding in the output were necessary to avoid
expensive copying of data within the file.
- Function/type/global/etc indexes were required to be known at the time
of preforming codegen, which severely limited the flexibility of where
code could be placed in the binary
- Significant complexity to track the state of the output file through
incremental updates
This commit takes things in a different direction. Code is incrementally
compiled into in-memory buffers and the entire binary is rewritten using
these buffers on flush. This has several advantages:
- Significantly smaller resulting binaries
- More performant resulting binaries due to lack of indirection
- Significantly simpler compiler code
- Indexes no longer need to be known before codegen. We can track where
Decls must be referenced by index insert the proper indexes while
writing the code in the flush() function. This is not yet implemented
but is planned for the next commit.
The main disadvantage is of course increased memory usage in order to
store these buffers of generated code.
This is a temporary debugging trick you can use to turn segfaults into more helpful
logged error messages with stack trace details. The downside is that every allocation
will be leaked!
This commit write out Mach-O header in the linker's `flush`
method. The header currently only populates the magic number,
filetype, and cpu info.
Signed-off-by: Jakub Konka <kubkon@jakubkonka.com>
I have observed on Linux writing and reading the same file many times
without the mtime changing, despite the file system having nanosecond
granularity (and about 1 millisecond worth of nanoseconds passing between
modifications). I am calling this a Linux Kernel Bug and adding file
size to the cache hash manifest as a mitigation. As evidence, macOS does
not exhibit this behavior.
This means it is possible, on Linux, for a file to be added to the cache
hash, and, if it is updated with the same file size, same inode, within
about 1 millisecond, the cache system will give us a false positive,
saying it is unmodified. I don't see any way to improve this situation
without fixing the bug in the Linux kernel.
closes#6082
* Implemented all R-type arithmetic/logical instructions
* Implemented all I-type arithmetic/logical instructions
* Implemented all load and store instructions
* Implemented all of RV64I except FENCE
I empirically observed mtime not changing when rapidly writing the same
file name within the same millisecond of wall clock time, despite the
mtime field having nanosecond precision.
I believe this fixes the CI test failures.