mirror of
				https://github.com/go-delve/delve.git
				synced 2025-11-01 03:42:59 +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
	 Derek Parker
					Derek Parker