]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/cgocheck.go
runtime: implement experiment to replace heap bitmap with alloc headers
[gostls13.git] / src / runtime / cgocheck.go
index ec5734a5c7c1126af56fe9f62ea3a8ca233e2318..3d6de4f855dc335ea699dc8dcf79ee157c78fcbd 100644 (file)
@@ -9,6 +9,7 @@ package runtime
 
 import (
        "internal/goarch"
+       "internal/goexperiment"
        "unsafe"
 )
 
@@ -176,16 +177,29 @@ func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
        }
 
        // src must be in the regular heap.
-
-       hbits := heapBitsForAddr(uintptr(src), size)
-       for {
-               var addr uintptr
-               if hbits, addr = hbits.next(); addr == 0 {
-                       break
+       if goexperiment.AllocHeaders {
+               tp := s.typePointersOf(uintptr(src), size)
+               for {
+                       var addr uintptr
+                       if tp, addr = tp.next(uintptr(src) + size); addr == 0 {
+                               break
+                       }
+                       v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
+                       if cgoIsGoPointer(v) && !isPinned(v) {
+                               throw(cgoWriteBarrierFail)
+                       }
                }
-               v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
-               if cgoIsGoPointer(v) && !isPinned(v) {
-                       throw(cgoWriteBarrierFail)
+       } else {
+               hbits := heapBitsForAddr(uintptr(src), size)
+               for {
+                       var addr uintptr
+                       if hbits, addr = hbits.next(); addr == 0 {
+                               break
+                       }
+                       v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
+                       if cgoIsGoPointer(v) && !isPinned(v) {
+                               throw(cgoWriteBarrierFail)
+                       }
                }
        }
 }