Compare commits

...

6 Commits

Author SHA1 Message Date
deadprogram 559ba98319 all: build/test using Go 1.27-rc3
Signed-off-by: deadprogram <ron@hybridgroup.com>
2026-08-14 11:28:58 -07:00
Damian Gryski c4219439eb runtime: make arrays and struct field hashes order dependent 2026-08-12 12:08:52 -07:00
Konstantin Sharlaimov 7a9c649268 fix(gc): pause all cores before scanning stack and globals.
In gcMarkReachable, busy-wait for other cores to enter the interrupt handler and pause before scanning the GC core's stack or globals. Prevents data race where a running core relocates heap references to globals during mark phase.
2026-08-09 12:11:59 -07:00
Konstantin Sharlaimov 213d10838f fix(gc): correct leaking allocator bounds and overflow checks.
Change heap-end comparison to > to prevent spurious OOM when heapptr exactly matches heapEnd. Add overflow check to prevent heap wrapping.
2026-08-09 12:11:59 -07:00
Konstantin Sharlaimov b573ef3813 fix(gc): correct old size calculation in block realloc.
Using blocksPerStateByte instead of bytesPerBlock caused the old size to be underestimated for multi-block allocations, leading to data truncation on growing reallocations.
2026-08-09 12:11:59 -07:00
Mohammed-Asad-Khan 854f91ecf2 Fix to allow -o flag to point to a directory
Previously, running 'tinygo build -o dist/ file.go' where dist/ already
exists as a directory failed with 'open dist/: is a directory', because
Build() only auto-derived a binary name when outpath was empty, not when
it pointed to an existing directory. This adds that check, matching the
behavior of 'go build -o dir/' with a package.

Note: only handles the case where the directory already exists; if the
directory doesn't exist yet, behavior is unchanged.
2026-08-05 07:17:00 -07:00
9 changed files with 37 additions and 25 deletions
+2 -2
View File
@@ -40,7 +40,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Restore LLVM source cache
uses: actions/cache/restore@v5
@@ -131,7 +131,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Build TinyGo (LLVM ${{ matrix.version }})
run: go install -tags=llvm${{ matrix.version }}
+5 -5
View File
@@ -23,7 +23,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Run go mod tidy
run: go mod tidy
@@ -36,7 +36,7 @@ jobs:
# statically linked binary.
runs-on: ubuntu-latest
container:
image: golang:1.27rc2-alpine
image: golang:1.27rc3-alpine
outputs:
version: ${{ steps.version.outputs.version }}
steps:
@@ -160,7 +160,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Install wasmtime
uses: bytecodealliance/actions/wasmtime/setup@v1
@@ -204,7 +204,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Install Node.js
uses: actions/setup-node@v6
@@ -323,7 +323,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Restore LLVM source cache
uses: actions/cache/restore@v5
+4 -4
View File
@@ -34,7 +34,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Restore cached LLVM source
uses: actions/cache/restore@v5
@@ -129,7 +129,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Download TinyGo build
uses: actions/download-artifact@v8
@@ -150,7 +150,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Download TinyGo build
uses: actions/download-artifact@v8
@@ -176,7 +176,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v6
with:
go-version: '1.27.0-rc.2'
go-version: '1.27.0-rc.3'
cache: true
- name: Download TinyGo build
uses: actions/download-artifact@v8
+2 -2
View File
@@ -1,5 +1,5 @@
# tinygo-llvm stage obtains the llvm source for TinyGo
FROM golang:1.27rc2 AS tinygo-llvm
FROM golang:1.27rc3 AS tinygo-llvm
RUN apt-get update && \
apt-get install -y apt-utils make cmake clang-17 ninja-build && \
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
# tinygo-compiler copies the compiler build over to a base Go container (without
# all the build tools etc).
FROM golang:1.27rc2 AS tinygo-compiler
FROM golang:1.27rc3 AS tinygo-compiler
# Copy tinygo build.
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
+8 -1
View File
@@ -177,8 +177,15 @@ func Build(pkgName, outpath string, config *compileopts.Config) error {
// Pick a default output path based on the main directory.
outpath = filepath.Base(result.MainDir) + config.DefaultBinaryExtension()
}
} else if fi, statErr := os.Stat(outpath); statErr == nil && fi.IsDir() {
var name string
if strings.HasSuffix(pkgName, ".go") {
name = filepath.Base(pkgName[:len(pkgName)-3]) + config.DefaultBinaryExtension()
} else {
name = filepath.Base(result.MainDir) + config.DefaultBinaryExtension()
}
outpath = filepath.Join(outpath, name)
}
if err := os.Rename(result.Binary, outpath); err != nil {
// Moving failed. Do a file copy.
inf, err := os.Open(result.Binary)
+1 -1
View File
@@ -510,7 +510,7 @@ func realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
lastBlock := firstBlock.findHead()
// Calculate the size of the original allocation body.
oldSize := uintptr(lastBlock-firstBlock)*blocksPerStateByte + (bytesPerBlock - unsafe.Sizeof(objHeader{}))
oldSize := uintptr(lastBlock-firstBlock)*bytesPerBlock + (bytesPerBlock - unsafe.Sizeof(objHeader{}))
if size <= oldSize {
// The requested size is less than the old size.
+7 -1
View File
@@ -47,8 +47,14 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
gcTotalAlloc += uint64(size)
gcMallocs++
heapptr += size
for heapptr >= heapEnd {
if heapptr < addr {
// The allocation size overflowed the heap pointer.
runtimePanic("out of memory")
}
for heapptr > heapEnd {
// Try to increase the heap and check again.
// Use > instead of >= because an allocation that exactly
// ends at heapEnd is still within heap boundaries.
if growHeap() {
continue
}
+6 -7
View File
@@ -43,6 +43,12 @@ func gcMarkReachable() {
gcPauseCore(i)
}
// Busy-wait until all the other cores are ready.
for gcScanState.Load() != numCPU {
spinLoopWait()
}
gcScanState.Store(0)
// Scan the stack(s) of the current core.
scanCurrentStack()
if !task.OnSystemStack() {
@@ -53,13 +59,6 @@ func gcMarkReachable() {
// Scan globals.
findGlobals(markRoots)
// Busy-wait until all the other cores are ready. They certainly should be,
// after the scanning we did above.
for gcScanState.Load() != numCPU {
spinLoopWait()
}
gcScanState.Store(0)
// Signal each core in turn that they can scan the stack.
for i := uint32(0); i < numCPU; i++ {
if i == core {
+2 -2
View File
@@ -807,13 +807,13 @@ func hashmapInterfaceHash(itf interface{}, seed uintptr) uint32 {
case reflectlite.Array:
var hash uint32
for i := 0; i < x.Len(); i++ {
hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Index(i)), seed)
hash = (hash * 31) ^ hashmapInterfaceHash(valueInterfaceUnsafe(x.Index(i)), seed)
}
return hash
case reflectlite.Struct:
var hash uint32
for i := 0; i < x.NumField(); i++ {
hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Field(i)), seed)
hash = (hash * 31) ^ hashmapInterfaceHash(valueInterfaceUnsafe(x.Field(i)), seed)
}
return hash
default: