// Copyright 2017 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocore

import (
	"iter"
	"math/bits"

	"golang.org/x/debug/internal/core"
)

// An Object represents a single reachable object in the Go heap.
// Unreachable (garbage) objects are not represented as Objects.
type Object core.Address

// markObjects finds all the live objects in the heap and marks them
// in the p.heapInfo mark fields.
func (p *Process) markObjects() {
	ptrSize := p.proc.PtrSize()

	// number of live objects found so far
	n := 0
	// total size of live objects
	var live int64

	var q []Object

	// Function to call when we find a new pointer.
	add := func(x core.Address) {
		h := p.heap.get(x)
		if h == nil { // not in heap or not in a valid span
			// Invalid spans can happen with intra-stack pointers.
			return
		}
		// Round down to object start.
		x = h.base.Add(x.Sub(h.base) / h.size * h.size)
		// Object start may map to a different info. Reload heap info.
		h = p.heap.get(x)
		// Find mark bit
		b := uint64(x) % heapInfoSize / 8
		if h.mark&(uint64(1)<<b) != 0 { // already found
			return
		}
		h.mark |= uint64(1) << b
		n++
		live += h.size
		q = append(q, Object(x))
	}

	// Start with scanning all the roots.
	// Note that we don't just use the DWARF roots, just in case DWARF isn't complete.
	// Instead we use exactly what the runtime uses.

	// BUG: If the process dumps core with a thread in mallocgc at the point
	// where an object is reachable from the stack but it hasn't been zeroed
	// yet, it's possible for us to observe stale pointers in a goroutine stack
	// frame and follow them.
	//
	// Not a huge deal given that we'll just ignore outright bad pointers, but
	// we may accidentally mark some objects as live erroneously.
	p.ForEachRoot(func(r *Root) bool {
		p.forEachRootPtr(r, func(_ int64, ptr core.Address) bool {
			add(ptr)
			return true
		})
		return true
	})

	// Expand root set to all reachable objects.
	for len(q) > 0 {
		x := q[len(q)-1]
		q = q[:len(q)-1]

		// Scan object for pointers.
		size := p.Size(x)
		for i := int64(0); i < size; i += ptrSize {
			a := core.Address(x).Add(i)
			if p.isPtrFromHeap(a) {
				add(p.proc.ReadPtr(a))
			}
		}
	}

	p.nObj = n

	// Initialize firstIdx fields in the heapInfo, for fast object index lookups.
	n = 0
	p.ForEachObject(func(x Object) bool {
		h := p.heap.get(p.Addr(x))
		if h.firstIdx == -1 {
			h.firstIdx = n
		}
		n++
		return true
	})
	if n != p.nObj {
		panic("object count wrong")
	}

	// Update stats to include the live/garbage distinction.
	allocSize := p.Stats().Sub("heap", "in use spans", "alloc").Value
	p.Stats().Sub("heap", "in use spans").setChild(
		groupStat("alloc",
			leafStat("live", live),
			leafStat("garbage", allocSize-live),
		),
	)
}

// isPtrFromHeap reports whether the inferior at address a contains a pointer.
// a must be somewhere in the heap.
func (p *Process) isPtrFromHeap(a core.Address) bool {
	return p.heap.get(a).isPtr(a, p.proc.PtrSize())
}

// IsPtr reports whether the inferior at address a contains a pointer.
func (p *Process) IsPtr(a core.Address) bool {
	h := p.heap.get(a)
	if h != nil {
		return h.isPtr(a, p.proc.PtrSize())
	}
	for _, m := range p.modules {
		for _, s := range [2]string{"data", "bss"} {
			min := core.Address(m.r.Field(s).Uintptr())
			max := core.Address(m.r.Field("e" + s).Uintptr())
			if a < min || a >= max {
				continue
			}
			gc := m.r.Field("gc" + s + "mask").Field("bytedata").Address()
			i := a.Sub(min) / p.proc.PtrSize()
			return p.proc.ReadUint8(gc.Add(i/8))>>uint(i%8)&1 != 0
		}
	}
	// Everywhere else can't be a pointer. At least, not a pointer into the Go heap.
	// TODO: stacks?
	// TODO: finalizers?
	return false
}

// FindObject finds the object containing a.  Returns that object and the offset within
// that object to which a points.
// Returns 0,0 if a doesn't point to a live heap object.
func (p *Process) FindObject(a core.Address) (Object, int64) {
	// Round down to the start of an object.
	h := p.heap.get(a)
	if h == nil {
		// Not in Go heap, or in a span
		// that doesn't hold Go objects (freed, stacks, ...)
		return 0, 0
	}
	x := h.base.Add(a.Sub(h.base) / h.size * h.size)
	// Check if object is marked.
	h = p.heap.get(x)
	if h.mark>>(uint64(x)%heapInfoSize/8)&1 == 0 { // free or garbage
		return 0, 0
	}
	return Object(x), a.Sub(x)
}

func (p *Process) findObjectIndex(a core.Address) (int, int64) {
	x, off := p.FindObject(a)
	if x == 0 {
		return -1, 0
	}
	h := p.heap.get(core.Address(x))
	return h.firstIdx + bits.OnesCount64(h.mark&(uint64(1)<<(uint64(x)%heapInfoSize/8)-1)), off
}

// ForEachObject calls fn with each object in the Go heap.
// If fn returns false, ForEachObject returns immediately.
func (p *Process) ForEachObject(fn func(x Object) bool) {
	for a, h := range p.heap.all() {
		m := h.mark
		for m != 0 {
			j := bits.TrailingZeros64(m)
			m &= m - 1
			x := Object(a + core.Address(j*8))
			if !fn(x) {
				return
			}
		}
	}
}

// ForEachRoot calls fn with each garbage collection root.
// If fn returns false, ForEachRoot returns immediately.
func (p *Process) ForEachRoot(fn func(r *Root) bool) {
	for _, r := range p.globals {
		if !fn(r) {
			return
		}
	}
	for _, g := range p.goroutines {
		for _, f := range g.frames {
			for _, r := range f.roots {
				if !fn(r) {
					return
				}
			}
		}
	}
}

// Addr returns the starting address of x.
func (p *Process) Addr(x Object) core.Address {
	return core.Address(x)
}

// Size returns the size of x in bytes.
func (p *Process) Size(x Object) int64 {
	return p.heap.get(core.Address(x)).size
}

// Type returns the type and repeat count for the object x.
// x contains at least repeat copies of the returned type.
func (p *Process) Type(x Object) (*Type, int64) {
	p.typeHeap()

	i, _ := p.findObjectIndex(core.Address(x))
	return p.types[i].t, p.types[i].r
}

// ForEachPtr calls fn for all heap pointers it finds in x.
// It calls fn with:
//
//	the offset of the pointer slot in x
//	the pointed-to object y
//	the offset in y where the pointer points.
//
// If fn returns false, ForEachPtr returns immediately.
// For an edge from an object to its finalizer, the first argument
// passed to fn will be -1. (TODO: implement)
func (p *Process) ForEachPtr(x Object, fn func(int64, Object, int64) bool) {
	size := p.Size(x)
	for i := int64(0); i < size; i += p.proc.PtrSize() {
		a := core.Address(x).Add(i)
		if !p.isPtrFromHeap(a) {
			continue
		}
		ptr := p.proc.ReadPtr(a)
		y, off := p.FindObject(ptr)
		if y != 0 {
			if !fn(i, y, off) {
				return
			}
		}
	}
}

// ForEachRootPtr behaves like ForEachPtr but it starts with a Root instead of an Object.
func (p *Process) ForEachRootPtr(r *Root, fn func(int64, Object, int64) bool) {
	p.forEachRootPtr(r, func(off int64, ptr core.Address) bool {
		dst, off2 := p.FindObject(ptr)
		if dst != 0 {
			if !fn(off, dst, off2) {
				return false
			}
		}
		return true
	})
}

// forEachRootPtr walks all the pointers of the root, even if they don't point to
// a valid object.
func (p *Process) forEachRootPtr(r *Root, fn func(int64, core.Address) bool) {
	ptrBuf := make([]byte, 8)
	walkRootTypePtrs(p, r, ptrBuf, 0, r.Type, fn)
}

const heapInfoSize = 512

// Information for heapInfoSize bytes of heap.
type heapInfo struct {
	base     core.Address // start of the span containing this heap region
	size     int64        // size of objects in the span
	mark     uint64       // 64 mark bits, one for every 8 bytes
	firstIdx int          // the index of the first object that starts in this region, or -1 if none
	// For 64-bit inferiors, ptr[0] contains 64 pointer bits, one
	// for every 8 bytes.  On 32-bit inferiors, ptr contains 128
	// pointer bits, one for every 4 bytes.
	ptr [2]uint64
}

func (h *heapInfo) isPtr(a core.Address, ptrSize int64) bool {
	if ptrSize == 8 {
		i := uint(a%heapInfoSize) / 8
		return h.ptr[0]>>i&1 != 0
	}
	i := a % heapInfoSize / 4
	return h.ptr[i/64]>>(i%64)&1 != 0
}

type heapTableID uint64

func (id heapTableID) addr() core.Address {
	return core.Address(id * heapInfoSize * heapTableSize)
}

type heapTable struct {
	table   map[heapTableID]*heapTableEntry
	entries []heapTableID
	ptrSize uint64
}

func heapTableIndex(a core.Address) (heapTableID, uint64) {
	return heapTableID(a / heapInfoSize / heapTableSize), uint64(a / heapInfoSize % heapTableSize)
}

// Heap info structures cover 9 bits of address.
// A page table entry covers 20 bits of address (1MB).
const heapTableSize = 1 << 11

type heapTableEntry [heapTableSize]heapInfo

func (ht *heapTable) setIsPointer(a core.Address) {
	h := ht.getOrCreate(a)
	ptrSize := ht.ptrSize
	if ptrSize == 8 {
		i := uint64(a%heapInfoSize) / 8
		h.ptr[0] |= uint64(1) << i
		return
	}
	i := uint64(a%heapInfoSize) / 4
	h.ptr[i/64] |= uint64(1) << (i % 64)
}

// get returns the heap info for an address. Returns nil
// if a is not a heap address.
func (ht *heapTable) get(a core.Address) *heapInfo {
	k, i := heapTableIndex(a)
	t := ht.table[k]
	if t == nil {
		return nil
	}
	h := &t[i]
	if h.base == 0 {
		return nil
	}
	return h
}

// getOrCreate returns the heap info for an address, or if nil,
// creates it, marking it as a heap address.
func (ht *heapTable) getOrCreate(a core.Address) *heapInfo {
	k, i := heapTableIndex(a)
	t := ht.table[k]
	if t == nil {
		t = new(heapTableEntry)
		for j := 0; j < heapTableSize; j++ {
			t[j].firstIdx = -1
		}
		ht.table[k] = t
		ht.entries = append(ht.entries, k)
	}
	return &t[i]
}

func (ht *heapTable) all() iter.Seq2[core.Address, *heapInfo] {
	return func(yield func(core.Address, *heapInfo) bool) {
		for _, k := range ht.entries {
			e := ht.table[k]
			for i := range e {
				h := &e[i]
				a := k.addr() + core.Address(uint64(i)*heapInfoSize)
				if !yield(a, h) {
					return
				}
			}
		}
	}
}
