mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 18:27:37 +08:00
Improve .debug_line parser performance
This commit is contained in:
BIN
dwarf/line/line.test
Executable file
BIN
dwarf/line/line.test
Executable file
Binary file not shown.
@ -50,20 +50,17 @@ func Parse(data []byte) *DebugLineInfo {
|
||||
func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
|
||||
p := &DebugLinePrologue{}
|
||||
|
||||
binary.Read(buf, binary.LittleEndian, &p.Length)
|
||||
binary.Read(buf, binary.LittleEndian, &p.Version)
|
||||
binary.Read(buf, binary.LittleEndian, &p.PrologueLength)
|
||||
binary.Read(buf, binary.LittleEndian, &p.MinInstrLength)
|
||||
binary.Read(buf, binary.LittleEndian, &p.InitialIsStmt)
|
||||
binary.Read(buf, binary.LittleEndian, &p.LineBase)
|
||||
binary.Read(buf, binary.LittleEndian, &p.LineRange)
|
||||
binary.Read(buf, binary.LittleEndian, &p.OpcodeBase)
|
||||
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
|
||||
p.Length = binary.LittleEndian.Uint32(buf.Next(4))
|
||||
p.Version = binary.LittleEndian.Uint16(buf.Next(2))
|
||||
p.PrologueLength = binary.LittleEndian.Uint32(buf.Next(4))
|
||||
p.MinInstrLength = uint8(buf.Next(1)[0])
|
||||
p.InitialIsStmt = uint8(buf.Next(1)[0])
|
||||
p.LineBase = int8(buf.Next(1)[0])
|
||||
p.LineRange = uint8(buf.Next(1)[0])
|
||||
p.OpcodeBase = uint8(buf.Next(1)[0])
|
||||
|
||||
p.StdOpLengths = make([]uint8, p.OpcodeBase-1)
|
||||
for i := uint8(0); i < p.OpcodeBase-1; i++ {
|
||||
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths[i])
|
||||
}
|
||||
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
|
||||
|
||||
dbl.Prologue = p
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/davecheney/profile"
|
||||
)
|
||||
|
||||
func grabDebugLineSection(fp string, t *testing.T) []byte {
|
||||
@ -91,3 +93,13 @@ func TestDebugLinePrologueParser(t *testing.T) {
|
||||
t.Fatal("First entry not parsed correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLineParser(b *testing.B) {
|
||||
defer profile.Start(profile.MemProfile).Stop()
|
||||
data := grabDebugLineSection("../../_fixtures/testnextprog", nil)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = Parse(data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unicode/utf8"
|
||||
)
|
||||
import "bytes"
|
||||
|
||||
// DecodeULEB128 decodes an unsigned Little Endian Base 128
|
||||
// represented number.
|
||||
@ -67,36 +64,10 @@ func DecodeSLEB128(buf *bytes.Buffer) (int64, uint32) {
|
||||
}
|
||||
|
||||
func ParseString(data *bytes.Buffer) (string, uint32) {
|
||||
var (
|
||||
size uint32
|
||||
str []rune
|
||||
strb []byte
|
||||
)
|
||||
|
||||
for {
|
||||
b, err := data.ReadByte()
|
||||
if err != nil {
|
||||
panic("parseString(): Could not read byte")
|
||||
}
|
||||
size++
|
||||
|
||||
if b == 0x0 {
|
||||
if size == 1 {
|
||||
return "", size
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
strb = append(strb, b)
|
||||
|
||||
if utf8.FullRune(strb) {
|
||||
r, _ := utf8.DecodeRune(strb)
|
||||
str = append(str, r)
|
||||
size++
|
||||
strb = strb[0:0]
|
||||
}
|
||||
str, err := data.ReadString(0x0)
|
||||
if err != nil {
|
||||
panic("Could not parse string")
|
||||
}
|
||||
|
||||
return string(str), size
|
||||
return str[:len(str)-1], uint32(len(str))
|
||||
}
|
||||
|
||||
@ -32,6 +32,6 @@ func TestParseString(t *testing.T) {
|
||||
str, _ := ParseString(bstr)
|
||||
|
||||
if str != "hi" {
|
||||
t.Fatal("String was not parsed correctly")
|
||||
t.Fatalf("String was not parsed correctly %#v", str)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user