Reduce running time / allocations of frame parser

This commit is contained in:
Derek Parker
2014-07-14 13:30:04 -05:00
parent 6a82ebb25d
commit c546ea2ef7
2 changed files with 21 additions and 13 deletions

View File

@ -6,7 +6,6 @@ package frame
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"io"
"github.com/derekparker/dbg/dwarf/util" "github.com/derekparker/dbg/dwarf/util"
) )
@ -44,7 +43,7 @@ func cieEntry(data []byte) bool {
func parseLength(ctx *parseContext) parsefunc { func parseLength(ctx *parseContext) parsefunc {
var fn parsefunc var fn parsefunc
binary.Read(ctx.Buf, binary.LittleEndian, &ctx.Length) ctx.Length = binary.LittleEndian.Uint32(ctx.Buf.Next(4))
cieid := ctx.Buf.Next(4) cieid := ctx.Buf.Next(4)
if cieEntry(cieid) { if cieEntry(cieid) {
@ -63,7 +62,7 @@ func parseLength(ctx *parseContext) parsefunc {
} }
func parseInitialLocation(ctx *parseContext) parsefunc { func parseInitialLocation(ctx *parseContext) parsefunc {
binary.Read(ctx.Buf, binary.LittleEndian, &ctx.Frame.AddressRange.begin) ctx.Frame.AddressRange.begin = binary.LittleEndian.Uint64(ctx.Buf.Next(8))
ctx.Length -= 8 ctx.Length -= 8
@ -71,7 +70,7 @@ func parseInitialLocation(ctx *parseContext) parsefunc {
} }
func parseAddressRange(ctx *parseContext) parsefunc { func parseAddressRange(ctx *parseContext) parsefunc {
binary.Read(ctx.Buf, binary.LittleEndian, &ctx.Frame.AddressRange.end) ctx.Frame.AddressRange.end = binary.LittleEndian.Uint64(ctx.Buf.Next(8))
ctx.Length -= 8 ctx.Length -= 8
@ -82,17 +81,18 @@ func parseFrameInstructions(ctx *parseContext) parsefunc {
// The rest of this entry consists of the instructions // The rest of this entry consists of the instructions
// so we can just grab all of the data from the buffer // so we can just grab all of the data from the buffer
// cursor to length. // cursor to length.
var buf = make([]byte, ctx.Length) ctx.Frame.Instructions = ctx.Buf.Next(int(ctx.Length))
io.ReadFull(ctx.Buf, buf)
ctx.Frame.Instructions = buf
ctx.Length = 0 ctx.Length = 0
return parseLength return parseLength
} }
func parseVersion(ctx *parseContext) parsefunc { func parseVersion(ctx *parseContext) parsefunc {
binary.Read(ctx.Buf, binary.LittleEndian, &ctx.Common.Version) version, err := ctx.Buf.ReadByte()
if err != nil {
panic(err)
}
ctx.Common.Version = version
ctx.Length -= 1 ctx.Length -= 1
return parseAugmentation return parseAugmentation
@ -137,10 +137,7 @@ func parseInitialInstructions(ctx *parseContext) parsefunc {
// The rest of this entry consists of the instructions // The rest of this entry consists of the instructions
// so we can just grab all of the data from the buffer // so we can just grab all of the data from the buffer
// cursor to length. // cursor to length.
var buf = make([]byte, ctx.Length) ctx.Common.InitialInstructions = ctx.Buf.Next(int(ctx.Length))
binary.Read(ctx.Buf, binary.LittleEndian, &buf)
ctx.Common.InitialInstructions = buf
ctx.Length = 0 ctx.Length = 0
return parseLength return parseLength

View File

@ -3,6 +3,7 @@ package frame_test
import ( import (
"testing" "testing"
"github.com/davecheney/profile"
"github.com/derekparker/dbg/dwarf/frame" "github.com/derekparker/dbg/dwarf/frame"
) )
@ -38,3 +39,13 @@ func TestParse(t *testing.T) {
} }
} }
func BenchmarkParse(b *testing.B) {
defer profile.Start(profile.CPUProfile).Stop()
data := grabDebugFrameSection("../../_fixtures/testprog", nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
frame.Parse(data)
}
}