Improve .debug_line parser performance

This commit is contained in:
Derek Parker
2014-07-14 21:41:15 -05:00
parent c546ea2ef7
commit 6b64296bca
5 changed files with 27 additions and 47 deletions

BIN
dwarf/line/line.test Executable file

Binary file not shown.

View File

@ -50,20 +50,17 @@ func Parse(data []byte) *DebugLineInfo {
func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) { func parseDebugLinePrologue(dbl *DebugLineInfo, buf *bytes.Buffer) {
p := &DebugLinePrologue{} p := &DebugLinePrologue{}
binary.Read(buf, binary.LittleEndian, &p.Length) p.Length = binary.LittleEndian.Uint32(buf.Next(4))
binary.Read(buf, binary.LittleEndian, &p.Version) p.Version = binary.LittleEndian.Uint16(buf.Next(2))
binary.Read(buf, binary.LittleEndian, &p.PrologueLength) p.PrologueLength = binary.LittleEndian.Uint32(buf.Next(4))
binary.Read(buf, binary.LittleEndian, &p.MinInstrLength) p.MinInstrLength = uint8(buf.Next(1)[0])
binary.Read(buf, binary.LittleEndian, &p.InitialIsStmt) p.InitialIsStmt = uint8(buf.Next(1)[0])
binary.Read(buf, binary.LittleEndian, &p.LineBase) p.LineBase = int8(buf.Next(1)[0])
binary.Read(buf, binary.LittleEndian, &p.LineRange) p.LineRange = uint8(buf.Next(1)[0])
binary.Read(buf, binary.LittleEndian, &p.OpcodeBase) p.OpcodeBase = uint8(buf.Next(1)[0])
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
p.StdOpLengths = make([]uint8, p.OpcodeBase-1) p.StdOpLengths = make([]uint8, p.OpcodeBase-1)
for i := uint8(0); i < p.OpcodeBase-1; i++ { binary.Read(buf, binary.LittleEndian, &p.StdOpLengths)
binary.Read(buf, binary.LittleEndian, &p.StdOpLengths[i])
}
dbl.Prologue = p dbl.Prologue = p
} }

View File

@ -6,6 +6,8 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/davecheney/profile"
) )
func grabDebugLineSection(fp string, t *testing.T) []byte { func grabDebugLineSection(fp string, t *testing.T) []byte {
@ -91,3 +93,13 @@ func TestDebugLinePrologueParser(t *testing.T) {
t.Fatal("First entry not parsed correctly") 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)
}
}

View File

@ -1,9 +1,6 @@
package util package util
import ( import "bytes"
"bytes"
"unicode/utf8"
)
// DecodeULEB128 decodes an unsigned Little Endian Base 128 // DecodeULEB128 decodes an unsigned Little Endian Base 128
// represented number. // represented number.
@ -67,36 +64,10 @@ func DecodeSLEB128(buf *bytes.Buffer) (int64, uint32) {
} }
func ParseString(data *bytes.Buffer) (string, uint32) { func ParseString(data *bytes.Buffer) (string, uint32) {
var ( str, err := data.ReadString(0x0)
size uint32 if err != nil {
str []rune panic("Could not parse string")
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]
}
} }
return string(str), size return str[:len(str)-1], uint32(len(str))
} }

View File

@ -32,6 +32,6 @@ func TestParseString(t *testing.T) {
str, _ := ParseString(bstr) str, _ := ParseString(bstr)
if str != "hi" { if str != "hi" {
t.Fatal("String was not parsed correctly") t.Fatalf("String was not parsed correctly %#v", str)
} }
} }