// 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.*`,
}, `|`)
