Skip to content

Commit

Permalink
use object addresses as unique IDs
Browse files Browse the repository at this point in the history
Using a global counter for unique IDs means that eventually, every long-running program will reuse IDs of live objects. Go's garbage collection currently is not compacting; if it ever becomes so, we can modify contains.Set or choose a new method to obtain unique IDs.
  • Loading branch information
zephyrtronium committed Apr 12, 2020
1 parent 74fd6fe commit 0ef0f0e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 30 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.14
require (
github.com/zephyrtronium/contains v0.0.0-20191109101209-403ebe7b0b60
gitlab.com/variadico/lctime v0.0.0-20190211022338-49aae8a53d11
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa
golang.org/x/text v0.3.2
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef
gopkg.in/yaml.v2 v2.2.8
)
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/zephyrtronium/contains v0.0.0-20190813150354-f7df53f08000 h1:rsL4vYsl1EVDklYnVDq2etRQv7jZtFu2gkv4OzKKFbo=
github.com/zephyrtronium/contains v0.0.0-20190813150354-f7df53f08000/go.mod h1:9VfULMvEEtBLQ93TyMwEFa2rMZj232ZMs7HA/dx31Eg=
github.com/zephyrtronium/contains v0.0.0-20191109101209-403ebe7b0b60 h1:spBs4SQ3oIUAGBh3fZLGWjQ6iAiEtmxmM5o68l5mTH8=
Expand All @@ -7,6 +8,7 @@ gitlab.com/variadico/lctime v0.0.0-20190211022338-49aae8a53d11 h1:Ly1b+G8N/Hhmty
gitlab.com/variadico/lctime v0.0.0-20190211022338-49aae8a53d11/go.mod h1:oBjcCtUE+aWYiW4NuGN+eK3OK3efpcyKphbDv1Y508M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -19,6 +21,8 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPT
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand All @@ -29,8 +33,11 @@ golang.org/x/tools v0.0.0-20191101200257-8dbcdeb83d3f/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8 h1:gkI/wGGwpcG5W4hLCzZNGxA4wzWBGGDStRI1MrjDl2Q=
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef h1:RHORRhs540cYZYrzgU2CPUyykkwZM78hGdzocOo9P8A=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
26 changes: 5 additions & 21 deletions internal/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ import (
"os"
"strings"
"sync"
"sync/atomic"
"time"
"unsafe" // for UniqueID

"github.com/zephyrtronium/contains"
)

// Object is the basic type of Io. Everything is an Object.
//
// Always use NewObject, ObjectWith, or a type-specific constructor to obtain
// new objects. Creating objects directly will result in arbitrary failures.
type Object struct {
// slots is the set of messages to which this object responds.
slots actualSlots
Expand All @@ -29,9 +26,6 @@ type Object struct {
Value interface{}
// tag is the type indicator of the object.
tag Tag

// id is the object's unique ID.
id uintptr
}

// Tag is a type indicator for iolang objects. Tag values must be comparable.
Expand Down Expand Up @@ -86,7 +80,6 @@ func (o *Object) Clone() *Object {
protos: protoLink{p: o},
Value: v,
tag: o.Tag(),
id: nextObject(),
}
}

Expand Down Expand Up @@ -125,7 +118,10 @@ func (o *Object) Tag() Tag {

// UniqueID returns the object's unique ID.
func (o *Object) UniqueID() uintptr {
return o.id
// This implementation depends on Go's garbage collector remaining
// non-compacting. Should that change, then either this or contains.Set
// will need to change as well.
return uintptr(unsafe.Pointer(o))
}

// BasicTag is a special Tag type for basic primitive types which do not have
Expand All @@ -148,16 +144,6 @@ func (t BasicTag) String() string {
return string(t)
}

// objcounter is the global counter for object IDs. All accesses to this must
// be atomic.
var objcounter uintptr

// nextObject increments the object counter and returns its value as a unique
// ID for a new object.
func nextObject() uintptr {
return atomic.AddUintptr(&objcounter, 1)
}

// initObject sets up the "base" object that is the first proto of all other
// built-in types.
func (vm *VM) initObject() {
Expand Down Expand Up @@ -254,7 +240,6 @@ func (vm *VM) ObjectWith(slots Slots, protos []*Object, value interface{}, tag T
r := &Object{
Value: value,
tag: tag,
id: nextObject(),
}
r.SetProtos(protos...)
vm.definitelyNewSlots(r, slots)
Expand All @@ -266,7 +251,6 @@ func (vm *VM) ObjectWith(slots Slots, protos []*Object, value interface{}, tag T
func (vm *VM) NewObject(slots Slots) *Object {
r := &Object{
protos: protoLink{p: vm.BaseObject},
id: nextObject(),
}
vm.definitelyNewSlots(r, slots)
return r
Expand Down
14 changes: 7 additions & 7 deletions internal/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ func NewVM(args ...string) *VM {
haveVM = true // TODO: atomic?

vm := VM{
Lobby: &Object{id: nextObject()},
Lobby: &Object{},

Core: &Object{id: nextObject()},
Addons: &Object{id: nextObject()},
Core: &Object{},
Addons: &Object{},

BaseObject: &Object{id: nextObject()},
True: &Object{id: nextObject()},
False: &Object{id: nextObject()},
Nil: &Object{id: nextObject()},
BaseObject: &Object{},
True: &Object{},
False: &Object{},
Nil: &Object{},

Control: make(chan RemoteStop, 1),

Expand Down

0 comments on commit 0ef0f0e

Please sign in to comment.