// Copyright 2014 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.

// This file implements parsers to convert legacy profiles into the
// profile.proto format.

package profile

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"math"
	"regexp"
	"strconv"
	"strings"
)

var (
	countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`)
	countRE      = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`)

	heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`)
	heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`)

	contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`)

	hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`)

	growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`)

	fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`)

	threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`)
	threadStartRE  = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`)

	procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`)

	briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`)

	// LegacyHeapAllocated instructs the heapz parsers to use the
	// allocated memory stats instead of the default in-use memory. Note
	// that tcmalloc doesn't provide all allocated memory, only in-use
	// stats.
	LegacyHeapAllocated bool
)

func isSpaceOrComment(line string) bool {
	trimmed := strings.TrimSpace(line)
	return len(trimmed) == 0 || trimmed[0] == '#'
}

// parseGoCount parses a Go count profile (e.g., threadcreate or
// goroutine) and returns a new Profile.
func parseGoCount(b []byte) (*Profile, error) {
	r := bytes.NewBuffer(b)

	var line string
	var err error
	for {
		// Skip past comments and empty lines seeking a real header.
		line, err = r.ReadString('\n')
		if err != nil {
			return nil, err
		}
		if !isSpaceOrComment(line) {
			break
		}
	}

	m := countStartRE.FindStringSubmatch(line)
	if m == nil {
		return nil, errUnrecognized
	}
	profileType := string(m[1])
	p := &Profile{
		PeriodType: &ValueType{Type: profileType, Unit: "count"},
		Period:     1,
		SampleType: []*ValueType{{Type: profileType, Unit: "count"}},
	}
	locations := make(map[uint64]*Location)
	for {
		line, err = r.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}
		if isSpaceOrComment(line) {
			continue
		}
		if strings.HasPrefix(line, "---") {
			break
		}
		m := countRE.FindStringSubmatch(line)
		if m == nil {
			return nil, errMalformed
		}
		n, err := strconv.ParseInt(string(m[1]), 0, 64)
		if err != nil {
			return nil, errMalformed
		}
		fields := strings.Fields(string(m[2]))
		locs := make([]*Location, 0, len(fields))
		for _, stk := range fields {
			addr, err := strconv.ParseUint(stk, 0, 64)
			if err != nil {
				return nil, errMalformed
			}
			// Adjust all frames by -1 (except the leaf) to land on top of
			// the call instruction.
			if len(locs) > 0 {
				addr--
			}
			loc := locations[addr]
			if loc == nil {
				loc = &Location{
					Address: addr,
				}
				locations[addr] = loc
				p.Location = append(p.Location, loc)
			}
			locs = append(locs, loc)
		}
		p.Sample = append(p.Sample, &Sample{
			Location: locs,
			Value:    []int64{n},
		})
	}

	if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil {
		return nil, err
	}
	return p, nil
}

// remapLocationIDs ensures there is a location for each address
// referenced by a sample, and remaps the samples to point to the new
// location ids.
func (p *Profile) remapLocationIDs() {
	seen := make(map[*Location]bool, len(p.Location))
	var locs []*Location

	for _, s := range p.Sample {
		for _, l := range s.Location {
			if seen[l] {
				continue
			}
			l.ID = uint64(len(locs) + 1)
			locs = append(locs, l)
			seen[l] = true
		}
	}
	p.Location = locs
}

func (p *Profile) remapFunctionIDs() {
	seen := make(map[*Function]bool, len(p.Function))
	var fns []*Function

	for _, l := range p.Location {
		for _, ln := range l.Line {
			fn := ln.Function
			if fn == nil || seen[fn] {
				continue
			}
			fn.ID = uint64(len(fns) + 1)
			fns = append(fns, fn)
			seen[fn] = true
		}
	}
	p.Function = fns
}

// remapMappingIDs matches location addresses with existing mappings
// and updates them appropriately. This is O(N*M), if this ever shows
// up as a bottleneck, evaluate sorting the mappings and doing a
// binary search, which would make it O(N*log(M)).
func (p *Profile) remapMappingIDs() {
	if len(p.Mapping) == 0 {
		return
	}

	// Some profile handlers will incorrectly set regions for the main
	// executable if its section is remapped. Fix them through heuristics.

	// Remove the initial mapping if named '/anon_hugepage' and has a
	// consecutive adjacent mapping.
	if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") {
		if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start {
			p.Mapping = p.Mapping[1:]
		}
	}

	// Subtract the offset from the start of the main mapping if it
	// ends up at a recognizable start address.
	const expectedStart = 0x400000
	if m := p.Mapping[0]; m.Start-m.Offset == expectedStart {
		m.Start = expectedStart
		m.Offset = 0
	}

	for _, l := range p.Location {
		if a := l.Address; a != 0 {
			for _, m := range p.Mapping {
				if m.Start <= a && a < m.Limit {
					l.Mapping = m
					break
				}
			}
		}
	}

	// Reset all mapping IDs.
	for i, m := range p.Mapping {
		m.ID = uint64(i + 1)
	}
}

var cpuInts = []func([]byte) (uint64, []byte){
	get32l,
	get32b,
	get64l,
	get64b,
}

func get32l(b []byte) (uint64, []byte) {
	if len(b) < 4 {
		return 0, nil
	}
	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:]
}

func get32b(b []byte) (uint64, []byte) {
	if len(b) < 4 {
		return 0, nil
	}
	return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:]
}

func get64l(b []byte) (uint64, []byte) {
	if len(b) < 8 {
		return 0, nil
	}
	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:]
}

func get64b(b []byte) (uint64, []byte) {
	if len(b) < 8 {
		return 0, nil
	}
	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:]
}

// ParseTracebacks parses a set of tracebacks and returns a newly
// populated profile. It will accept any text file and generate a
// Profile out of it with any hex addresses it can identify, including
// a process map if it can recognize one. Each sample will include a
// tag "source" with the addresses recognized in string format.
func ParseTracebacks(b []byte) (*Profile, error) {
	r := bytes.NewBuffer(b)

	p := &Profile{
		PeriodType: &ValueType{Type: "trace", Unit: "count"},
		Period:     1,
		SampleType: []*ValueType{
			{Type: "trace", Unit: "count"},
		},
	}

	var sources []string
	var sloc []*Location

	locs := make(map[uint64]*Location)
	for {
		l, err := r.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			if l == "" {
				break
			}
		}
		if sectionTrigger(l) == memoryMapSection {
			break
		}
		if s, addrs := extractHexAddresses(l); len(s) > 0 {
			for _, addr := range addrs {
				// Addresses from stack traces point to the next instruction after
				// each call.  Adjust by -1 to land somewhere on the actual call
				// (except for the leaf, which is not a call).
				if len(sloc) > 0 {
					addr--
				}
				loc := locs[addr]
				if locs[addr] == nil {
					loc = &Location{
						Address: addr,
					}
					p.Location = append(p.Location, loc)
					locs[addr] = loc
				}
				sloc = append(sloc, loc)
			}

			sources = append(sources, s...)
		} else {
			if len(sources) > 0 || len(sloc) > 0 {
				addTracebackSample(sloc, sources, p)
				sloc, sources = nil, nil
			}
		}
	}

	// Add final sample to save any leftover data.
	if len(sources) > 0 || len(sloc) > 0 {
		addTracebackSample(sloc, sources, p)
	}

	if err := p.ParseMemoryMap(r); err != nil {
		return nil, err
	}
	return p, nil
}

func addTracebackSample(l []*Location, s []string, p *Profile) {
	p.Sample = append(p.Sample,
		&Sample{
			Value:    []int64{1},
			Location: l,
			Label:    map[string][]string{"source": s},
		})
}

// parseCPU parses a profilez legacy profile and returns a newly
// populated Profile.
//
// The general format for profilez samples is a sequence of words in
// binary format. The first words are a header with the following data:
//   1st word -- 0
//   2nd word -- 3
//   3rd word -- 0 if a c++ application, 1 if a java application.
//   4th word -- Sampling period (in microseconds).
//   5th word -- Padding.
func parseCPU(b []byte) (*Profile, error) {
	var parse func([]byte) (uint64, []byte)
	var n1, n2, n3, n4, n5 uint64
	for _, parse = range cpuInts {
		var tmp []byte
		n1, tmp = parse(b)
		n2, tmp = parse(tmp)
		n3, tmp = parse(tmp)
		n4, tmp = parse(tmp)
		n5, tmp = parse(tmp)

		if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 {
			b = tmp
			return cpuProfile(b, int64(n4), parse)
		}
	}
	return nil, errUnrecognized
}

// cpuProfile returns a new Profile from C++ profilez data.
// b is the profile bytes after the header, period is the profiling
// period, and parse is a function to parse 8-byte chunks from the
// profile in its native endianness.
func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {
	p := &Profile{
		Period:     period * 1000,
		PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"},
		SampleType: []*ValueType{
			{Type: "samples", Unit: "count"},
			{Type: "cpu", Unit: "nanoseconds"},
		},
	}
	var err error
	if b, _, err = parseCPUSamples(b, parse, true, p); err != nil {
		return nil, err
	}

	// If all samples have the same second-to-the-bottom frame, it
	// strongly suggests that it is an uninteresting artifact of
	// measurement -- a stack frame pushed by the signal handler. The
	// bottom frame is always correct as it is picked up from the signal
	// structure, not the stack. Check if this is the case and if so,
	// remove.
	if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 {
		allSame := true
		id1 := p.Sample[0].Location[1].Address
		for _, s := range p.Sample {
			if len(s.Location) < 2 || id1 != s.Location[1].Address {
				allSame = false
				break
			}
		}
		if allSame {
			for _, s := range p.Sample {
				s.Location = append(s.Location[:1], s.Location[2:]...)
			}
		}
	}

	if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil {
		return nil, err
	}
	return p, nil
}

// parseCPUSamples parses a collection of profilez samples from a
// profile.
//
// profilez samples are a repeated sequence of stack frames of the
// form:
//    1st word -- The number of times this stack was encountered.
//    2nd word -- The size of the stack (StackSize).
//    3rd word -- The first address on the stack.
//    ...
//    StackSize + 2 -- The last address on the stack
// The last stack trace is of the form:
//   1st word -- 0
//   2nd word -- 1
//   3rd word -- 0
//
// Addresses from stack traces may point to the next instruction after
// each call.  Optionally adjust by -1 to land somewhere on the actual
// call (except for the leaf, which is not a call).
func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) {
	locs := make(map[uint64]*Location)
	for len(b) > 0 {
		var count, nstk uint64
		count, b = parse(b)
		nstk, b = parse(b)
		if b == nil || nstk > uint64(len(b)/4) {
			return nil, nil, errUnrecognized
		}
		var sloc []*Location
		addrs := make([]uint64, nstk)
		for i := 0; i < int(nstk); i++ {
			addrs[i], b = parse(b)
		}

		if count == 0 && nstk == 1 && addrs[0] == 0 {
			// End of data marker
			break
		}
		for i, addr := range addrs {
			if adjust && i > 0 {
				addr--
			}
			loc := locs[addr]
			if loc == nil {
				loc = &Location{
					Address: addr,
				}
				locs[addr] = loc
				p.Location = append(p.Location, loc)
			}
			sloc = append(sloc, loc)
		}
		p.Sample = append(p.Sample,
			&Sample{
				Value:    []int64{int64(count), int64(count) * int64(p.Period)},
				Location: sloc,
			})
	}
	// Reached the end without finding the EOD marker.
	return b, locs, nil
}

// parseHeap parses a heapz legacy or a growthz profile and
// returns a newly populated Profile.
func parseHeap(b []byte) (p *Profile, err error) {
	r := bytes.NewBuffer(b)
	l, err := r.ReadString('\n')
	if err != nil {
		return nil, errUnrecognized
	}

	sampling := ""

	if header := heapHeaderRE.FindStringSubmatch(l); header != nil {
		p = &Profile{
			SampleType: []*ValueType{
				{Type: "objects", Unit: "count"},
				{Type: "space", Unit: "bytes"},
			},
			PeriodType: &ValueType{Type: "objects", Unit: "bytes"},
		}

		var period int64
		if len(header[6]) > 0 {
			if period, err = strconv.ParseInt(string(header[6]), 10, 64); err != nil {
				return nil, errUnrecognized
			}
		}

		switch header[5] {
		case "heapz_v2", "heap_v2":
			sampling, p.Period = "v2", period
		case "heapprofile":
			sampling, p.Period = "", 1
		case "heap":
			sampling, p.Period = "v2", period/2
		default:
			return nil, errUnrecognized
		}
	} else if header = growthHeaderRE.FindStringSubmatch(l); header != nil {
		p = &Profile{
			SampleType: []*ValueType{
				{Type: "objects", Unit: "count"},
				{Type: "space", Unit: "bytes"},
			},
			PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"},
			Period:     1,
		}
	} else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil {
		p = &Profile{
			SampleType: []*ValueType{
				{Type: "objects", Unit: "count"},
				{Type: "space", Unit: "bytes"},
			},
			PeriodType: &ValueType{Type: "allocations", Unit: "count"},
			Period:     1,
		}
	} else {
		return nil, errUnrecognized
	}

	if LegacyHeapAllocated {
		for _, st := range p.SampleType {
			st.Type = "alloc_" + st.Type
		}
	} else {
		for _, st := range p.SampleType {
			st.Type = "inuse_" + st.Type
		}
	}

	locs := make(map[uint64]*Location)
	for {
		l, err = r.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				return nil, err
			}

			if l == "" {
				break
			}
		}

		if isSpaceOrComment(l) {
			continue
		}
		l = strings.TrimSpace(l)

		if sectionTrigger(l) != unrecognizedSection {
			break
		}

		value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling)
		if err != nil {
			return nil, err
		}
		var sloc []*Location
		for i, addr := range addrs {
			// Addresses from stack traces point to the next instruction after
			// each call.  Adjust by -1 to land somewhere on the actual call
			// (except for the leaf, which is not a call).
			if i > 0 {
				addr--
			}
			loc := locs[addr]
			if locs[addr] == nil {
				loc = &Location{
					Address: addr,
				}
				p.Location = append(p.Location, loc)
				locs[addr] = loc
			}
			sloc = append(sloc, loc)
		}

		p.Sample = append(p.Sample, &Sample{
			Value:    value,
			Location: sloc,
			NumLabel: map[string][]int64{"bytes": {blocksize}},
		})
	}

	if err = parseAdditionalSections(l, r, p); err != nil {
		return nil, err
	}
	return p, nil
}

// parseHeapSample parses a single row from a heap profile into a new Sample.
func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) {
	sampleData := heapSampleRE.FindStringSubmatch(line)
	if len(sampleData) != 6 {
		return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData))
	}

	// Use first two values by default; tcmalloc sampling generates the
	// same value for both, only the older heap-profile collect separate
	// stats for in-use and allocated objects.
	valueIndex := 1
	if LegacyHeapAllocated {
		valueIndex = 3
	}

	var v1, v2 int64
	if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil {
		return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
	}
	if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil {
		return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
	}

	if v1 == 0 {
		if v2 != 0 {
			return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2)
		}
	} else {
		blocksize = v2 / v1
		if sampling == "v2" {
			v1, v2 = scaleHeapSample(v1, v2, rate)
		}
	}

	value = []int64{v1, v2}
	addrs = parseHexAddresses(sampleData[5])

	return value, blocksize, addrs, nil
}

// extractHexAddresses extracts hex numbers from a string and returns
// them, together with their numeric value, in a slice.
func extractHexAddresses(s string) ([]string, []uint64) {
	hexStrings := hexNumberRE.FindAllString(s, -1)
	var ids []uint64
	for _, s := range hexStrings {
		if id, err := strconv.ParseUint(s, 0, 64); err == nil {
			ids = append(ids, id)
		} else {
			// Do not expect any parsing failures due to the regexp matching.
			panic("failed to parse hex value:" + s)
		}
	}
	return hexStrings, ids
}

// parseHexAddresses parses hex numbers from a string and returns them
// in a slice.
func parseHexAddresses(s string) []uint64 {
	_, ids := extractHexAddresses(s)
	return ids
}

// scaleHeapSample adjusts the data from a heapz Sample to
// account for its probability of appearing in the collected
// data. heapz profiles are a sampling of the memory allocations
// requests in a program. We estimate the unsampled value by dividing
// each collected sample by its probability of appearing in the
// profile. heapz v2 profiles rely on a poisson process to determine
// which samples to collect, based on the desired average collection
// rate R. The probability of a sample of size S to appear in that
// profile is 1-exp(-S/R).
func scaleHeapSample(count, size, rate int64) (int64, int64) {
	if count == 0 || size == 0 {
		return 0, 0
	}

	if rate <= 1 {
		// if rate==1 all samples were collected so no adjustment is needed.
		// if rate<1 treat as unknown and skip scaling.
		return count, size
	}

	avgSize := float64(size) / float64(count)
	scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))

	return int64(float64(count) * scale), int64(float64(size) * scale)
}

// parseContention parses a contentionz profile and returns a newly
// populated Profile.
func parseContention(b []byte) (p *Profile, err error) {
	r := bytes.NewBuffer(b)
	l, err := r.ReadString('\n')
	if err != nil {
		return nil, errUnrecognized
	}

	if !strings.HasPrefix(l, "--- contention") {
		return nil, errUnrecognized
	}

	p = &Profile{
		PeriodType: &ValueType{Type: "contentions", Unit: "count"},
		Period:     1,
		SampleType: []*ValueType{
			{Type: "contentions", Unit: "count"},
			{Type: "delay", Unit: "nanoseconds"},
		},
	}

	var cpuHz int64
	// Parse text of the form "attribute = value" before the samples.
	const delimiter = "="
	for {
		l, err = r.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				return nil, err
			}

			if l == "" {
				break
			}
		}

		if l = strings.TrimSpace(l); l == "" {
			continue
		}

		if strings.HasPrefix(l, "---") {
			break
		}

		attr := strings.SplitN(l, delimiter, 2)
		if len(attr) != 2 {
			break
		}
		key, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])
		var err error
		switch key {
		case "cycles/second":
			if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil {
				return nil, errUnrecognized
			}
		case "sampling period":
			if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil {
				return nil, errUnrecognized
			}
		case "ms since reset":
			ms, err := strconv.ParseInt(val, 0, 64)
			if err != nil {
				return nil, errUnrecognized
			}
			p.DurationNanos = ms * 1000 * 1000
		case "format":
			// CPP contentionz profiles don't have format.
			return nil, errUnrecognized
		case "resolution":
			// CPP contentionz profiles don't have resolution.
			return nil, errUnrecognized
		case "discarded samples":
		default:
			return nil, errUnrecognized
		}
	}

	locs := make(map[uint64]*Location)
	for {
		if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
			break
		}
		value, addrs, err := parseContentionSample(l, p.Period, cpuHz)
		if err != nil {
			return nil, err
		}
		var sloc []*Location
		for i, addr := range addrs {
			// Addresses from stack traces point to the next instruction after
			// each call.  Adjust by -1 to land somewhere on the actual call
			// (except for the leaf, which is not a call).
			if i > 0 {
				addr--
			}
			loc := locs[addr]
			if locs[addr] == nil {
				loc = &Location{
					Address: addr,
				}
				p.Location = append(p.Location, loc)
				locs[addr] = loc
			}
			sloc = append(sloc, loc)
		}
		p.Sample = append(p.Sample, &Sample{
			Value:    value,
			Location: sloc,
		})

		if l, err = r.ReadString('\n'); err != nil {
			if err != io.EOF {
				return nil, err
			}
			if l == "" {
				break
			}
		}
	}

	if err = parseAdditionalSections(l, r, p); err != nil {
		return nil, err
	}

	return p, nil
}

// parseContentionSample parses a single row from a contention profile
// into a new Sample.
func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {
	sampleData := contentionSampleRE.FindStringSubmatch(line)
	if sampleData == nil {
		return value, addrs, errUnrecognized
	}

	v1, err := strconv.ParseInt(sampleData[1], 10, 64)
	if err != nil {
		return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
	}
	v2, err := strconv.ParseInt(sampleData[2], 10, 64)
	if err != nil {
		return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
	}

	// Unsample values if period and cpuHz are available.
	// - Delays are scaled to cycles and then to nanoseconds.
	// - Contentions are scaled to cycles.
	if period > 0 {
		if cpuHz > 0 {
			cpuGHz := float64(cpuHz) / 1e9
			v1 = int64(float64(v1) * float64(period) / cpuGHz)
		}
		v2 = v2 * period
	}

	value = []int64{v2, v1}
	addrs = parseHexAddresses(sampleData[3])

	return value, addrs, nil
}

// parseThread parses a Threadz profile and returns a new Profile.
func parseThread(b []byte) (*Profile, error) {
	r := bytes.NewBuffer(b)

	var line string
	var err error
	for {
		// Skip past comments and empty lines seeking a real header.
		line, err = r.ReadString('\n')
		if err != nil {
			return nil, err
		}
		if !isSpaceOrComment(line) {
			break
		}
	}

	if m := threadzStartRE.FindStringSubmatch(line); m != nil {
		// Advance over initial comments until first stack trace.
		for {
			line, err = r.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					return nil, err
				}

				if line == "" {
					break
				}
			}
			if sectionTrigger(line) != unrecognizedSection || line[0] == '-' {
				break
			}
		}
	} else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
		return nil, errUnrecognized
	}

	p := &Profile{
		SampleType: []*ValueType{{Type: "thread", Unit: "count"}},
		PeriodType: &ValueType{Type: "thread", Unit: "count"},
		Period:     1,
	}

	locs := make(map[uint64]*Location)
	// Recognize each thread and populate profile samples.
	for sectionTrigger(line) == unrecognizedSection {
		if strings.HasPrefix(line, "---- no stack trace for") {
			line = ""
			break
		}
		if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
			return nil, errUnrecognized
		}

		var addrs []uint64
		line, addrs, err = parseThreadSample(r)
		if err != nil {
			return nil, errUnrecognized
		}
		if len(addrs) == 0 {
			// We got a --same as previous threads--. Bump counters.
			if len(p.Sample) > 0 {
				s := p.Sample[len(p.Sample)-1]
				s.Value[0]++
			}
			continue
		}

		var sloc []*Location
		for i, addr := range addrs {
			// Addresses from stack traces point to the next instruction after
			// each call.  Adjust by -1 to land somewhere on the actual call
			// (except for the leaf, which is not a call).
			if i > 0 {
				addr--
			}
			loc := locs[addr]
			if locs[addr] == nil {
				loc = &Location{
					Address: addr,
				}
				p.Location = append(p.Location, loc)
				locs[addr] = loc
			}
			sloc = append(sloc, loc)
		}

		p.Sample = append(p.Sample, &Sample{
			Value:    []int64{1},
			Location: sloc,
		})
	}

	if err = parseAdditionalSections(line, r, p); err != nil {
		return nil, err
	}

	return p, nil
}

// parseThreadSample parses a symbolized or unsymbolized stack trace.
// Returns the first line after the traceback, the sample (or nil if
// it hits a 'same-as-previous' marker) and an error.
func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) {
	var l string
	sameAsPrevious := false
	for {
		if l, err = b.ReadString('\n'); err != nil {
			if err != io.EOF {
				return "", nil, err
			}
			if l == "" {
				break
			}
		}
		if l = strings.TrimSpace(l); l == "" {
			continue
		}

		if strings.HasPrefix(l, "---") {
			break
		}
		if strings.Contains(l, "same as previous thread") {
			sameAsPrevious = true
			continue
		}

		addrs = append(addrs, parseHexAddresses(l)...)
	}

	if sameAsPrevious {
		return l, nil, nil
	}
	return l, addrs, nil
}

// parseAdditionalSections parses any additional sections in the
// profile, ignoring any unrecognized sections.
func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) {
	for {
		if sectionTrigger(l) == memoryMapSection {
			break
		}
		// Ignore any unrecognized sections.
		if l, err := b.ReadString('\n'); err != nil {
			if err != io.EOF {
				return err
			}
			if l == "" {
				break
			}
		}
	}
	return p.ParseMemoryMap(b)
}

// ParseMemoryMap parses a memory map in the format of
// /proc/self/maps, and overrides the mappings in the current profile.
// It renumbers the samples and locations in the profile correspondingly.
func (p *Profile) ParseMemoryMap(rd io.Reader) error {
	b := bufio.NewReader(rd)

	var attrs []string
	var r *strings.Replacer
	const delimiter = "="
	for {
		l, err := b.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				return err
			}
			if l == "" {
				break
			}
		}
		if l = strings.TrimSpace(l); l == "" {
			continue
		}

		if r != nil {
			l = r.Replace(l)
		}
		m, err := parseMappingEntry(l)
		if err != nil {
			if err == errUnrecognized {
				// Recognize assignments of the form: attr=value, and replace
				// $attr with value on subsequent mappings.
				if attr := strings.SplitN(l, delimiter, 2); len(attr) == 2 {
					attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]))
					r = strings.NewReplacer(attrs...)
				}
				// Ignore any unrecognized entries
				continue
			}
			return err
		}
		if m == nil || (m.File == "" && len(p.Mapping) != 0) {
			// In some cases the first entry may include the address range
			// but not the name of the file. It should be followed by
			// another entry with the name.
			continue
		}
		if len(p.Mapping) == 1 && p.Mapping[0].File == "" {
			// Update the name if this is the entry following that empty one.
			p.Mapping[0].File = m.File
			continue
		}
		p.Mapping = append(p.Mapping, m)
	}
	p.remapLocationIDs()
	p.remapFunctionIDs()
	p.remapMappingIDs()
	return nil
}

func parseMappingEntry(l string) (*Mapping, error) {
	mapping := &Mapping{}
	var err error
	if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 {
		if !strings.Contains(me[3], "x") {
			// Skip non-executable entries.
			return nil, nil
		}
		if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
			return nil, errUnrecognized
		}
		if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
			return nil, errUnrecognized
		}
		if me[4] != "" {
			if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil {
				return nil, errUnrecognized
			}
		}
		mapping.File = me[8]
		return mapping, nil
	}

	if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 {
		if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
			return nil, errUnrecognized
		}
		if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
			return nil, errUnrecognized
		}
		mapping.File = me[3]
		if me[5] != "" {
			if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil {
				return nil, errUnrecognized
			}
		}
		return mapping, nil
	}

	return nil, errUnrecognized
}

type sectionType int

const (
	unrecognizedSection sectionType = iota
	memoryMapSection
)

var memoryMapTriggers = []string{
	"--- Memory map: ---",
	"MAPPED_LIBRARIES:",
}

func sectionTrigger(line string) sectionType {
	for _, trigger := range memoryMapTriggers {
		if strings.Contains(line, trigger) {
			return memoryMapSection
		}
	}
	return unrecognizedSection
}

func (p *Profile) addLegacyFrameInfo() {
	switch {
	case isProfileType(p, heapzSampleTypes) ||
		isProfileType(p, heapzInUseSampleTypes) ||
		isProfileType(p, heapzAllocSampleTypes):
		p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr
	case isProfileType(p, contentionzSampleTypes):
		p.DropFrames, p.KeepFrames = lockRxStr, ""
	default:
		p.DropFrames, p.KeepFrames = cpuProfilerRxStr, ""
	}
}

var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles
var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"}
var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"}
var contentionzSampleTypes = []string{"contentions", "delay"}

func isProfileType(p *Profile, t []string) bool {
	st := p.SampleType
	if len(st) != len(t) {
		return false
	}

	for i := range st {
		if st[i].Type != t[i] {
			return false
		}
	}
	return true
}

var allocRxStr = strings.Join([]string{
	// POSIX entry points.
	`calloc`,
	`cfree`,
	`malloc`,
	`free`,
	`memalign`,
	`do_memalign`,
	`(__)?posix_memalign`,
	`pvalloc`,
	`valloc`,
	`realloc`,

	// TC malloc.
	`tcmalloc::.*`,
	`tc_calloc`,
	`tc_cfree`,
	`tc_malloc`,
	`tc_free`,
	`tc_memalign`,
	`tc_posix_memalign`,
	`tc_pvalloc`,
	`tc_valloc`,
	`tc_realloc`,
	`tc_new`,
	`tc_delete`,
	`tc_newarray`,
	`tc_deletearray`,
	`tc_new_nothrow`,
	`tc_newarray_nothrow`,

	// Memory-allocation routines on OS X.
	`malloc_zone_malloc`,
	`malloc_zone_calloc`,
	`malloc_zone_valloc`,
	`malloc_zone_realloc`,
	`malloc_zone_memalign`,
	`malloc_zone_free`,

	// Go runtime
	`runtime\..*`,

	// Other misc. memory allocation routines
	`BaseArena::.*`,
	`(::)?do_malloc_no_errno`,
	`(::)?do_malloc_pages`,
	`(::)?do_malloc`,
	`DoSampledAllocation`,
	`MallocedMemBlock::MallocedMemBlock`,
	`_M_allocate`,
	`__builtin_(vec_)?delete`,
	`__builtin_(vec_)?new`,
	`__gnu_cxx::new_allocator::allocate`,
	`__libc_malloc`,
	`__malloc_alloc_template::allocate`,
	`allocate`,
	`cpp_alloc`,
	`operator new(\[\])?`,
	`simple_alloc::allocate`,
}, `|`)

var allocSkipRxStr = strings.Join([]string{
	// Preserve Go runtime frames that appear in the middle/bottom of
	// the stack.
	`runtime\.panic`,
}, `|`)

var cpuProfilerRxStr = strings.Join([]string{
	`ProfileData::Add`,
	`ProfileData::prof_handler`,
	`CpuProfiler::prof_handler`,
	`__pthread_sighandler`,
	`__restore`,
}, `|`)

var lockRxStr = strings.Join([]string{
	`RecordLockProfileData`,
	`(base::)?RecordLockProfileData.*`,
	`(base::)?SubmitMutexProfileData.*`,
	`(base::)?SubmitSpinLockProfileData.*`,
	`(Mutex::)?AwaitCommon.*`,
	`(Mutex::)?Unlock.*`,
	`(Mutex::)?UnlockSlow.*`,
	`(Mutex::)?ReaderUnlock.*`,
	`(MutexLock::)?~MutexLock.*`,
	`(SpinLock::)?Unlock.*`,
	`(SpinLock::)?SlowUnlock.*`,
	`(SpinLockHolder::)?~SpinLockHolder.*`,
}, `|`)
