Skip to content

Commit 3c5bcdf

Browse files
committed
Prototype with propcache storage caching
1 parent 809be71 commit 3c5bcdf

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
*/
@@ -2668,10 +2671,11 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
26682671
*/
26692672
duk_tval *storage;
26702673
storage = duk_propcache_lookup(thr, curr, key);
2674+
DUK_D(DUK_DPRINT("propcache GETPROP lookup: %!O %!O -> %p", orig_base, key, (void *) storage));
26712675
if (storage) {
2672-
DUK_D(DUK_DPRINT("cached lookup %!O -> %!T", key, storage));
2673-
duk_pop(ctx);
2676+
DUK_D(DUK_DPRINT("cached GETPROP lookup %!O -> %!T", key, storage));
26742677
duk_push_tval(ctx, storage);
2678+
duk_remove(ctx, -2); /* FIXME: careful with order */
26752679
/* FIXME: assume no post process? */
26762680
return 1;
26772681
}
@@ -2802,9 +2806,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj,
28022806
}
28032807
#endif /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */
28042808

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

28102818
duk_remove_m2(ctx); /* [key result] -> [result] */
@@ -3338,6 +3346,7 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33383346
duk_tval tv_key_copy;
33393347
duk_tval tv_val_copy;
33403348
duk_hobject *orig = NULL; /* NULL if tv_obj is primitive */
3349+
duk_hobject *orig_base;
33413350
duk_hobject *curr;
33423351
duk_hstring *key = NULL;
33433352
duk_propdesc desc;
@@ -3362,7 +3371,12 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
33623371

33633372
DUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);
33643373

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

33673381
/*
33683382
* Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of
@@ -3664,6 +3678,23 @@ DUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj,
36643678

36653679
lookup:
36663680

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

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

40914130
write_to_entry_part:
40924131

4132+
/* Must invalidate: new property may affect existing inheritance
4133+
* chains.
4134+
*/
4135+
duk_propcache_invalidate(thr);
4136+
4137+
40934138
/*
40944139
* Write to entry part
40954140
*/

0 commit comments

Comments
 (0)