diff --git a/compiler/compiler.go b/compiler/compiler.go index aad5e0d9..53086478 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -152,6 +152,7 @@ type builder struct { phis []phiNode deferPtr llvm.Value deferFrame llvm.Value + stackChainAlloca llvm.Value landingpad llvm.BasicBlock difunc llvm.Metadata dilocals map[*types.Var]llvm.Metadata @@ -1226,6 +1227,13 @@ func (b *builder) createFunctionStart(intrinsic bool) { // them. b.deferInitFunc() } + + if b.NeedsStackObjects { + // Create a dummy alloca that will be used in runtime.trackPointer. + // It is necessary to pass a dummy alloca to runtime.trackPointer + // because runtime.trackPointer is replaced by an alloca store. + b.stackChainAlloca = b.CreateAlloca(b.ctx.Int8Type(), "stackalloc") + } } // createFunction builds the LLVM IR implementation for this function. The diff --git a/compiler/gc.go b/compiler/gc.go index 6aa0b45a..0fd6f5aa 100644 --- a/compiler/gc.go +++ b/compiler/gc.go @@ -84,7 +84,7 @@ func (b *builder) trackPointer(value llvm.Value) { if value.Type() != b.i8ptrType { value = b.CreateBitCast(value, b.i8ptrType, "") } - b.createRuntimeCall("trackPointer", []llvm.Value{value}, "") + b.createRuntimeCall("trackPointer", []llvm.Value{value, b.stackChainAlloca}, "") } // typeHasPointers returns whether this type is a pointer or contains pointers. diff --git a/compiler/llvm.go b/compiler/llvm.go index 0dddb330..33c6603e 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -136,11 +136,7 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value { llvm.Undef(b.i8ptrType), // unused context parameter }, "") if b.NeedsStackObjects { - trackPointer := b.mod.NamedFunction("runtime.trackPointer") - b.CreateCall(trackPointer.GlobalValueType(), trackPointer, []llvm.Value{ - packedHeapAlloc, - llvm.Undef(b.i8ptrType), // unused context parameter - }, "") + b.trackPointer(packedHeapAlloc) } packedAlloc := b.CreateBitCast(packedHeapAlloc, llvm.PointerType(packedType, 0), "") diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll index 4daf7b7c..52a638db 100644 --- a/compiler/testdata/basic.ll +++ b/compiler/testdata/basic.ll @@ -12,7 +12,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -196,8 +196,9 @@ entry: define hidden void @main.foo(ptr %context) unnamed_addr #1 { entry: %complit = alloca %main.kv.0, align 8 + %stackalloc = alloca i8, align 1 store %main.kv.0 zeroinitializer, ptr %complit, align 8 - call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %complit, ptr nonnull %stackalloc, ptr undef) #2 call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef) ret void } @@ -206,8 +207,9 @@ entry: define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 { entry: %b1 = alloca %main.kv.0, align 8 + %stackalloc = alloca i8, align 1 store %main.kv.0 zeroinitializer, ptr %b1, align 8 - call void @runtime.trackPointer(ptr nonnull %b1, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %b1, ptr nonnull %stackalloc, ptr undef) #2 store %main.kv.0 %b, ptr %b1, align 8 ret void } diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll index 8f4ed74e..6fdb1407 100644 --- a/compiler/testdata/channel.ll +++ b/compiler/testdata/channel.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -58,7 +58,8 @@ define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr % entry: %complit = alloca {}, align 8 %chan.blockedList = alloca %runtime.channelBlockedList, align 8 - call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #3 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr nonnull %complit, ptr nonnull %stackalloc, ptr undef) #3 call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList) call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3 call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList) diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index 2acc2ed4..38ccc9d3 100644 --- a/compiler/testdata/float.ll +++ b/compiler/testdata/float.ll @@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { diff --git a/compiler/testdata/func.ll b/compiler/testdata/func.ll index 227e52c1..2df92345 100644 --- a/compiler/testdata/func.ll +++ b/compiler/testdata/func.ll @@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll index 4044ae72..a59a546f 100644 --- a/compiler/testdata/gc.ll +++ b/compiler/testdata/gc.ll @@ -27,7 +27,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -38,17 +38,18 @@ entry: ; Function Attrs: nounwind define hidden void @main.newScalar(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %new = call ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new, ptr @main.scalar1, align 4 %new1 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new1, ptr @main.scalar2, align 4 %new2 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new2, ptr @main.scalar3, align 4 %new3 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new3, ptr @main.scalar4, align 4 ret void } @@ -56,14 +57,15 @@ entry: ; Function Attrs: nounwind define hidden void @main.newArray(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %new = call ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new, ptr @main.array1, align 4 %new1 = call ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new1, ptr @main.array2, align 4 %new2 = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new2, ptr @main.array3, align 4 ret void } @@ -71,17 +73,18 @@ entry: ; Function Attrs: nounwind define hidden void @main.newStruct(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %new = call ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new, ptr @main.struct1, align 4 %new1 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new1, ptr @main.struct2, align 4 %new2 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new2, ptr @main.struct3, align 4 %new3 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #2 store ptr %new3, ptr @main.struct4, align 4 ret void } @@ -89,26 +92,28 @@ entry: ; Function Attrs: nounwind define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %new = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %new } ; Function Attrs: nounwind define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %makeslice = call ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #2 store ptr %makeslice, ptr @main.slice1, align 8 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8 %makeslice1 = call ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #2 store ptr %makeslice1, ptr @main.slice2, align 8 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8 %makeslice3 = call ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #2 store ptr %makeslice3, ptr @main.slice3, align 8 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4 store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8 @@ -118,13 +123,14 @@ entry: ; Function Attrs: nounwind define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2 store double %v.r, ptr %0, align 8 %.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1 store double %v.i, ptr %.repack1, align 8 %1 = insertvalue %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:complex128" to i32), ptr undef }, ptr %0, 1 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2 ret %runtime._interface %1 } diff --git a/compiler/testdata/go1.20.ll b/compiler/testdata/go1.20.ll index fc66b47c..16e8904c 100644 --- a/compiler/testdata/go1.20.ll +++ b/compiler/testdata/go1.20.ll @@ -7,7 +7,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -18,13 +18,15 @@ entry: ; Function Attrs: nounwind define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %s.data, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %s.data } ; Function Attrs: nounwind define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = icmp slt i16 %len, 0 %1 = icmp eq ptr %ptr, null %2 = icmp ne i16 %len, 0 @@ -36,7 +38,7 @@ unsafe.String.next: ; preds = %entry %5 = zext i16 %len to i32 %6 = insertvalue %runtime._string undef, ptr %ptr, 0 %7 = insertvalue %runtime._string %6, i32 %5, 1 - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret %runtime._string %7 unsafe.String.throw: ; preds = %entry @@ -49,7 +51,8 @@ declare void @runtime.unsafeSlicePanic(ptr) #0 ; Function Attrs: nounwind define hidden ptr @main.unsafeStringData(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %s.data, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %s.data } diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll index 280f216a..0f38e181 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -64,13 +64,14 @@ entry: ; Function Attrs: nounwind define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8 - call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #8 store i32 3, ptr %n, align 4 - call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 - call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr nonnull %stackalloc, ptr undef) #8 %0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8 store i32 5, ptr %0, align 4 %1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 store ptr %n, ptr %1, align 4 @@ -103,8 +104,9 @@ declare void @runtime.printint32(i32, ptr) #0 ; Function Attrs: nounwind define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8 store i32 5, ptr %0, align 4 %1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 store ptr %fn.context, ptr %1, align 4 @@ -154,8 +156,9 @@ declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0 ; Function Attrs: nounwind define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8 store ptr %itf.value, ptr %0, align 4 %1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1 store ptr @"main$string", ptr %1, align 4 diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll index 38d4e567..2ddaf4ec 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -23,7 +23,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -34,21 +34,24 @@ entry: ; Function Attrs: nounwind define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr null, ptr undef) #6 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr null, ptr undef) #6 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr null, ptr undef) #6 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null } } @@ -57,7 +60,8 @@ declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #2 ; Function Attrs: nounwind define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr null, ptr undef) #6 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null } } @@ -116,9 +120,10 @@ declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{b ; Function Attrs: nounwind define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6 %1 = extractvalue %runtime._string %0, 0 - call void @runtime.trackPointer(ptr %1, ptr undef) #6 + call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._string %0 } diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index 9bc8bd35..ac1a4bc7 100644 --- a/compiler/testdata/pointer.ll +++ b/compiler/testdata/pointer.ll @@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -22,52 +22,58 @@ entry: ; Function Attrs: nounwind define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %x, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } ; Function Attrs: nounwind define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %x, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } ; Function Attrs: nounwind define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %x, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } ; Function Attrs: nounwind define hidden ptr @main.pointerUnsafeGEPFixedOffset(ptr dereferenceable_or_null(1) %ptr, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 %0 = getelementptr inbounds i8, ptr %ptr, i32 10 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %0 } ; Function Attrs: nounwind define hidden ptr @main.pointerUnsafeGEPByteOffset(ptr dereferenceable_or_null(1) %ptr, i32 %offset, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 %0 = getelementptr inbounds i8, ptr %ptr, i32 %offset - call void @runtime.trackPointer(ptr %0, ptr undef) #2 - call void @runtime.trackPointer(ptr %0, ptr undef) #2 + call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2 + call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %0 } ; Function Attrs: nounwind define hidden ptr @main.pointerUnsafeGEPIntOffset(ptr dereferenceable_or_null(4) %ptr, i32 %offset, ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + %stackalloc = alloca i8, align 1 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 %0 = shl i32 %offset, 2 %1 = getelementptr inbounds i8, ptr %ptr, i32 %0 - call void @runtime.trackPointer(ptr %1, ptr undef) #2 - call void @runtime.trackPointer(ptr %1, ptr undef) #2 + call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2 + call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %1 } diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index c49c83bd..00c619d5 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -12,7 +12,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 56e40f5f..01410e50 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { @@ -46,8 +46,9 @@ declare void @runtime.lookupPanic(ptr) #0 ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %varargs = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %varargs, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #2 store i32 1, ptr %varargs, align 4 %0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1 store i32 2, ptr %0, align 4 @@ -60,7 +61,7 @@ entry: %2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0 %3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1 %4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2 - call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2 + call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %4 } @@ -69,6 +70,7 @@ declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #2 %append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0 %append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1 @@ -76,7 +78,7 @@ entry: %0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0 %1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1 %2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2 - call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2 + call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %2 } @@ -92,6 +94,7 @@ declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %slice.maxcap = icmp slt i32 %len, 0 br i1 %slice.maxcap, label %slice.throw, label %slice.next @@ -100,7 +103,7 @@ slice.next: ; preds = %entry %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 - call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %2 slice.throw: ; preds = %entry @@ -113,6 +116,7 @@ declare void @runtime.slicePanic(ptr) #0 ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %slice.maxcap = icmp slt i32 %len, 0 br i1 %slice.maxcap, label %slice.throw, label %slice.next @@ -122,7 +126,7 @@ slice.next: ; preds = %entry %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 - call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %2 slice.throw: ; preds = %entry @@ -133,6 +137,7 @@ slice.throw: ; preds = %entry ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %slice.maxcap = icmp ugt i32 %len, 1431655765 br i1 %slice.maxcap, label %slice.throw, label %slice.next @@ -142,7 +147,7 @@ slice.next: ; preds = %entry %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 - call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %2 slice.throw: ; preds = %entry @@ -153,6 +158,7 @@ slice.throw: ; preds = %entry ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %slice.maxcap = icmp ugt i32 %len, 1073741823 br i1 %slice.maxcap, label %slice.throw, label %slice.next @@ -162,7 +168,7 @@ slice.next: ; preds = %entry %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 - call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %2 slice.throw: ; preds = %entry @@ -173,17 +179,19 @@ slice.throw: ; preds = %entry ; Function Attrs: nounwind define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = getelementptr i8, ptr %p, i32 %len - call void @runtime.trackPointer(ptr %0, ptr undef) #2 + call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %0 } ; Function Attrs: nounwind define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = trunc i64 %len to i32 %1 = getelementptr i8, ptr %p, i32 %0 - call void @runtime.trackPointer(ptr %1, ptr undef) #2 + call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %1 } @@ -206,8 +214,9 @@ declare void @runtime.sliceToArrayPointerPanic(ptr) #0 ; Function Attrs: nounwind define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %makeslice = call ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 - call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2 + call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #2 br i1 false, label %slicetoarray.throw, label %slicetoarray.next slicetoarray.next: ; preds = %entry @@ -220,6 +229,7 @@ slicetoarray.throw: ; preds = %entry ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = icmp ugt i32 %len, 1073741823 %1 = icmp eq ptr %ptr, null %2 = icmp ne i32 %len, 0 @@ -231,7 +241,7 @@ unsafe.Slice.next: ; preds = %entry %5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 %6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1 %7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2 - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %7 unsafe.Slice.throw: ; preds = %entry @@ -244,6 +254,7 @@ declare void @runtime.unsafeSlicePanic(ptr) #0 ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = icmp eq ptr %ptr, null %1 = icmp ne i16 %len, 0 %2 = and i1 %0, %1 @@ -254,7 +265,7 @@ unsafe.Slice.next: ; preds = %entry %4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 %5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1 %6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2 - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %6 unsafe.Slice.throw: ; preds = %entry @@ -265,6 +276,7 @@ unsafe.Slice.throw: ; preds = %entry ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = icmp ugt i64 %len, 1073741823 %1 = icmp eq ptr %ptr, null %2 = icmp ne i64 %len, 0 @@ -277,7 +289,7 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 %7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2 - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %8 unsafe.Slice.throw: ; preds = %entry @@ -288,6 +300,7 @@ unsafe.Slice.throw: ; preds = %entry ; Function Attrs: nounwind define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { entry: + %stackalloc = alloca i8, align 1 %0 = icmp ugt i64 %len, 1073741823 %1 = icmp eq ptr %ptr, null %2 = icmp ne i64 %len, 0 @@ -300,7 +313,7 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 %7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2 - call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret { ptr, i32, i32 } %8 unsafe.Slice.throw: ; preds = %entry diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index bd3b8f5a..e6491e23 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind define hidden void @main.init(ptr %context) unnamed_addr #1 { diff --git a/src/runtime/gc_stack_portable.go b/src/runtime/gc_stack_portable.go index 871f1c61..ab921a99 100644 --- a/src/runtime/gc_stack_portable.go +++ b/src/runtime/gc_stack_portable.go @@ -53,7 +53,7 @@ func markStack() { // trackPointer is a stub function call inserted by the compiler during IR // construction. Calls to it are later replaced with regular stack bookkeeping // code. -func trackPointer(ptr unsafe.Pointer) +func trackPointer(ptr, alloca unsafe.Pointer) // swapStackChain swaps the stack chain. // This is called from internal/task when switching goroutines.