diff --git a/src-input/duk_heap.h b/src-input/duk_heap.h index 10d62d1c70..62eb002422 100644 --- a/src-input/duk_heap.h +++ b/src-input/duk_heap.h @@ -144,7 +144,7 @@ /* Slotcache is used to speeding up object property lookups without * caching a property value. */ -#define DUK_HEAP_SLOTCACHE_SIZE 8192 +#define DUK_HEAP_SLOTCACHE_SIZE 256 /* helper to insert a (non-string) heap object into heap allocated list */ #define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr) duk_heap_insert_into_heap_allocated((heap),(hdr)) @@ -533,8 +533,10 @@ DUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap); DUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h); DUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset); +/* FIXME: duk_small_uint_t? */ DUK_INTERNAL_DECL duk_uint32_t duk_heap_slotcache_lookup(duk_heap *heap, duk_hobject *obj, duk_hstring *key); DUK_INTERNAL_DECL void duk_heap_slotcache_insert(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint32_t slot); +DUK_INTERNAL_DECL duk_uint32_t duk_heap_slotcache_getkey(duk_hobject *obj, duk_hstring *key); #if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS) DUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size); diff --git a/src-input/duk_heap_slotcache.c b/src-input/duk_heap_slotcache.c index 6390949238..fd50a6fe2d 100644 --- a/src-input/duk_heap_slotcache.c +++ b/src-input/duk_heap_slotcache.c @@ -4,6 +4,24 @@ #include "duk_internal.h" +/* FIXME: check if it's useful to compute the slotcache key only once in property code + * (live range is not trivial so maybe not). + */ + +DUK_LOCAL DUK_ALWAYS_INLINE duk_uint32_t duk__slotcache_compute_key(duk_hobject *obj, duk_hstring *key) { + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + + return (((duk_uint32_t) obj) ^ DUK_HSTRING_GET_HASH(key)) & (DUK_HEAP_SLOTCACHE_SIZE - 1); +} + +DUK_INTERNAL duk_uint32_t duk_heap_slotcache_getkey(duk_hobject *obj, duk_hstring *key) { + DUK_ASSERT(obj != NULL); + DUK_ASSERT(key != NULL); + + return duk__slotcache_compute_key(obj, key); +} + DUK_INTERNAL duk_uint32_t duk_heap_slotcache_lookup(duk_heap *heap, duk_hobject *obj, duk_hstring *key) { duk_uint32_t idx; duk_slotcache_entry *ent; @@ -14,8 +32,8 @@ DUK_INTERNAL duk_uint32_t duk_heap_slotcache_lookup(duk_heap *heap, duk_hobject /* FIXME: assert: hashlimit <= 256 */ - idx = ((duk_uint32_t) obj) ^ DUK_HSTRING_GET_HASH(key); - ent = heap->slotcache + (idx & (DUK_HEAP_SLOTCACHE_SIZE - 1)); + idx = duk__slotcache_compute_key(obj, key); + ent = heap->slotcache + idx; return ent->slot; } @@ -25,10 +43,10 @@ DUK_INTERNAL void duk_heap_slotcache_insert(duk_heap *heap, duk_hobject *obj, du /* FIXME: assert: hashlimit <= 256 */ /* FIXME: skip check if hash part present and hashlimit correct */ - if (DUK_UNLIKELY(slot >= DUK_UINT16_MAX)) { + if (DUK_UNLIKELY(slot >= DUK_UINT8_MAX)) { return; } - idx = ((duk_uint32_t) obj) ^ DUK_HSTRING_GET_HASH(key); - ent = heap->slotcache + (idx & (DUK_HEAP_SLOTCACHE_SIZE - 1)); + idx = duk__slotcache_compute_key(obj, key); + ent = heap->slotcache + idx; ent->slot = (duk_uint16_t) slot; } diff --git a/src-input/duk_hobject_props.c b/src-input/duk_hobject_props.c index 03dfd6b44e..25c3405b7d 100644 --- a/src-input/duk_hobject_props.c +++ b/src-input/duk_hobject_props.c @@ -1182,7 +1182,9 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *o slot = duk_heap_slotcache_lookup(heap, obj, key); if (slot < DUK_HOBJECT_GET_ENEXT(obj)) { if (DUK_HOBJECT_E_GET_KEY(heap, obj, slot) == key) { - DUK_D(DUK_DPRINT("slot cache hit: %p %p -> %ld", (void *) obj, (void *) key, (long) slot)); + DUK_D(DUK_DPRINT("slot cache hit: %p %p %!O -> %ld (slotcache lookup key %lu)", + (void *) obj, (void *) key, key, (long) slot, + (unsigned long) duk_heap_slotcache_getkey(obj, key))); *e_idx = slot; *h_idx = -1; return; @@ -1193,7 +1195,9 @@ DUK_INTERNAL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *o n = DUK_HOBJECT_GET_ENEXT(obj); for (i = 0; i < n; i++) { if (h_keys_base[i] == key) { - DUK_D(DUK_DPRINT("slot cache insert: %p %p -> %ld", (void *) obj, (void *) key, (long) i)); + DUK_D(DUK_DPRINT("slot cache insert: %p %p %!O -> %ld (slotcache lookup key %lu)", + (void *) obj, (void *) key, key, (long) i, + (unsigned long) duk_heap_slotcache_getkey(obj, key))); duk_heap_slotcache_insert(heap, obj, key, i); *e_idx = i; *h_idx = -1;