i am testing and experimenting with where in go objects are on the stack vs the heap. I understand why the jsonBlob is put on the heap because its passed by reference and could be modified later. in the below example i would expect the
<code>a := Animal{}
</code>
<code>a := Animal{}
</code>
a := Animal{}
to be on the stack but the -m build says otherwise. is anyone able to explain the Unmarshall or if there is a json parse way that can be pure stack based.
<code>import (
"encoding/json"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type Animal struct {
age int
}
func main() {
// UNIX Time is faster and smaller than most timestamps
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().Msg("app start")
jsonBlob := []byte(`{"age": 1}`)
intOnStack := 1
log.Info().Int("inty", intOnStack).Msg("intOnStaci: ")
animal := perform(jsonBlob)
log.Info().Int("age", animal).Msg("animal")
}
func perform(jsonData []byte) int {
a := Animal{}
err := json.Unmarshal(jsonData, &a)
if err != nil {
log.Error().Err(err).Msg("error unmarshalling json")
}
return a.age
}
</code>
<code>import (
"encoding/json"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type Animal struct {
age int
}
func main() {
// UNIX Time is faster and smaller than most timestamps
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().Msg("app start")
jsonBlob := []byte(`{"age": 1}`)
intOnStack := 1
log.Info().Int("inty", intOnStack).Msg("intOnStaci: ")
animal := perform(jsonBlob)
log.Info().Int("age", animal).Msg("animal")
}
func perform(jsonData []byte) int {
a := Animal{}
err := json.Unmarshal(jsonData, &a)
if err != nil {
log.Error().Err(err).Msg("error unmarshalling json")
}
return a.age
}
</code>
import (
"encoding/json"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type Animal struct {
age int
}
func main() {
// UNIX Time is faster and smaller than most timestamps
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Info().Msg("app start")
jsonBlob := []byte(`{"age": 1}`)
intOnStack := 1
log.Info().Int("inty", intOnStack).Msg("intOnStaci: ")
animal := perform(jsonBlob)
log.Info().Int("age", animal).Msg("animal")
}
func perform(jsonData []byte) int {
a := Animal{}
err := json.Unmarshal(jsonData, &a)
if err != nil {
log.Error().Err(err).Msg("error unmarshalling json")
}
return a.age
}
this is the build output
<code>go build -gcflags "-m" main-simple.go
# command-line-arguments
./main-simple.go:38:12: inlining call to log.Error
./main-simple.go:38:27: inlining call to zerolog.(*Event).Msg
./main-simple.go:38:12: inlining call to zerolog.(*Logger).Error
./main-simple.go:24:10: inlining call to log.Info
./main-simple.go:24:16: inlining call to zerolog.(*Event).Msg
./main-simple.go:28:10: inlining call to log.Info
./main-simple.go:28:40: inlining call to zerolog.(*Event).Msg
./main-simple.go:31:10: inlining call to log.Info
./main-simple.go:31:35: inlining call to zerolog.(*Event).Msg
./main-simple.go:24:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:28:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:31:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:34:14: leaking param: jsonData
./main-simple.go:35:2: moved to heap: a
./main-simple.go:25:21: ([]byte)(`{"age": 1}`) escapes to heap
</code>
<code>go build -gcflags "-m" main-simple.go
# command-line-arguments
./main-simple.go:38:12: inlining call to log.Error
./main-simple.go:38:27: inlining call to zerolog.(*Event).Msg
./main-simple.go:38:12: inlining call to zerolog.(*Logger).Error
./main-simple.go:24:10: inlining call to log.Info
./main-simple.go:24:16: inlining call to zerolog.(*Event).Msg
./main-simple.go:28:10: inlining call to log.Info
./main-simple.go:28:40: inlining call to zerolog.(*Event).Msg
./main-simple.go:31:10: inlining call to log.Info
./main-simple.go:31:35: inlining call to zerolog.(*Event).Msg
./main-simple.go:24:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:28:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:31:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:34:14: leaking param: jsonData
./main-simple.go:35:2: moved to heap: a
./main-simple.go:25:21: ([]byte)(`{"age": 1}`) escapes to heap
</code>
go build -gcflags "-m" main-simple.go
# command-line-arguments
./main-simple.go:38:12: inlining call to log.Error
./main-simple.go:38:27: inlining call to zerolog.(*Event).Msg
./main-simple.go:38:12: inlining call to zerolog.(*Logger).Error
./main-simple.go:24:10: inlining call to log.Info
./main-simple.go:24:16: inlining call to zerolog.(*Event).Msg
./main-simple.go:28:10: inlining call to log.Info
./main-simple.go:28:40: inlining call to zerolog.(*Event).Msg
./main-simple.go:31:10: inlining call to log.Info
./main-simple.go:31:35: inlining call to zerolog.(*Event).Msg
./main-simple.go:24:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:28:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:31:10: inlining call to zerolog.(*Logger).Info
./main-simple.go:34:14: leaking param: jsonData
./main-simple.go:35:2: moved to heap: a
./main-simple.go:25:21: ([]byte)(`{"age": 1}`) escapes to heap