builder: run interp per package

This results in a significant speedup in some cases. For example, this
runs over twice as fast with a warm cache:

    tinygo build -o test.elf ./testdata/stdlib.go

This should help a lot with edit-compile-test cycles, that typically
only modify a single package.

This required some changes to the interp package to deal with globals
created in a previous run of the interp package and to deal with
external globals (that can't be loaded from or stored to).
This commit is contained in:
Ayke van Laethem
2021-03-29 23:51:56 +02:00
committed by Ron Evans
parent 35bf0746a1
commit 312f5d3833
5 changed files with 188 additions and 10 deletions
+15 -1
View File
@@ -548,6 +548,13 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
continue
}
result := mem.load(ptr, uint32(size))
if result == nil {
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
if err != nil {
return nil, mem, err
}
continue
}
if r.debug {
fmt.Fprintln(os.Stderr, indent+"load:", ptr, "->", result)
}
@@ -570,7 +577,14 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if r.debug {
fmt.Fprintln(os.Stderr, indent+"store:", val, ptr)
}
mem.store(val, ptr)
ok := mem.store(val, ptr)
if !ok {
// Could not store the value, do it at runtime.
err := r.runAtRuntime(fn, inst, locals, &mem, indent)
if err != nil {
return nil, mem, err
}
}
case llvm.Alloca:
// Alloca normally allocates some stack memory. In the interpreter,
// it allocates a global instead.