mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 18:57:18 +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) { | 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 | ||||||
| } | } | ||||||
|  | |||||||
| @ -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) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -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)) | ||||||
| } | } | ||||||
|  | |||||||
| @ -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) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Derek Parker
					Derek Parker