Skip to content

Commit 445d45e

Browse files
committed
Prototype with propcache storage caching
1 parent 95365bd commit 445d45e

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

src-input/duk_heap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ struct duk_propcache_entry {
304304
/* All references are borrowed. */
305305
duk_hobject *obj_lookup;
306306
duk_hstring *key_lookup;
307-
duk_tval value;
307+
duk_tval *val_storage;
308308
duk_uint32_t generation;
309309
};
310310

src-input/duk_heap_propcache.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ DUK_LOCAL DUK_NOINLINE void duk__propcache_scrub(duk_heap *heap) {
55
* to zero, and the generation count is then bumped once more
66
* to one to invalidate the scrubbed entries.
77
*/
8+
DUK_D(DUK_DPRINT("INVALIDATE propcache"));
89
DUK_MEMZERO((void *) heap->propcache, sizeof(heap->propcache));
910
heap->propcache_generation++;
1011
}
@@ -33,10 +34,15 @@ DUK_INTERNAL duk_tval *duk_propcache_lookup(duk_hthread *thr, duk_hobject *obj,
3334
prophash = duk__compute_prophash(obj, key);
3435
ent = thr->heap->propcache + prophash;
3536

37+
DUK_D(DUK_DPRINT("lookup, prophash %lu, gen %lu, ent->gen %lu, ent->obj %p, ent->key %p, ent->val %p",
38+
(unsigned long) prophash, (unsigned long) thr->heap->propcache_generation,
39+
(unsigned long) ent->generation, (void *) ent->obj_lookup,
40+
(void *) ent->key_lookup, (void *) ent->val_storage));
41+
3642
if (ent->generation == thr->heap->propcache_generation &&
3743
ent->obj_lookup == obj &&
3844
ent->key_lookup == key) {
39-
return &ent->value;
45+
return ent->val_storage; /* Storage location. */
4046
}
4147

4248
return NULL;
@@ -51,5 +57,5 @@ DUK_INTERNAL void duk_propcache_insert(duk_hthread *thr, duk_hobject *obj, duk_h
5157
ent->generation = thr->heap->propcache_generation;
5258
ent->obj_lookup = obj;
5359
ent->key_lookup = key;
54-
DUK_TVAL_SET_TVAL(&ent->value, tv);
60+
ent->val_storage = tv;
5561
}

src-input/duk_hobject_props.c

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,9 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
570570
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
571571
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
572572

573+
/* Invalidate property cache. FIXME: also at the end? */
574+
duk_propcache_invalidate(thr);
575+
573576
/*
574577
* Pre resize assertions.
575578
*/
@@ -2666,10 +2669,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
26662669
*/
26672670
duk_tval *storage;
26682671
storage = duk_propcache_lookup(thr, curr, key);
2672+
DUK_D(DUK_DPRINT("propcache GETPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage));
26692673
if (storage) {
2670-
DUK_D(DUK_DPRINT("cached lookup %!O -> %!T", key, storage));
2671-
duk_pop(ctx);
2674+
DUK_D(DUK_DPRINT("cached GETPROP lookup %!O -> %!T", key, storage));
26722675
duk_push_tval(ctx, storage);
2676+
duk_remove(ctx, -2); /* FIXME: careful with order */
26732677
/* FIXME: assume no post process? */
26742678
return 1;
26752679
}
@@ -2800,9 +2804,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
28002804
}
28012805
#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
28022806

2803-
if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX) { /* FIXME: condition */
2807+
if (orig_base && arr_idx == DUK__NO_ARRAY_INDEX && desc.e_idx >= 0) { /* FIXME: condition */
28042808
/* FIXME: other conditions, e.g. not a getter */
2805-
duk_propcache_insert(thr, orig_base, key, DUK_GET_TVAL_NEGIDX(ctx, -1));
2809+
/* FIXME: note that caching is based on orig_base, but storage location is in 'curr'! */
2810+
duk_tval *tv_storage;
2811+
tv_storage = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, curr, desc.e_idx);
2812+
DUK_D(DUK_DPRINT("insert propcache GETPROP %!O", key));
2813+
duk_propcache_insert(thr, orig_base, key, tv_storage);
28062814
}
28072815

28082816
duk_remove_m2(ctx); /* [key result] -> [result] */
@@ -3336,6 +3344,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33363344
duk_tval tv_key_copy;
33373345
duk_tval tv_val_copy;
33383346
duk_hobject *orig = NULL; /* NULL if tv_obj is primitive */
3347+
duk_hobject *orig_base;
33393348
duk_hobject *curr;
33403349
duk_hstring *key = NULL;
33413350
duk_propdesc desc;
@@ -3360,7 +3369,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33603369

33613370
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
33623371

3372+
/* FIXME... with storage location caching, only need to invalidate
3373+
* if new properties are established (may shadow existing chains)?
3374+
*/
3375+
#if 0
33633376
duk_propcache_invalidate(thr);
3377+
#endif
33643378

33653379
/*
33663380
* Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
@@ -3662,6 +3676,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
36623676

36633677
lookup:
36643678

3679+
DUK_ASSERT(curr != NULL);
3680+
orig_base = curr;
3681+
3682+
{
3683+
/* FIXME: when base is primitive, we cache the "wrong" property,
3684+
* which is fine.
3685+
*/
3686+
duk_tval *storage;
3687+
storage = duk_propcache_lookup(thr, orig_base, key);
3688+
DUK_D(DUK_DPRINT("propcache PUTPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage));
3689+
if (storage) {
3690+
DUK_D(DUK_DPRINT("cached PUTPROP lookup %!O -> old value %!T", key, storage));
3691+
DUK_TVAL_SET_TVAL_UPDREF(thr, storage, tv_val);
3692+
goto success_no_arguments_exotic;
3693+
}
3694+
}
3695+
36653696
/*
36663697
* Check whether the property already exists in the prototype chain.
36673698
* Note that the actual write goes into the original base object
@@ -3886,6 +3917,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
38863917

38873918
if (desc.e_idx >= 0) {
38883919
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);
3920+
3921+
/* FIXME argument exotic condition... */
3922+
if (1) { /* FIXME: condition */
3923+
/* FIXME: other conditions, e.g. not a getter */
3924+
DUK_D(DUK_DPRINT("insert propcache PUTPROP %!O", key));
3925+
duk_propcache_insert(thr, orig_base, key, tv);
3926+
}
3927+
38893928
DUK_DDD(DUK_DDDPRINT("previous entry value: %!iT", (duk_tval *) tv));
38903929
DUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val); /* side effects; e_idx may be invalidated */
38913930
/* don't touch property attributes or hash part */
@@ -4088,6 +4127,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
40884127

40894128
write_to_entry_part:
40904129

4130+
/* Must invalidate: new property may affect existing inheritance
4131+
* chains.
4132+
*/
4133+
duk_propcache_invalidate(thr);
4134+
4135+
40914136
/*
40924137
* Write to entry part
40934138
*/

0 commit comments

Comments
 (0)