Browse Source

Populate more carefully the profile.proto in the topproto output

Instead of putting a pretty-printed string on the function.name,
populate the function.name, .file and location line with the
information from the node. This will help more easily extract this
information.

Also add some cachign to reuse functions and added a small test.
Raul Silvera 8 years ago
parent
commit
6c7cca8edf
2 changed files with 50 additions and 10 deletions
  1. 26
    10
      internal/report/report.go
  2. 24
    0
      internal/report/report_test.go

+ 26
- 10
internal/report/report.go View File

286
 		PeriodType:    p.PeriodType,
286
 		PeriodType:    p.PeriodType,
287
 		Period:        p.Period,
287
 		Period:        p.Period,
288
 	}
288
 	}
289
-	var flatSum int64
289
+	functionMap := make(functionMap)
290
 	for i, n := range g.Nodes {
290
 	for i, n := range g.Nodes {
291
-		name, flat, cum := n.Info.PrintableName(), n.FlatValue(), n.CumValue()
292
-
293
-		flatSum += flat
294
-		f := &profile.Function{
295
-			ID:         uint64(i + 1),
296
-			Name:       name,
297
-			SystemName: name,
298
-		}
291
+		f := functionMap.FindOrAdd(n.Info)
292
+		flat, cum := n.FlatValue(), n.CumValue()
299
 		l := &profile.Location{
293
 		l := &profile.Location{
300
-			ID: uint64(i + 1),
294
+			ID:      uint64(i + 1),
295
+			Address: n.Info.Address,
301
 			Line: []profile.Line{
296
 			Line: []profile.Line{
302
 				{
297
 				{
298
+					Line:     int64(n.Info.Lineno),
303
 					Function: f,
299
 					Function: f,
304
 				},
300
 				},
305
 			},
301
 			},
319
 	return out.Write(w)
315
 	return out.Write(w)
320
 }
316
 }
321
 
317
 
318
+type functionMap map[string]*profile.Function
319
+
320
+func (fm functionMap) FindOrAdd(ni graph.NodeInfo) *profile.Function {
321
+	fName := fmt.Sprintf("%q%q%q%d", ni.Name, ni.OrigName, ni.File, ni.StartLine)
322
+
323
+	if f := fm[fName]; f != nil {
324
+		return f
325
+	}
326
+
327
+	f := &profile.Function{
328
+		ID:         uint64(len(fm) + 1),
329
+		Name:       ni.Name,
330
+		SystemName: ni.OrigName,
331
+		Filename:   ni.File,
332
+		StartLine:  int64(ni.StartLine),
333
+	}
334
+	fm[fName] = f
335
+	return f
336
+}
337
+
322
 // printAssembly prints an annotated assembly listing.
338
 // printAssembly prints an annotated assembly listing.
323
 func printAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
339
 func printAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
324
 	o := rpt.options
340
 	o := rpt.options

+ 24
- 0
internal/report/report_test.go View File

236
 		}
236
 		}
237
 	}
237
 	}
238
 }
238
 }
239
+
240
+func TestFunctionMap(t *testing.T) {
241
+
242
+	fm := make(functionMap)
243
+	nodes := []graph.NodeInfo{
244
+		{Name: "fun1"},
245
+		{Name: "fun2", File: "filename"},
246
+		{Name: "fun1"},
247
+		{Name: "fun2", File: "filename2"},
248
+	}
249
+
250
+	want := []profile.Function{
251
+		{ID: 1, Name: "fun1"},
252
+		{ID: 2, Name: "fun2", Filename: "filename"},
253
+		{ID: 1, Name: "fun1"},
254
+		{ID: 3, Name: "fun2", Filename: "filename2"},
255
+	}
256
+
257
+	for i, tc := range nodes {
258
+		if got, want := fm.FindOrAdd(tc), want[i]; *got != want {
259
+			t.Errorf("%d: want %v, got %v", i, want, got)
260
+		}
261
+	}
262
+}