Skip to content

Commit 01b2d2e

Browse files
arahmanantsedgwick
authored andcommitted
REALMC-7452 implement memory usage (dop251#2)
* REALMC-7452 implement memory usage
1 parent ab45fa8 commit 01b2d2e

16 files changed

+818
-361
lines changed

array.go

+17-7
Original file line numberDiff line numberDiff line change
@@ -633,24 +633,34 @@ func strToGoIdx(s unistring.String) int {
633633
}
634634

635635
func (a *arrayObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
636-
total := SizeEmpty
636+
if a == nil || ctx.IsObjVisited(a) {
637+
return SizeEmpty, nil
638+
}
639+
ctx.VisitObj(a)
637640

638-
// inc, err := a.baseObject.MemUsage(ctx)
639-
// total += inc
640-
// if err != nil {
641-
// return total, err
642-
// }
643-
inc, err := a.lengthProp.MemUsage(ctx)
641+
total := SizeEmpty
642+
inc, err := a.baseObject.MemUsage(ctx)
644643
total += inc
645644
if err != nil {
646645
return total, err
647646
}
647+
648+
if err := ctx.Descend(); err != nil {
649+
return total, err
650+
}
651+
648652
for _, v := range a.values {
653+
if v == nil {
654+
continue
655+
}
656+
649657
inc, err := v.MemUsage(ctx)
650658
total += inc
651659
if err != nil {
652660
return total, err
653661
}
654662
}
663+
664+
ctx.Ascend()
655665
return total, nil
656666
}

array_sparse.go

+27-1
Original file line numberDiff line numberDiff line change
@@ -467,5 +467,31 @@ func (a *sparseArrayObject) exportType() reflect.Type {
467467
}
468468

469469
func (a *sparseArrayObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
470-
return SizeEmpty, nil
470+
if a == nil || ctx.IsObjVisited(a) {
471+
return SizeEmpty, nil
472+
}
473+
ctx.VisitObj(a)
474+
475+
if err := ctx.Descend(); err != nil {
476+
return SizeEmpty, err
477+
}
478+
479+
total := SizeEmpty
480+
for _, item := range a.items {
481+
// Add the size of the index
482+
total += SizeInt32
483+
if item.value != nil {
484+
inc, err := item.value.MemUsage(ctx)
485+
total += inc
486+
if err != nil {
487+
return total, err
488+
}
489+
}
490+
}
491+
492+
ctx.Ascend()
493+
494+
inc, err := a.baseObject.MemUsage(ctx)
495+
total += inc
496+
return total, err
471497
}

builtin_map.go

+42
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,48 @@ func (mo *mapObject) init() {
4040
mo.m = newOrderedMap(mo.val.runtime.getHash())
4141
}
4242

43+
func (mo *mapObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
44+
if mo == nil || ctx.IsObjVisited(mo) {
45+
return SizeEmpty, nil
46+
}
47+
ctx.VisitObj(mo)
48+
49+
if err := ctx.Descend(); err != nil {
50+
return 0, err
51+
}
52+
53+
total, err := mo.baseObject.MemUsage(ctx)
54+
if err != nil {
55+
return total, err
56+
}
57+
58+
for _, entry := range mo.m.hashTable {
59+
if entry == nil {
60+
continue
61+
}
62+
63+
if entry.key != nil {
64+
inc, err := entry.key.MemUsage(ctx)
65+
total += inc
66+
if err != nil {
67+
return total, err
68+
}
69+
}
70+
71+
if entry.value != nil {
72+
inc, err := entry.value.MemUsage(ctx)
73+
total += inc
74+
if err != nil {
75+
return total, err
76+
}
77+
}
78+
}
79+
80+
ctx.Ascend()
81+
82+
return total, nil
83+
}
84+
4385
func (r *Runtime) mapProto_clear(call FunctionCall) Value {
4486
thisObj := r.toObject(call.This)
4587
mo, ok := thisObj.self.(*mapObject)

compiler.go

+25
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,32 @@ func (p *Program) sourceOffset(pc int) int {
346346
return 0
347347
}
348348

349+
func (p *Program) MemUsage(ctx *MemUsageContext) (uint64, error) {
350+
total := uint64(0)
351+
for _, val := range p.values {
352+
if val == nil {
353+
continue
354+
}
355+
356+
inc, err := val.MemUsage(ctx)
357+
total += inc
358+
if err != nil {
359+
return total, err
360+
}
361+
}
362+
363+
return total, nil
364+
}
365+
366+
func (s *scope) isFunction() bool {
367+
if !s.lexical {
368+
return s.outer != nil
369+
}
370+
return s.outer.isFunction()
371+
}
372+
349373
func (s *scope) lookupName(name unistring.String) (binding *binding, noDynamics bool) {
374+
var level uint32 = 0
350375
noDynamics = true
351376
toStash := false
352377
for curScope := s; curScope != nil; curScope = curScope.outer {

date.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -140,5 +140,14 @@ func (d *dateObject) timeUTC() time.Time {
140140
}
141141

142142
func (d *dateObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
143-
return SizeEmpty, nil
143+
if d == nil || ctx.IsObjVisited(d) {
144+
return SizeEmpty, nil
145+
}
146+
ctx.VisitObj(d)
147+
148+
// start with the size of msec
149+
total := SizeNumber
150+
inc, err := d.baseObject.MemUsage(ctx)
151+
total += inc
152+
return total, err
144153
}

func.go

+19-11
Original file line numberDiff line numberDiff line change
@@ -289,24 +289,32 @@ func (f *boundFuncObject) hasInstance(v Value) bool {
289289
}
290290

291291
func (f *nativeFuncObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
292-
if ctx.IsObjVisited(f) {
293-
return 0, nil
292+
if f == nil || ctx.IsObjVisited(f) {
293+
return SizeEmpty, nil
294294
}
295295
ctx.VisitObj(f)
296296

297-
total := SizeEmpty
298-
for _, k := range f.propNames {
299-
prop := f.getOwnPropStr(k)
300-
inc, err := prop.MemUsage(ctx)
297+
return f.baseFuncObject.MemUsage(ctx)
298+
}
299+
300+
func (f *funcObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
301+
if f == nil || ctx.IsObjVisited(f) {
302+
return SizeEmpty, nil
303+
}
304+
ctx.VisitObj(f)
305+
306+
total, baseObjectErr := f.baseObject.MemUsage(ctx)
307+
if baseObjectErr != nil {
308+
return total, baseObjectErr
309+
}
310+
311+
if f.stash != nil {
312+
inc, err := f.stash.MemUsage(ctx)
301313
total += inc
302314
if err != nil {
303315
return total, err
304316
}
305-
306317
}
307-
return total, nil
308-
}
309318

310-
func (f *funcObject) MemUsage(ctx *MemUsageContext) (uint64, error) {
311-
return f.baseObject.MemUsage(ctx)
319+
return total, nil
312320
}

mem_context.go

+5-24
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@ package goja
22

33
import (
44
"errors"
5-
"hash/maphash"
65
)
76

87
type visitTracker struct {
98
objsVisited map[objectImpl]bool
109
stashesVisited map[*stash]bool
11-
valsVisited map[uint64]bool
12-
h *maphash.Hash
1310
}
1411

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

24-
func (vt visitTracker) IsValVisited(obj Value) bool {
25-
if obj == nil {
26-
return true
27-
}
28-
_, ok := vt.valsVisited[obj.hash(vt.h)]
29-
return ok
30-
}
31-
32-
func (vt visitTracker) VisitVal(obj Value) {
33-
vt.valsVisited[obj.hash(vt.h)] = true
34-
}
35-
3621
func (vt visitTracker) IsStashVisited(stash *stash) bool {
3722
_, ok := vt.stashesVisited[stash]
3823
return ok
3924
}
4025

41-
// func (vt visitTracker) IsStackVisited(stash valueStack) bool {
42-
// _, ok := vt.stashesVisited[stash]
43-
// fmt.Println("visited :check:")
44-
// return ok
45-
// }
46-
4726
func (vt visitTracker) VisitStash(stash *stash) {
4827
vt.stashesVisited[stash] = true
4928
}
@@ -109,16 +88,14 @@ func (self *stash) MemUsage(ctx *MemUsageContext) (uint64, error) {
10988
}
11089

11190
type MemUsageContext struct {
112-
vm *Runtime
11391
visitTracker
11492
*depthTracker
11593
NativeMemUsageChecker
11694
}
11795

11896
func NewMemUsageContext(vm *Runtime, maxDepth int, nativeChecker NativeMemUsageChecker) *MemUsageContext {
11997
return &MemUsageContext{
120-
vm: vm,
121-
visitTracker: visitTracker{objsVisited: map[objectImpl]bool{}, valsVisited: map[uint64]bool{}, stashesVisited: map[*stash]bool{}, h: &maphash.Hash{}},
98+
visitTracker: visitTracker{objsVisited: map[objectImpl]bool{}, stashesVisited: map[*stash]bool{}},
12299
depthTracker: &depthTracker{curDepth: 0, maxDepth: maxDepth},
123100
NativeMemUsageChecker: nativeChecker,
124101
}
@@ -127,3 +104,7 @@ func NewMemUsageContext(vm *Runtime, maxDepth int, nativeChecker NativeMemUsageC
127104
var (
128105
ErrMaxDepth = errors.New("reached max depth")
129106
)
107+
108+
type MemUsageReporter interface {
109+
MemUsage(ctx *MemUsageContext) (uint64, error)
110+
}

0 commit comments

Comments
 (0)