diff --git a/src-input/duk_heap.h b/src-input/duk_heap.h index fb3a25fd98..20c13d7a24 100644 --- a/src-input/duk_heap.h +++ b/src-input/duk_heap.h @@ -617,6 +617,10 @@ struct duk_heap { duk_int_t stats_putprop_proxy; duk_int_t stats_getvar_all; duk_int_t stats_putvar_all; + duk_int_t stats_propcache_invalidate; + duk_int_t stats_propcache_hit; + duk_int_t stats_propcache_miss; + duk_int_t stats_propcache_insert; #endif }; diff --git a/src-input/duk_heap_markandsweep.c b/src-input/duk_heap_markandsweep.c index a41f8bd24f..584d614ccb 100644 --- a/src-input/duk_heap_markandsweep.c +++ b/src-input/duk_heap_markandsweep.c @@ -1090,6 +1090,9 @@ DUK_LOCAL void duk__dump_stats(duk_heap *heap) { (long) heap->stats_getvar_all)); DUK_D(DUK_DPRINT("stats putvar: all=%ld", (long) heap->stats_putvar_all)); + DUK_D(DUK_DPRINT("stats propcache: invalidate=%ld, hit=%ld, miss=%ld, insert=%ld", + (long) heap->stats_propcache_invalidate, (long) heap->stats_propcache_hit, + (long) heap->stats_propcache_miss, (long) heap->stats_propcache_insert)); } #endif /* DUK_USE_DEBUG */ diff --git a/src-input/duk_heap_propcache.c b/src-input/duk_heap_propcache.c index 1c24615bce..8817f1d918 100644 --- a/src-input/duk_heap_propcache.c +++ b/src-input/duk_heap_propcache.c @@ -5,12 +5,13 @@ DUK_LOCAL DUK_NOINLINE void duk__propcache_scrub(duk_heap *heap) { * to zero, and the generation count is then bumped once more * to one to invalidate the scrubbed entries. */ - DUK_D(DUK_DPRINT("INVALIDATE propcache")); + DUK_DD(DUK_DDPRINT("INVALIDATE propcache")); DUK_MEMZERO((void *) heap->propcache, sizeof(heap->propcache)); heap->propcache_generation++; } DUK_INTERNAL DUK_ALWAYS_INLINE void duk_propcache_invalidate_heap(duk_heap *heap) { + DUK_STATS_INC(heap, stats_propcache_invalidate); if (DUK_UNLIKELY(++heap->propcache_generation == 0)) { duk__propcache_scrub(heap); } @@ -34,17 +35,19 @@ DUK_INTERNAL duk_tval *duk_propcache_lookup(duk_hthread *thr, duk_hobject *obj, prophash = duk__compute_prophash(obj, key); ent = thr->heap->propcache + prophash; - DUK_D(DUK_DPRINT("lookup, prophash %lu, gen %lu, ent->gen %lu, ent->obj %p, ent->key %p, ent->val %p", - (unsigned long) prophash, (unsigned long) thr->heap->propcache_generation, - (unsigned long) ent->generation, (void *) ent->obj_lookup, - (void *) ent->key_lookup, (void *) ent->val_storage)); + DUK_DD(DUK_DDPRINT("lookup, prophash %lu, gen %lu, ent->gen %lu, ent->obj %p, ent->key %p, ent->val %p", + (unsigned long) prophash, (unsigned long) thr->heap->propcache_generation, + (unsigned long) ent->generation, (void *) ent->obj_lookup, + (void *) ent->key_lookup, (void *) ent->val_storage)); if (ent->generation == thr->heap->propcache_generation && ent->obj_lookup == obj && ent->key_lookup == key) { + DUK_STATS_INC(thr->heap, stats_propcache_hit); return ent->val_storage; /* Storage location. */ } + DUK_STATS_INC(thr->heap, stats_propcache_miss); return NULL; } @@ -52,6 +55,7 @@ DUK_INTERNAL void duk_propcache_insert(duk_hthread *thr, duk_hobject *obj, duk_h duk_size_t prophash; duk_propcache_entry *ent; + DUK_STATS_INC(thr->heap, stats_propcache_insert); prophash = duk__compute_prophash(obj, key); ent = thr->heap->propcache + prophash; ent->generation = thr->heap->propcache_generation; diff --git a/src-input/duk_hobject_props.c b/src-input/duk_hobject_props.c index 6245602be9..b6aa36ead9 100644 --- a/src-input/duk_hobject_props.c +++ b/src-input/duk_hobject_props.c @@ -2695,11 +2695,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, */ duk_tval *storage; storage = duk_propcache_lookup(thr, curr, key); - DUK_D(DUK_DPRINT("propcache GETPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage)); + DUK_DD(DUK_DDPRINT("propcache GETPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage)); if (storage) { - DUK_D(DUK_DPRINT("cached GETPROP lookup %!O -> %!T", key, storage)); - duk_push_tval(ctx, storage); - duk_remove(ctx, -2); /* FIXME: careful with order */ + DUK_DD(DDUK_DPRINT("cached GETPROP lookup %!O -> %!T", key, storage)); + duk_push_tval(thr, storage); + duk_remove(thr, -2); /* FIXME: careful with order */ /* FIXME: assume no post process? */ return 1; } @@ -2834,11 +2834,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, /* FIXME: note that caching is based on orig_base, but storage location is in 'curr'! */ duk_tval *tv_storage; tv_storage = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, curr, desc.e_idx); - DUK_D(DUK_DPRINT("insert propcache GETPROP %!O", key)); + DUK_DD(DUK_DDPRINT("insert propcache GETPROP %!O", key)); duk_propcache_insert(thr, orig_base, key, tv_storage); } - duk_remove_m2(ctx); /* [key result] -> [result] */ + duk_remove_m2(thr); /* [key result] -> [result] */ DUK_DDD(DUK_DDDPRINT("-> %!T (found)", (duk_tval *) duk_get_tval(thr, -1))); return 1; @@ -3700,9 +3700,9 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, */ duk_tval *storage; storage = duk_propcache_lookup(thr, orig_base, key); - DUK_D(DUK_DPRINT("propcache PUTPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage)); + DUK_DD(DUK_DDPRINT("propcache PUTPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage)); if (storage) { - DUK_D(DUK_DPRINT("cached PUTPROP lookup %!O -> old value %!T", key, storage)); + DUK_DD(DUK_DDPRINT("cached PUTPROP lookup %!O -> old value %!T", key, storage)); DUK_TVAL_SET_TVAL_UPDREF(thr, storage, tv_val); goto success_no_arguments_exotic; } @@ -3936,7 +3936,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, /* FIXME argument exotic condition... */ if (1) { /* FIXME: condition */ /* FIXME: other conditions, e.g. not a getter */ - DUK_D(DUK_DPRINT("insert propcache PUTPROP %!O", key)); + DUK_DD(DUK_DDPRINT("insert propcache PUTPROP %!O", key)); duk_propcache_insert(thr, orig_base, key, tv); }