Skip to content

Commit

Permalink
REALMC-7452 implement memory usage (dop251#2)
Browse files Browse the repository at this point in the history
* REALMC-7452 implement memory usage
  • Loading branch information
arahmanan authored Dec 21, 2020
1 parent c84a696 commit 65dd408
Show file tree
Hide file tree
Showing 16 changed files with 810 additions and 361 deletions.
24 changes: 17 additions & 7 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,24 +634,34 @@ func strToGoIdx(s unistring.String) int {
}

func (a *arrayObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
total := SizeEmpty
if a == nil || ctx.IsObjVisited(a) {
return SizeEmpty, nil
}
ctx.VisitObj(a)

// inc, err := a.baseObject.MemUsage(ctx)
// total += inc
// if err != nil {
// return total, err
// }
inc, err := a.lengthProp.MemUsage(ctx)
total := SizeEmpty
inc, err := a.baseObject.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}

if err := ctx.Descend(); err != nil {
return total, err
}

for _, v := range a.values {
if v == nil {
continue
}

inc, err := v.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}
}

ctx.Ascend()
return total, nil
}
28 changes: 27 additions & 1 deletion array_sparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,5 +453,31 @@ func (a *sparseArrayObject) exportType() reflect.Type {
}

func (a *sparseArrayObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
return SizeEmpty, nil
if a == nil || ctx.IsObjVisited(a) {
return SizeEmpty, nil
}
ctx.VisitObj(a)

if err := ctx.Descend(); err != nil {
return SizeEmpty, err
}

total := SizeEmpty
for _, item := range a.items {
// Add the size of the index
total += SizeInt32
if item.value != nil {
inc, err := item.value.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}
}
}

ctx.Ascend()

inc, err := a.baseObject.MemUsage(ctx)
total += inc
return total, err
}
42 changes: 42 additions & 0 deletions builtin_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,48 @@ func (mo *mapObject) init() {
mo.m = newOrderedMap(mo.val.runtime.getHash())
}

func (mo *mapObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
if mo == nil || ctx.IsObjVisited(mo) {
return SizeEmpty, nil
}
ctx.VisitObj(mo)

if err := ctx.Descend(); err != nil {
return 0, err
}

total, err := mo.baseObject.MemUsage(ctx)
if err != nil {
return total, err
}

for _, entry := range mo.m.hashTable {
if entry == nil {
continue
}

if entry.key != nil {
inc, err := entry.key.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}
}

if entry.value != nil {
inc, err := entry.value.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}
}
}

ctx.Ascend()

return total, nil
}

func (r *Runtime) mapProto_clear(call FunctionCall) Value {
thisObj := r.toObject(call.This)
mo, ok := thisObj.self.(*mapObject)
Expand Down
17 changes: 17 additions & 0 deletions compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,23 @@ func (p *Program) sourceOffset(pc int) int {
return 0
}

func (p *Program) MemUsage(ctx *MemUsageContext) (uint64, error) {
total := uint64(0)
for _, val := range p.values {
if val == nil {
continue
}

inc, err := val.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}
}

return total, nil
}

func (s *scope) isFunction() bool {
if !s.lexical {
return s.outer != nil
Expand Down
11 changes: 10 additions & 1 deletion date.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,14 @@ func (d *dateObject) timeUTC() time.Time {
}

func (d *dateObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
return SizeEmpty, nil
if d == nil || ctx.IsObjVisited(d) {
return SizeEmpty, nil
}
ctx.VisitObj(d)

// start with the size of msec
total := SizeNumber
inc, err := d.baseObject.MemUsage(ctx)
total += inc
return total, err
}
30 changes: 19 additions & 11 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,24 +288,32 @@ func (f *boundFuncObject) hasInstance(v Value) bool {
}

func (f *nativeFuncObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
if ctx.IsObjVisited(f) {
return 0, nil
if f == nil || ctx.IsObjVisited(f) {
return SizeEmpty, nil
}
ctx.VisitObj(f)

total := SizeEmpty
for _, k := range f.propNames {
prop := f.getOwnPropStr(k)
inc, err := prop.MemUsage(ctx)
return f.baseFuncObject.MemUsage(ctx)
}

func (f *funcObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
if f == nil || ctx.IsObjVisited(f) {
return SizeEmpty, nil
}
ctx.VisitObj(f)

total, baseObjectErr := f.baseObject.MemUsage(ctx)
if baseObjectErr != nil {
return total, baseObjectErr
}

if f.stash != nil {
inc, err := f.stash.MemUsage(ctx)
total += inc
if err != nil {
return total, err
}

}
return total, nil
}

func (f *funcObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
return f.baseObject.MemUsage(ctx)
return total, nil
}
29 changes: 5 additions & 24 deletions mem_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ package goja

import (
"errors"
"hash/maphash"
)

type visitTracker struct {
objsVisited map[objectImpl]bool
stashesVisited map[*stash]bool
valsVisited map[uint64]bool
h *maphash.Hash
}

func (vt visitTracker) IsObjVisited(obj objectImpl) bool {
Expand All @@ -21,29 +18,11 @@ func (vt visitTracker) VisitObj(obj objectImpl) {
vt.objsVisited[obj] = true
}

func (vt visitTracker) IsValVisited(obj Value) bool {
if obj == nil {
return true
}
_, ok := vt.valsVisited[obj.hash(vt.h)]
return ok
}

func (vt visitTracker) VisitVal(obj Value) {
vt.valsVisited[obj.hash(vt.h)] = true
}

func (vt visitTracker) IsStashVisited(stash *stash) bool {
_, ok := vt.stashesVisited[stash]
return ok
}

// func (vt visitTracker) IsStackVisited(stash valueStack) bool {
// _, ok := vt.stashesVisited[stash]
// fmt.Println("visited :check:")
// return ok
// }

func (vt visitTracker) VisitStash(stash *stash) {
vt.stashesVisited[stash] = true
}
Expand Down Expand Up @@ -109,16 +88,14 @@ func (self *stash) MemUsage(ctx *MemUsageContext) (uint64, error) {
}

type MemUsageContext struct {
vm *Runtime
visitTracker
*depthTracker
NativeMemUsageChecker
}

func NewMemUsageContext(vm *Runtime, maxDepth int, nativeChecker NativeMemUsageChecker) *MemUsageContext {
return &MemUsageContext{
vm: vm,
visitTracker: visitTracker{objsVisited: map[objectImpl]bool{}, valsVisited: map[uint64]bool{}, stashesVisited: map[*stash]bool{}, h: &maphash.Hash{}},
visitTracker: visitTracker{objsVisited: map[objectImpl]bool{}, stashesVisited: map[*stash]bool{}},
depthTracker: &depthTracker{curDepth: 0, maxDepth: maxDepth},
NativeMemUsageChecker: nativeChecker,
}
Expand All @@ -127,3 +104,7 @@ func NewMemUsageContext(vm *Runtime, maxDepth int, nativeChecker NativeMemUsageC
var (
ErrMaxDepth = errors.New("reached max depth")
)

type MemUsageReporter interface {
MemUsage(ctx *MemUsageContext) (uint64, error)
}
Loading

0 comments on commit 65dd408

Please sign in to comment.