Skip to content

Commit

Permalink
fix(vm): Release VM properly (gnolang#1116)
Browse files Browse the repository at this point in the history
Properly clean slices using make (the internal logic is expecting slices
to not be nil).

It closes gnolang#1033

- [X] Added new tests, or not needed, or not feasible
- [X] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [X] Updated the official documentation or not needed
- [X] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [X] Added references to related issues and PRs
- [X] Provided any useful hints for running manual tests
- [X] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).

---------

Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com>
Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com>
  • Loading branch information
2 people authored and gfanton committed Nov 9, 2023
1 parent 5f7141e commit e3a54fe
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
42 changes: 18 additions & 24 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ type MachineOptions struct {
var machinePool = sync.Pool{
New: func() interface{} {
return &Machine{
Ops: make([]Op, OpSize),
Values: make([]TypedValue, ValueSize),
Ops: make([]Op, VMSliceSize),
Values: make([]TypedValue, VMSliceSize),
}
},
}
Expand Down Expand Up @@ -117,20 +117,14 @@ func NewMachineWithOptions(opts MachineOptions) *Machine {
}
context := opts.Context
mm := machinePool.Get().(*Machine)
*mm = Machine{
Ops: mm.Ops,
NumOps: 0,
Values: mm.Values,
NumValues: 0,
Package: pv,
Alloc: alloc,
CheckTypes: checkTypes,
ReadOnly: readOnly,
MaxCycles: maxCycles,
Output: output,
Store: store,
Context: context,
}
mm.Package = pv
mm.Alloc = alloc
mm.CheckTypes = checkTypes
mm.ReadOnly = readOnly
mm.MaxCycles = maxCycles
mm.Output = output
mm.Store = store
mm.Context = context

if pv != nil {
mm.SetActivePackage(pv)
Expand All @@ -139,13 +133,12 @@ func NewMachineWithOptions(opts MachineOptions) *Machine {
}

const (
OpSize = 1024
ValueSize = 1024
VMSliceSize = 1024
)

var (
opZeroed [OpSize]Op
valueZeroed [ValueSize]TypedValue
opZeroed [VMSliceSize]Op
valueZeroed [VMSliceSize]TypedValue
)

// m should not be used after this call
Expand All @@ -154,13 +147,14 @@ var (
// and prevent objects that were not taken from
// the pool, to call Release
func (m *Machine) Release() {
// copy()
// here we zero in the values for the next user
m.NumOps = 0
m.NumValues = 0
// this is the fastest way to zero-in a slice in Go
copy(m.Ops, opZeroed[:])
copy(m.Values, valueZeroed[:])

ops, values := m.Ops[:VMSliceSize:VMSliceSize], m.Values[:VMSliceSize:VMSliceSize]
copy(ops, opZeroed[:])
copy(values, valueZeroed[:])
*m = Machine{Ops: ops, Values: values}

machinePool.Put(m)
}
Expand Down
10 changes: 10 additions & 0 deletions gnovm/pkg/gnolang/machine_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package gnolang

import "testing"

func BenchmarkCreateNewMachine(b *testing.B) {
for i := 0; i < b.N; i++ {
m := NewMachineWithOptions(MachineOptions{})
m.Release()
}
}

0 comments on commit e3a54fe

Please sign in to comment.