Commit fb44fb6c authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: always pass type to mallocgc when allocating scannable memory

We allocate scannable memory w/o type only in few places in runtime.
All these cases are not-performance critical (e.g. G or finq args buffer),
and in long term they all need to go away.
It's not worth it to have special code for this case in mallocgc.
So use special fake "notype" type for such allocations.

LGTM=khr
R=golang-codereviews, khr
CC=golang-codereviews, rlh, rsc
https://golang.org/cl/127450044
parent 9198ed4b
...@@ -21,7 +21,10 @@ MHeap runtime·mheap; ...@@ -21,7 +21,10 @@ MHeap runtime·mheap;
#pragma dataflag NOPTR #pragma dataflag NOPTR
MStats runtime·memstats; MStats runtime·memstats;
static Type* notype;
void runtime·cmallocgc(uintptr size, Type *typ, uint32 flag, void **ret); void runtime·cmallocgc(uintptr size, Type *typ, uint32 flag, void **ret);
void runtime·gc_notype_ptr(Eface*);
void* void*
runtime·mallocgc(uintptr size, Type *typ, uint32 flag) runtime·mallocgc(uintptr size, Type *typ, uint32 flag)
...@@ -31,6 +34,8 @@ runtime·mallocgc(uintptr size, Type *typ, uint32 flag) ...@@ -31,6 +34,8 @@ runtime·mallocgc(uintptr size, Type *typ, uint32 flag)
// Call into the Go version of mallocgc. // Call into the Go version of mallocgc.
// TODO: maybe someday we can get rid of this. It is // TODO: maybe someday we can get rid of this. It is
// probably the only location where we run Go code on the M stack. // probably the only location where we run Go code on the M stack.
if((flag&FlagNoScan) == 0 && typ == nil)
typ = notype;
runtime·cmallocgc(size, typ, flag, &ret); runtime·cmallocgc(size, typ, flag, &ret);
return ret; return ret;
} }
...@@ -124,6 +129,7 @@ runtime·mallocinit(void) ...@@ -124,6 +129,7 @@ runtime·mallocinit(void)
uintptr limit; uintptr limit;
uint64 i; uint64 i;
bool reserved; bool reserved;
Eface notype_eface;
p = nil; p = nil;
p_size = 0; p_size = 0;
...@@ -251,6 +257,9 @@ runtime·mallocinit(void) ...@@ -251,6 +257,9 @@ runtime·mallocinit(void)
// Initialize the rest of the allocator. // Initialize the rest of the allocator.
runtime·MHeap_Init(&runtime·mheap); runtime·MHeap_Init(&runtime·mheap);
g->m->mcache = runtime·allocmcache(); g->m->mcache = runtime·allocmcache();
runtime·gc_notype_ptr(&notype_eface);
notype = notype_eface.type;
} }
void* void*
......
...@@ -225,7 +225,6 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer { ...@@ -225,7 +225,6 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
*xbits |= (bitsPointer << 2) << shift *xbits |= (bitsPointer << 2) << shift
goto marked goto marked
} }
if typ != nil && (uintptr(typ.gc[0])|uintptr(typ.gc[1])) != 0 && uintptr(typ.size) > ptrSize {
if typ.kind&kindGCProg != 0 { if typ.kind&kindGCProg != 0 {
nptr := (uintptr(typ.size) + ptrSize - 1) / ptrSize nptr := (uintptr(typ.size) + ptrSize - 1) / ptrSize
masksize := nptr masksize := nptr
...@@ -270,22 +269,13 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer { ...@@ -270,22 +269,13 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
if te%2 == 0 { if te%2 == 0 {
te /= 2 te /= 2
} }
}
if size == 2*ptrSize {
xbitsb := (*uint8)(add(unsafe.Pointer(xbits), shift/8))
*xbitsb = (bitsPointer << 2) | (bitsPointer << 6) | bitBoundary
goto marked
}
// Copy pointer bitmask into the bitmap. // Copy pointer bitmask into the bitmap.
for i := uintptr(0); i < size0; i += 2 * ptrSize { for i := uintptr(0); i < size0; i += 2 * ptrSize {
v := uint8((bitsPointer << 2) | (bitsPointer << 6)) v := *(*uint8)(add(unsafe.Pointer(ptrmask), ti))
if ptrmask != nil {
v = *(*uint8)(add(unsafe.Pointer(ptrmask), ti))
ti++ ti++
if ti == te { if ti == te {
ti = 0 ti = 0
} }
}
if i == 0 { if i == 0 {
v |= bitBoundary v |= bitBoundary
} }
......
...@@ -19,6 +19,15 @@ func gc_itab_ptr(ret *interface{}) { ...@@ -19,6 +19,15 @@ func gc_itab_ptr(ret *interface{}) {
*ret = (*itab)(nil) *ret = (*itab)(nil)
} }
// Type used for "conservative" allocations in C code.
type notype [8]*byte
// Called from C. Returns the Go type used for C allocations w/o type.
func gc_notype_ptr(ret *interface{}) {
var x notype
*ret = x
}
func timenow() (sec int64, nsec int32) func timenow() (sec int64, nsec int32)
func gc_unixnanotime(now *int64) { func gc_unixnanotime(now *int64) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment