]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: factor object dumping code out of greyobject
authorAustin Clements <austin@google.com>
Thu, 12 Mar 2015 18:26:04 +0000 (14:26 -0400)
committerAustin Clements <austin@google.com>
Tue, 17 Mar 2015 01:46:35 +0000 (01:46 +0000)
When checkmark fails, greyobject dumps both the object that pointed to
the unmarked object and the unmarked object. This code cluttered up
greyobject, was copy-pasted for the two objects, and the copy for
dumping the unmarked object was not entirely correct.

Extract object dumping out to a new function. This declutters
greyobject and fixes the bugs in dumping the unmarked object. The new
function is slightly cleaned up from the original code to have more
natural control flow and shows a marker on the field in the base
object that points to the unmarked object to make it easy to find.

Change-Id: Ib51318a943f50b0b99995f0941d03ee8876b9fcf
Reviewed-on: https://go-review.googlesource.com/7506
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/mgcmark.go

index 5d3a9efbb3d7b7bee53804a5892101eec38031be..4a3cc4d769f06561dd4f14af903a2f27d4e7ce03 100644 (file)
@@ -522,45 +522,16 @@ func greyobject(obj, base, off uintptr, hbits heapBits, gcw *gcWorkProducer) {
 
        if useCheckmark {
                if !hbits.isMarked() {
+                       printlock()
                        print("runtime:greyobject: checkmarks finds unexpected unmarked object obj=", hex(obj), "\n")
                        print("runtime: found obj at *(", hex(base), "+", hex(off), ")\n")
 
                        // Dump the source (base) object
-
-                       kb := base >> _PageShift
-                       xb := kb
-                       xb -= mheap_.arena_start >> _PageShift
-                       sb := h_spans[xb]
-                       printlock()
-                       print("runtime:greyobject Span: base=", hex(base), " kb=", hex(kb))
-                       if sb == nil {
-                               print(" sb=nil\n")
-                       } else {
-                               print(" sb.start*_PageSize=", hex(sb.start*_PageSize), " sb.limit=", hex(sb.limit), " sb.sizeclass=", sb.sizeclass, " sb.elemsize=", sb.elemsize, "\n")
-                               // base is (a pointer to) the source object holding the reference to object. Create a pointer to each of the fields
-                               // fields in base and print them out as hex values.
-                               for i := 0; i < int(sb.elemsize/ptrSize); i++ {
-                                       print(" *(base+", i*ptrSize, ") = ", hex(*(*uintptr)(unsafe.Pointer(base + uintptr(i)*ptrSize))), "\n")
-                               }
-                       }
+                       gcDumpObject("base", base, off)
 
                        // Dump the object
+                       gcDumpObject("obj", obj, ^uintptr(0))
 
-                       k := obj >> _PageShift
-                       x := k
-                       x -= mheap_.arena_start >> _PageShift
-                       s := h_spans[x]
-                       print("runtime:greyobject Span: obj=", hex(obj), " k=", hex(k))
-                       if s == nil {
-                               print(" s=nil\n")
-                       } else {
-                               print(" s.start=", hex(s.start*_PageSize), " s.limit=", hex(s.limit), " s.sizeclass=", s.sizeclass, " s.elemsize=", s.elemsize, "\n")
-                               // NOTE(rsc): This code is using s.sizeclass as an approximation of the
-                               // number of pointer-sized words in an object. Perhaps not what was intended.
-                               for i := 0; i < int(s.sizeclass); i++ {
-                                       print(" *(obj+", i*ptrSize, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + uintptr(i)*ptrSize))), "\n")
-                               }
-                       }
                        throw("checkmark found unmarked object")
                }
                if !hbits.isCheckmarked() {
@@ -595,6 +566,28 @@ func greyobject(obj, base, off uintptr, hbits heapBits, gcw *gcWorkProducer) {
        gcw.put(obj)
 }
 
+// gcDumpObject dumps the contents of obj for debugging and marks the
+// field at byte offset off in obj.
+func gcDumpObject(label string, obj, off uintptr) {
+       k := obj >> _PageShift
+       x := k
+       x -= mheap_.arena_start >> _PageShift
+       s := h_spans[x]
+       print(label, "=", hex(obj), " k=", hex(k))
+       if s == nil {
+               print(" s=nil\n")
+               return
+       }
+       print(" s.start*_PageSize=", hex(s.start*_PageSize), " s.limit=", hex(s.limit), " s.sizeclass=", s.sizeclass, " s.elemsize=", s.elemsize, "\n")
+       for i := uintptr(0); i < s.elemsize; i += ptrSize {
+               print(" *(", label, "+", i, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + uintptr(i)))))
+               if i == off {
+                       print(" <==")
+               }
+               print("\n")
+       }
+}
+
 // When in GCmarkterminate phase we allocate black.
 //go:nowritebarrier
 func gcmarknewobject_m(obj uintptr) {