The algorithm now checks for invalid UTF-8 sequences, which is required
by the Go spec.
This gets the tests of the unicode/utf8 package to pass.
Also add bytes.Equal for Go 1.11, which again is necessary for the
unicode/utf8 package.
There were a few problems with the go/packages package. While it is more
or less designed for our purpose, it didn't work quite well as it didn't
provide access to indirectly imported packages (most importantly the
runtime package). This led to a workaround that sometimes broke
`tinygo test`.
This PR contains a number of related changes:
* It uses `go list` directly to retrieve the list of packages/files to
compile, instead of relying on the go/packages package.
* It replaces our custom TestMain replace code with the standard code
for running tests (generated by `go list`).
* It adds a dummy runtime/pprof package and modifies the testing
package, to get tests to run again with the code generated by
`go list`.
This is only very minimal support. More support (such as tinygo flash,
or peripheral access) should be added in later commits, to keep this one
focused.
Importantly, this commit changes the LLVM repo from llvm/llvm-project to
tinygo-org/llvm-project. This provides a little bit of versioning in
case something changes in the Espressif fork. If we want to upgrade to
LLVM 11 it's easy to switch back to llvm/llvm-project until Espressif
has updated their fork.
This is a big change that will determine the stack size for many
goroutines automatically. Functions that aren't recursive and don't call
function pointers can in many cases have an automatically determined
worst case stack size. This is useful, as the stack size is usually much
lower than the previous hardcoded default of 1024 bytes: somewhere
around 200-500 bytes is common.
A side effect of this change is that the default stack sizes (including
the stack size for other architectures such as AVR) can now be changed
in the config JSON file, making it tunable per application.
This reduces current consumption from 500-1000µA to very low (<10µA)
current consumption. This change is important for battery powered
devices, especially devices that may be running for long periods of
time.
Call Frame Information is stored in the .debug_frame section and is used
by debuggers for unwinding. For assembly, this information is not known.
Debuggers will normally use heuristics to figure out the parent function
in the absence of call frame information.
This usually works fine, but is not enough for determining stack sizes.
Instead, I hardcoded the stack size information in
stacksize/stacksize.go, which is somewhat fragile. This change uses CFI
assembly directives to store this information instead of hardcoding it.
This change also fixes the following error message that would appear in
GDB:
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
More information on CFI:
* https://sourceware.org/binutils/docs/as/CFI-directives.html
* https://www.imperialviolet.org/2017/01/18/cfi.html
For now, this is just an extra flag that can be used to print stack
frame information, but this is intended to provide a way to determine
stack sizes for goroutines at compile time in many cases.
Stack sizes are often somewhere around 350 bytes so are in fact not all
that big usually. Once this can be determined at compile time in many
cases, it is possible to use this information when available and as a
result increase the fallback stack size if the size cannot be determined
at compile time. This should reduce stack overflows while at the same
time reducing RAM consumption in many cases.
Interesting output for testdata/channel.go:
function stack usage (in bytes)
Reset_Handler 332
.Lcommand-line-arguments.fastreceiver 220
.Lcommand-line-arguments.fastsender 192
.Lcommand-line-arguments.iterator 192
.Lcommand-line-arguments.main$1 184
.Lcommand-line-arguments.main$2 200
.Lcommand-line-arguments.main$3 200
.Lcommand-line-arguments.main$4 328
.Lcommand-line-arguments.receive 176
.Lcommand-line-arguments.selectDeadlock 72
.Lcommand-line-arguments.selectNoOp 72
.Lcommand-line-arguments.send 184
.Lcommand-line-arguments.sendComplex 192
.Lcommand-line-arguments.sender 192
.Lruntime.run$1 548
This shows that the stack size (if these numbers are correct) can in
fact be determined automatically in many cases, especially for small
goroutines. One of the great things about Go is lightweight goroutines,
and reducing stack sizes is very important to make goroutines
lightweight on microcontrollers.
- Fix UART & putChar
- Timer-based sleep
- Enable systick in abort
- Buffered, interrupt-based UART TX
- Use the new interrupt API and fix sleepTicks
- Make pins behave more like other boards
- Use the MCU's UART numbering
- Allow interrupts to wake the scheduler (#1214)
Commit fc4857e98c (runtime: avoid recursion in printuint64 function)
caused a regression for AVR. I have tried locally with LLVM 11 (which
contains a number of codegen bugs) and the issue is no longer present,
so I'm assuming it's a codegen bug that is now fixed. However, LLVM 11
is not yet released so it seems best to me to work around this
temporarily (for the next few months).
This commit can easily be reverted when we start using LLVM 11.
Previously, chansend and chanrecv allocated a heap object before blocking on a channel.
This object was used to implement a linked list of goroutines blocked on the channel.
The chansend and chanrecv now instead accept a buffer to store this object in as an argument.
The compiler now creates a stack allocation for this object and passes it in.
This commit refactors both determining the current time and sleeping for
a given time. It also improves precision for many chips.
* The nrf chips had a long-standing TODO comment about a slightly
inaccurate clock. This should now be fixed.
* The SAM D2x/D5x chips may have a slightly more accurate clock,
although probably within the error margin of the RTC. Also, by
working with RTC ticks and converting in the least number of places,
code size is often slightly reduced (usually just a few bytes, up to
around 1kB in some cases).
* I believe the HiFive1 rev B timer was slightly wrong (32768Hz vs
30517.6Hz). Because the datasheet says the clock runs at 32768Hz,
I've used the same conversion code here as in the nrf and sam cases.
* I couldn't test both stm32 timers, so I kept them as they currently
are. It may be possible to make them more efficient by using the
native tick frequency instead of using microseconds everywhere.
Previously, we implemented individual bytealg functions via linknaming, and had to update them every once in a while when we hit linker errors.
Instead, this change reimplements the bytealg package in pure Go.
If something is missing, it will cause a compiler error rather than a linker error.
This is easier to test and maintain.