AST Tweaks (#551)

* Use pointers instead of copying around ast.Node

Node is a 56B struct that is constantly in the hot path. Passing nodes
around by copy had a cost that started to add up. This change replaces
them by pointers. Using unsafe pointer arithmetic and converting
sibling/child indexes to relative offsets, it removes the need to carry
around a pointer to the root of the tree. This saves 8B per Node. This
space will be used to store an extra []byte slice to provide contextual
error handling on all nodes, including the ones whose data is different
than the raw input (for example: strings with escaped characters), while
staying under the size of a cache line.

* Remove conditional

* Add Raw to track range in data for parsed values

* Simplify reference tracking
This commit is contained in:
Thomas Pelletier
2021-06-03 21:48:51 -04:00
committed by GitHub
parent f3bb20ea79
commit 618f0181ac
13 changed files with 239 additions and 165 deletions
+9 -9
View File
@@ -2,8 +2,8 @@ package toml
import (
"github.com/pelletier/go-toml/v2/internal/ast"
"github.com/pelletier/go-toml/v2/internal/danger"
"github.com/pelletier/go-toml/v2/internal/tracker"
"github.com/pelletier/go-toml/v2/internal/unsafe"
)
type strict struct {
@@ -15,7 +15,7 @@ type strict struct {
missing []decodeError
}
func (s *strict) EnterTable(node ast.Node) {
func (s *strict) EnterTable(node *ast.Node) {
if !s.Enabled {
return
}
@@ -23,7 +23,7 @@ func (s *strict) EnterTable(node ast.Node) {
s.key.UpdateTable(node)
}
func (s *strict) EnterArrayTable(node ast.Node) {
func (s *strict) EnterArrayTable(node *ast.Node) {
if !s.Enabled {
return
}
@@ -31,7 +31,7 @@ func (s *strict) EnterArrayTable(node ast.Node) {
s.key.UpdateArrayTable(node)
}
func (s *strict) EnterKeyValue(node ast.Node) {
func (s *strict) EnterKeyValue(node *ast.Node) {
if !s.Enabled {
return
}
@@ -39,7 +39,7 @@ func (s *strict) EnterKeyValue(node ast.Node) {
s.key.Push(node)
}
func (s *strict) ExitKeyValue(node ast.Node) {
func (s *strict) ExitKeyValue(node *ast.Node) {
if !s.Enabled {
return
}
@@ -47,7 +47,7 @@ func (s *strict) ExitKeyValue(node ast.Node) {
s.key.Pop(node)
}
func (s *strict) MissingTable(node ast.Node) {
func (s *strict) MissingTable(node *ast.Node) {
if !s.Enabled {
return
}
@@ -59,7 +59,7 @@ func (s *strict) MissingTable(node ast.Node) {
})
}
func (s *strict) MissingField(node ast.Node) {
func (s *strict) MissingField(node *ast.Node) {
if !s.Enabled {
return
}
@@ -88,7 +88,7 @@ func (s *strict) Error(doc []byte) error {
return err
}
func keyLocation(node ast.Node) []byte {
func keyLocation(node *ast.Node) []byte {
k := node.Key()
hasOne := k.Next()
@@ -103,5 +103,5 @@ func keyLocation(node ast.Node) []byte {
end = k.Node().Data
}
return unsafe.BytesRange(start, end)
return danger.BytesRange(start, end)
}