Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: limit size of the machine string #2385

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 135 additions & 47 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2034,104 +2034,185 @@
}

func (m *Machine) String() string {
const (
maxSliceElements = 32
avgBlocksSize = 1024
avgLineSize = 32

// This is an approximation using the max slice elements we will process; it follows
// the calculation below: 5 slices sizes multiplied by 32 + 1024 + maxSliceElements again
// for exceptions.
maxBuilderBufferSize = 5*maxSliceElements*avgLineSize + avgBlocksSize + maxSliceElements
)

Check warning on line 2047 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2046-L2047

Added lines #L2046 - L2047 were not covered by tests
// Calculate some reasonable total length to avoid reallocation
// Assuming an average length of 32 characters per string
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
vsLength = m.NumValues * avgLineSize
ssLength = len(m.Stmts) * avgLineSize

Check warning on line 2052 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2051-L2052

Added lines #L2051 - L2052 were not covered by tests
xsLength = len(m.Exprs) * avgLineSize
bsLength = avgBlocksSize
obsLength = len(m.Blocks) * avgLineSize
fsLength = len(m.Frames) * avgLineSize

Check warning on line 2056 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2056

Added line #L2056 was not covered by tests
exceptionsLength = len(m.Exceptions)

totalLength = vsLength + ssLength + xsLength + bsLength + obsLength + fsLength + exceptionsLength
)

if totalLength > maxBuilderBufferSize {

Check warning on line 2062 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2062

Added line #L2062 was not covered by tests
totalLength = maxBuilderBufferSize
}

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))
builder.WriteString(fmt.Sprintf("Machine:\n CheckTypes: %t\n", m.CheckTypes))
builder.WriteString(" Op: [")

Check warning on line 2070 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2069-L2070

Added lines #L2069 - L2070 were not covered by tests

var startOpIdx int
if m.NumOps > maxSliceElements {

Check warning on line 2073 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2073

Added line #L2073 was not covered by tests
// Only print the last maxSliceElements. Print the very first op as well.
startOpIdx = m.NumOps - maxSliceElements
builder.WriteString(fmt.Sprintf("%v ... ", m.Ops[0]))

Check warning on line 2076 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2075-L2076

Added lines #L2075 - L2076 were not covered by tests
}

Check warning on line 2078 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2078

Added line #L2078 was not covered by tests
for _, op := range m.Ops[startOpIdx:m.NumOps] {
builder.WriteString(fmt.Sprintf("%v ", op))
}
builder.WriteString("]\n")
builder.WriteString(fmt.Sprintf(" Values: (len: %d)\n", m.NumValues))

Check warning on line 2083 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2082-L2083

Added lines #L2082 - L2083 were not covered by tests

for i := m.NumValues - 1; i >= 0; i-- {
var i, count int
for i = m.NumValues - 1; i >= 0 && count < maxSliceElements; i-- {
builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Values[i]))
count++
}

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")

Check warning on line 2092 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2092

Added line #L2092 was not covered by tests
builder.WriteString(fmt.Sprintf(" #%d %v\n", 0, m.Values[0]))
}

builder.WriteString(" Exprs:\n")

for i := len(m.Exprs) - 1; i >= 0; i-- {
count, i = 0, 0
for i = len(m.Exprs) - 1; i >= 0 && count < maxSliceElements; i-- {

Check warning on line 2099 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2098-L2099

Added lines #L2098 - L2099 were not covered by tests
builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Exprs[i]))
count++
}

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")
builder.WriteString(fmt.Sprintf(" #%d %v\n", 0, m.Exprs[0]))

Check warning on line 2106 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2101-L2106

Added lines #L2101 - L2106 were not covered by tests
}

builder.WriteString(" Stmts:\n")

for i := len(m.Stmts) - 1; i >= 0; i-- {
count, i = 0, 0
for i = len(m.Stmts) - 1; i >= 0 && count < maxSliceElements; i-- {

Check warning on line 2112 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2111-L2112

Added lines #L2111 - L2112 were not covered by tests
builder.WriteString(fmt.Sprintf(" #%d %v\n", i, m.Stmts[i]))
count++
}

Check warning on line 2115 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2114-L2115

Added lines #L2114 - L2115 were not covered by tests

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")
builder.WriteString(fmt.Sprintf(" #%d %v\n", 0, m.Stmts[0]))

Check warning on line 2119 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2117-L2119

Added lines #L2117 - L2119 were not covered by tests
}

builder.WriteString(" Blocks:\n")

for b := m.LastBlock(); b != nil; {
gen := builder.Len()/3 + 1
gens := "@" // strings.Repeat("@", gen)
count = 0
b := m.LastBlock()
printBlocks := func() {
for b != nil && count < maxSliceElements {
gen := builder.Len()/3 + 1
gens := "@" // strings.Repeat("@", gen)

if pv, ok := b.Source.(*PackageNode); ok {

Check warning on line 2131 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2124-L2131

Added lines #L2124 - L2131 were not covered by tests
// package blocks have too much, so just
// print the pkgpath.
builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, pv.PkgPath))
} else {
bsi := b.StringIndented(" ")
builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, bsi))

Check warning on line 2137 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2134-L2137

Added lines #L2134 - L2137 were not covered by tests

if pv, ok := b.Source.(*PackageNode); ok {
// package blocks have too much, so just
// print the pkgpath.
builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, pv.PkgPath))
} else {
bsi := b.StringIndented(" ")
builder.WriteString(fmt.Sprintf(" %s(%d) %s\n", gens, gen, bsi))
if b.Source != nil {
sb := b.GetSource(m.Store).GetStaticBlock().GetBlock()
builder.WriteString(fmt.Sprintf(" (s vals) %s(%d) %s\n", gens, gen, sb.StringIndented(" ")))

Check warning on line 2141 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2139-L2141

Added lines #L2139 - L2141 were not covered by tests

if b.Source != nil {
sb := b.GetSource(m.Store).GetStaticBlock().GetBlock()
builder.WriteString(fmt.Sprintf(" (s vals) %s(%d) %s\n", gens, gen, sb.StringIndented(" ")))
sts := b.GetSource(m.Store).GetStaticBlock().Types
builder.WriteString(fmt.Sprintf(" (s typs) %s(%d) %s\n", gens, gen, sts))

Check warning on line 2144 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2143-L2144

Added lines #L2143 - L2144 were not covered by tests
}
}

Check warning on line 2146 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2146

Added line #L2146 was not covered by tests

sts := b.GetSource(m.Store).GetStaticBlock().Types
builder.WriteString(fmt.Sprintf(" (s typs) %s(%d) %s\n", gens, gen, sts))
// Update b
switch bp := b.Parent.(type) {
case nil:
b = nil
case *Block:
b = bp
case RefValue:
builder.WriteString(fmt.Sprintf(" (block ref %v)\n", bp.ObjectID))
b = nil
default:
panic(fmt.Sprintf("unexpected block parent type %T", bp))

Check warning on line 2158 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2149-L2158

Added lines #L2149 - L2158 were not covered by tests
}
}

// Update b
switch bp := b.Parent.(type) {
case nil:
b = nil
case *Block:
b = bp
case RefValue:
builder.WriteString(fmt.Sprintf(" (block ref %v)\n", bp.ObjectID))
b = nil
default:
panic("should not happen")
count++

Check warning on line 2161 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2161

Added line #L2161 was not covered by tests
}
}

printBlocks()
if b != nil { // loop exited due to count
builder.WriteString(" ...\n")
b = m.Blocks[0]
printBlocks()
}

Check warning on line 2171 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2165-L2171

Added lines #L2165 - L2171 were not covered by tests
builder.WriteString(" Blocks (other):\n")

for i := len(m.Blocks) - 2; i >= 0; i-- {
b := m.Blocks[i]
printOtherBlock := func(idx int, skipPkgNode bool) {
b := m.Blocks[idx]

Check warning on line 2175 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2174-L2175

Added lines #L2174 - L2175 were not covered by tests

if b == nil || b.Source == nil {
continue
return

Check warning on line 2178 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2178

Added line #L2178 was not covered by tests
}

if _, ok := b.Source.(*PackageNode); ok {
break // done, skip *PackageNode.
if _, ok := b.Source.(*PackageNode); ok && skipPkgNode {
return // done, skip *PackageNode.

Check warning on line 2182 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2181-L2182

Added lines #L2181 - L2182 were not covered by tests
} else {
builder.WriteString(fmt.Sprintf(" #%d %s\n", i,
builder.WriteString(fmt.Sprintf(" #%d %s\n", idx,

Check warning on line 2184 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2184

Added line #L2184 was not covered by tests
b.StringIndented(" ")))
if b.Source != nil {
sb := b.GetSource(m.Store).GetStaticBlock().GetBlock()
builder.WriteString(fmt.Sprintf(" (static) #%d %s\n", i,
builder.WriteString(fmt.Sprintf(" (static) #%d %s\n", idx,

Check warning on line 2188 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2188

Added line #L2188 was not covered by tests
sb.StringIndented(" ")))
}
}
}

count, i = 0, 0
for i = len(m.Blocks) - 2; i >= 0 && count < maxSliceElements; i-- {
printOtherBlock(i, true)
count++
}

Check warning on line 2198 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2194-L2198

Added lines #L2194 - L2198 were not covered by tests

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")
printOtherBlock(0, false)
}

Check warning on line 2203 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2200-L2203

Added lines #L2200 - L2203 were not covered by tests

builder.WriteString(" Frames:\n")

for i := len(m.Frames) - 1; i >= 0; i-- {
count, i = 0, 0
for i = len(m.Frames) - 1; i >= 0 && count < maxSliceElements; i-- {

Check warning on line 2208 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2207-L2208

Added lines #L2207 - L2208 were not covered by tests
builder.WriteString(fmt.Sprintf(" #%d %s\n", i, m.Frames[i]))
count++
}

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")
builder.WriteString(fmt.Sprintf(" #%d %s\n", 0, m.Frames[0]))

Check warning on line 2215 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2210-L2215

Added lines #L2210 - L2215 were not covered by tests
}

if m.Realm != nil {
Expand All @@ -2140,8 +2221,15 @@

builder.WriteString(" Exceptions:\n")

for _, ex := range m.Exceptions {
builder.WriteString(fmt.Sprintf(" %s\n", ex.Sprint(m)))
count, i = 0, 0
for i = len(m.Exceptions) - 1; i >= 0 && count < maxSliceElements; i-- {
builder.WriteString(fmt.Sprintf(" #%d %s\n", i, m.Exceptions[i].Sprint(m)))
count++
}

Check warning on line 2228 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2224-L2228

Added lines #L2224 - L2228 were not covered by tests

if i >= 0 { // loop exited due to count
builder.WriteString(" ...\n")
builder.WriteString(fmt.Sprintf(" #%d %s\n", 0, m.Exceptions[0].Sprint(m)))

Check warning on line 2232 in gnovm/pkg/gnolang/machine.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/machine.go#L2230-L2232

Added lines #L2230 - L2232 were not covered by tests
}

return builder.String()
Expand Down
Loading