From 79ebf5a1e0c1b7aefad8f8d3c28f059508520f66 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Mon, 29 Apr 2024 13:42:56 +0200 Subject: [PATCH 1/3] save --- gnovm/pkg/gnolang/machine.go | 121 +++++++++++++++-------------------- gnovm/pkg/gnolang/values.go | 2 +- 2 files changed, 51 insertions(+), 72 deletions(-) diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 018fac66e64..db5e967f05c 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -2024,117 +2024,96 @@ func (m *Machine) Printf(format string, args ...interface{}) { } func (m *Machine) String() string { - vs := []string{} + // Calculate some reasonable total length to avoid reallocation + // Assuming an average length of 32 characters per string + vsLength := m.NumValues * 32 + ssLength := len(m.Stmts) * 32 + xsLength := len(m.Exprs) * 32 + bsLength := 1024 + obsLength := len(m.Blocks) * 32 + fsLength := len(m.Frames) * 32 + exceptionsLength := len(m.Exceptions) + + totalLength := vsLength + ssLength + xsLength + bsLength + obsLength + fsLength + exceptionsLength + + var builder strings.Builder + builder.Grow(totalLength) + + builder.WriteString(fmt.Sprintf("Machine:\n CheckTypes: %v\n Op: %v\n Values: (len: %d)\n", m.CheckTypes, m.Ops[:m.NumOps], m.NumValues)) + for i := m.NumValues - 1; i >= 0; i-- { - v := m.Values[i] - vs = append(vs, fmt.Sprintf(" #%d %v", i, v)) + builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Values[i])) } - ss := []string{} - for i := len(m.Stmts) - 1; i >= 0; i-- { - s := m.Stmts[i] - ss = append(ss, fmt.Sprintf(" #%d %v", i, s)) - } - xs := []string{} + for i := len(m.Exprs) - 1; i >= 0; i-- { - x := m.Exprs[i] - xs = append(xs, fmt.Sprintf(" #%d %v", i, x)) + builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Exprs[i])) } - bs := []string{} + + for i := len(m.Stmts) - 1; i >= 0; i-- { + builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Stmts[i])) + } + for b := m.LastBlock(); b != nil; { - gen := len(bs)/3 + 1 + gen := builder.Len()/3 + 1 gens := "@" // strings.Repeat("@", gen) + if pv, ok := b.Source.(*PackageNode); ok { // package blocks have too much, so just // print the pkgpath. - bs = append(bs, fmt.Sprintf(" %s(%d) %s", gens, gen, pv.PkgPath)) + builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, pv.PkgPath)) } else { bsi := b.StringIndented(" ") - bs = append(bs, fmt.Sprintf(" %s(%d) %s", gens, gen, bsi)) + builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, bsi)) + if b.Source != nil { sb := b.GetSource(m.Store).GetStaticBlock().GetBlock() - bs = append(bs, fmt.Sprintf(" (s vals) %s(%d) %s", gens, gen, - sb.StringIndented(" "))) + builder.WriteString(fmt.Sprintf(" (s vals) %s(%d) %s\n", gens, gen, sb.StringIndented(" "))) + sts := b.GetSource(m.Store).GetStaticBlock().Types - bs = append(bs, fmt.Sprintf(" (s typs) %s(%d) %s", gens, gen, - sts)) + builder.WriteString(fmt.Sprintf(" (s typs) %s(%d) %s\n", gens, gen, sts)) } } - // b = b.Parent.(*Block|RefValue) + + // Update b switch bp := b.Parent.(type) { case nil: b = nil - break case *Block: b = bp case RefValue: - bs = append(bs, fmt.Sprintf(" (block ref %v)", bp.ObjectID)) + builder.WriteString(fmt.Sprintf(" (block ref %v)\n", bp.ObjectID)) b = nil - break default: panic("should not happen") } } - obs := []string{} + for i := len(m.Blocks) - 2; i >= 0; i-- { b := m.Blocks[i] if _, ok := b.Source.(*PackageNode); ok { break // done, skip *PackageNode. } else { - obs = append(obs, fmt.Sprintf(" #%d %s", i, + builder.WriteString(fmt.Sprintf(" #%d %s", i, b.StringIndented(" "))) if b.Source != nil { sb := b.GetSource(m.Store).GetStaticBlock().GetBlock() - obs = append(obs, fmt.Sprintf(" (static) #%d %s", i, + builder.WriteString(fmt.Sprintf(" (static) #%d %s", i, sb.StringIndented(" "))) } } } - fs := []string{} + for i := len(m.Frames) - 1; i >= 0; i-- { - fr := m.Frames[i] - fs = append(fs, fmt.Sprintf(" #%d %s", i, fr.String())) - } - rlmpath := "" - if m.Realm != nil { - rlmpath = m.Realm.Path - } - exceptions := make([]string, len(m.Exceptions)) - for i, ex := range m.Exceptions { - exceptions[i] = ex.Sprint(m) - } - return fmt.Sprintf(`Machine: - CheckTypes: %v - Op: %v - Values: (len: %d) -%s - Exprs: -%s - Stmts: -%s - Blocks: -%s - Blocks (other): -%s - Frames: -%s - Realm: - %s - Exceptions: - %s - %s`, - m.CheckTypes, - m.Ops[:m.NumOps], - m.NumValues, - strings.Join(vs, "\n"), - strings.Join(xs, "\n"), - strings.Join(ss, "\n"), - strings.Join(bs, "\n"), - strings.Join(obs, "\n"), - strings.Join(fs, "\n"), - rlmpath, - m.Exceptions, - strings.Join(exceptions, "\n"), - ) + builder.WriteString(fmt.Sprintf(" #%d %s\n", i, m.Frames[i])) + } + + builder.WriteString(fmt.Sprintf(" Realm:\n %s\n", m.Realm.Path)) + + for _, ex := range m.Exceptions { + builder.WriteString(fmt.Sprintf(" %s\n", ex.Sprint(m))) + } + + return builder.String() } //---------------------------------------- diff --git a/gnovm/pkg/gnolang/values.go b/gnovm/pkg/gnolang/values.go index ae5ac7fd40b..bc9af8e1a32 100644 --- a/gnovm/pkg/gnolang/values.go +++ b/gnovm/pkg/gnolang/values.go @@ -2284,7 +2284,7 @@ func (b *Block) StringIndented(indent string) string { if len(source) > 32 { source = source[:32] + "..." } - lines := []string{} + lines := make([]string, 0, 3) lines = append(lines, fmt.Sprintf("Block(ID:%v,Addr:%p,Source:%s,Parent:%p)", b.ObjectInfo.ID, b, source, b.Parent)) // XXX Parent may be RefValue{}. From d55989f4f35d0da20673041c4bdbaa2f94e234b6 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Tue, 30 Apr 2024 13:26:10 +0200 Subject: [PATCH 2/3] save --- gnovm/pkg/gnolang/gno_test.go | 23 +++++++++++++++++++++++ gnovm/pkg/gnolang/machine.go | 9 ++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index dca2d0d9757..1a779322def 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -17,6 +17,29 @@ import ( "github.com/stretchr/testify/require" ) +func setupMachine(numValues, numStmts, numExprs, numBlocks, numFrames, numExceptions int) *Machine { + m := &Machine{ + Ops: make([]Op, 100), + NumOps: 100, + Values: make([]TypedValue, numValues), + NumValues: numValues, + Exprs: make([]Expr, numExprs), + Stmts: make([]Stmt, numStmts), + Blocks: make([]*Block, numBlocks), + Frames: make([]*Frame, numFrames), + Exceptions: make([]Exception, numExceptions), + } + return m +} + +func BenchmarkStringLargeData(b *testing.B) { + m := setupMachine(10000, 5000, 5000, 2000, 3000, 1000) + + for i := 0; i < b.N; i++ { + _ = m.String() + } +} + func TestRunInvalidLabels(t *testing.T) { tests := []struct { code string diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index db5e967f05c..95d7b962bf4 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -2090,6 +2090,11 @@ func (m *Machine) String() string { for i := len(m.Blocks) - 2; i >= 0; i-- { b := m.Blocks[i] + + if b == nil || b.Source == nil { + continue + } + if _, ok := b.Source.(*PackageNode); ok { break // done, skip *PackageNode. } else { @@ -2107,7 +2112,9 @@ func (m *Machine) String() string { builder.WriteString(fmt.Sprintf(" #%d %s\n", i, m.Frames[i])) } - builder.WriteString(fmt.Sprintf(" Realm:\n %s\n", m.Realm.Path)) + if m.Realm != nil { + builder.WriteString(fmt.Sprintf(" Realm:\n %s\n", m.Realm.Path)) + } for _, ex := range m.Exceptions { builder.WriteString(fmt.Sprintf(" %s\n", ex.Sprint(m))) From 20ea949f1364b5c72b30fa66cf22885653a61dd4 Mon Sep 17 00:00:00 2001 From: Petar Dambovaliev Date: Fri, 3 May 2024 17:44:10 +0200 Subject: [PATCH 3/3] save --- gnovm/pkg/gnolang/gno_test.go | 6 ++++-- gnovm/pkg/gnolang/machine.go | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index 1a779322def..95c4ec7a84c 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -17,7 +17,9 @@ import ( "github.com/stretchr/testify/require" ) -func setupMachine(numValues, numStmts, numExprs, numBlocks, numFrames, numExceptions int) *Machine { +func setupMachine(b *testing.B, numValues, numStmts, numExprs, numBlocks, numFrames, numExceptions int) *Machine { + b.Helper() + m := &Machine{ Ops: make([]Op, 100), NumOps: 100, @@ -33,7 +35,7 @@ func setupMachine(numValues, numStmts, numExprs, numBlocks, numFrames, numExcept } func BenchmarkStringLargeData(b *testing.B) { - m := setupMachine(10000, 5000, 5000, 2000, 3000, 1000) + m := setupMachine(b, 10000, 5000, 5000, 2000, 3000, 1000) for i := 0; i < b.N; i++ { _ = m.String() diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index 95d7b962bf4..69210570c0d 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -2026,15 +2026,17 @@ func (m *Machine) Printf(format string, args ...interface{}) { func (m *Machine) String() string { // Calculate some reasonable total length to avoid reallocation // Assuming an average length of 32 characters per string - vsLength := m.NumValues * 32 - ssLength := len(m.Stmts) * 32 - xsLength := len(m.Exprs) * 32 - bsLength := 1024 - obsLength := len(m.Blocks) * 32 - fsLength := len(m.Frames) * 32 - exceptionsLength := len(m.Exceptions) - - totalLength := vsLength + ssLength + xsLength + bsLength + obsLength + fsLength + exceptionsLength + var ( + vsLength = m.NumValues * 32 + ssLength = len(m.Stmts) * 32 + xsLength = len(m.Exprs) * 32 + bsLength = 1024 + obsLength = len(m.Blocks) * 32 + fsLength = len(m.Frames) * 32 + exceptionsLength = len(m.Exceptions) + + totalLength = vsLength + ssLength + xsLength + bsLength + obsLength + fsLength + exceptionsLength + ) var builder strings.Builder builder.Grow(totalLength)