verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
verifyGCBits(t, ArrayOf(2, Tscalar), empty)
- verifyGCBits(t, TypeOf([100]Xscalar{}), empty)
- verifyGCBits(t, ArrayOf(100, Tscalar), empty)
+ verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
+ verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
- verifyGCBits(t, TypeOf([100]Xptr{}), rep(100, lit(1)))
- verifyGCBits(t, ArrayOf(100, Tptr), rep(100, lit(1)))
+ verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
+ verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
- verifyGCBits(t, TypeOf([100]Xscalarptr{}), rep(100, lit(0, 1)))
- verifyGCBits(t, ArrayOf(100, Tscalarptr), rep(100, lit(0, 1)))
+ verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
+ verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
- verifyGCBits(t, TypeOf([100]Xptrscalar{}), rep(100, lit(1, 0)))
- verifyGCBits(t, ArrayOf(100, Tptrscalar), rep(100, lit(1, 0)))
- verifyGCBits(t, TypeOf([1][100]Xptrscalar{}), rep(100, lit(1, 0)))
- verifyGCBits(t, ArrayOf(1, ArrayOf(100, Tptrscalar)), rep(100, lit(1, 0)))
- verifyGCBits(t, TypeOf([2][100]Xptrscalar{}), rep(200, lit(1, 0)))
- verifyGCBits(t, ArrayOf(2, ArrayOf(100, Tptrscalar)), rep(200, lit(1, 0)))
+ verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
+ verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
+ verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
+ verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
+ verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
+ verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
- verifyGCBits(t, TypeOf((func([100]Xscalarptr))(nil)), lit(1))
- verifyGCBits(t, FuncOf([]Type{ArrayOf(100, Tscalarptr)}, nil, false), lit(1))
+ verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
+ verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
- verifyGCBits(t, TypeOf((map[[100]Xscalarptr]Xscalar)(nil)), lit(1))
- verifyGCBits(t, MapOf(ArrayOf(100, Tscalarptr), Tscalar), lit(1))
+ verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
+ verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
- verifyGCBits(t, TypeOf((*[100]Xscalar)(nil)), lit(1))
- verifyGCBits(t, PtrTo(ArrayOf(100, Tscalar)), lit(1))
+ verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
+ verifyGCBits(t, PtrTo(ArrayOf(10000, Tscalar)), lit(1))
- verifyGCBits(t, TypeOf(([][100]Xscalar)(nil)), lit(1))
- verifyGCBits(t, SliceOf(ArrayOf(100, Tscalar)), lit(1))
+ verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
+ verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
hdr := make([]byte, 8/PtrSize)
verifyGCBits(t, MapBucketOf(Tscalar, Tptr), join(hdr, rep(8, lit(0)), rep(8, lit(1)), lit(1)))
}
}
+// typeBitsBulkBarrier executes writebarrierptr_nostore
+// for every pointer slot in the memory range [p, p+size),
+// using the type bitmap to locate those pointer slots.
+// The type typ must correspond exactly to [p, p+size).
+// This executes the write barriers necessary after a copy.
+// Both p and size must be pointer-aligned.
+// The type typ must have a plain bitmap, not a GC program.
+// The only use of this function is in channel sends, and the
+// 64 kB channel element limit takes care of this for us.
+//
+// Must not be preempted because it typically runs right after memmove,
+// and the GC must not complete between those two.
+//
+//go:nosplit
+func typeBitsBulkBarrier(typ *_type, p, size uintptr) {
+ if typ == nil {
+ throw("runtime: typeBitsBulkBarrier without type")
+ }
+ if typ.size != size {
+ println("runtime: typeBitsBulkBarrier with type ", *typ._string, " of size ", typ.size, " but memory size", size)
+ throw("runtime: invalid typeBitsBulkBarrier")
+ }
+ if typ.kind&kindGCProg != 0 {
+ println("runtime: typeBitsBulkBarrier with type ", *typ._string, " with GC prog")
+ throw("runtime: invalid typeBitsBulkBarrier")
+ }
+ if !writeBarrierEnabled {
+ return
+ }
+ ptrmask := typ.gcdata
+ var bits uint32
+ for i := uintptr(0); i < typ.ptrdata; i += ptrSize {
+ if i&(ptrSize*8-1) == 0 {
+ bits = uint32(*ptrmask)
+ ptrmask = addb(ptrmask, 1)
+ } else {
+ bits = bits >> 1
+ }
+ if bits&1 != 0 {
+ x := (*uintptr)(unsafe.Pointer(p + i))
+ writebarrierptr_nostore(x, *x)
+ }
+ }
+}
+
// The methods operating on spans all require that h has been returned
// by heapBitsForSpan and that size, n, total are the span layout description
// returned by the mspan's layout method.