Browse Source

Merge pull request #443 from svaarala/add-norz-macros

Add some NORZ (no-refzero free) refcount macros
pull/976/head
Sami Vaarala 8 years ago
committed by GitHub
parent
commit
41a81777f3
  1. 2
      RELEASES.rst
  2. 14
      src-input/duk_api_stack.c
  3. 6
      src-input/duk_heap.h
  4. 68
      src-input/duk_heap_refcount.c
  5. 90
      src-input/duk_heaphdr.h
  6. 33
      tests/perf/test-object-garbage-2.js

2
RELEASES.rst

@ -1961,7 +1961,7 @@ Planned
reg/const pointers in the bytecode executor (GH-674); avoid value stack for
Array .length coercion (GH-862); value stack operation optimization
(GH-891); call related bytecode simplification (GH-896); minor bytecode
opcode handler optimizations (GH-903)
opcode handler optimizations (GH-903); refcount optimizations (GH-443)
* Internal change: rework shared internal string handling so that shared
strings are plain string constants used in macro values, rather than

14
src-input/duk_api_stack.c

@ -414,15 +414,19 @@ DUK_EXTERNAL void duk_set_top(duk_context *ctx, duk_idx_t idx) {
/* Stack size decreases. */
#if defined(DUK_USE_REFERENCE_COUNTING)
duk_uidx_t count;
duk_tval *tv_end;
count = vs_size - uidx;
DUK_ASSERT(count > 0);
while (count > 0) {
count--;
tv = --thr->valstack_top; /* tv -> value just before prev top value; must relookup */
tv_end = thr->valstack_top - count;
tv = thr->valstack_top;
do {
tv--;
DUK_ASSERT(tv >= thr->valstack_bottom);
DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
}
DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);
} while (tv != tv_end);
thr->valstack_top = tv_end;
DUK_REFZERO_CHECK(thr);
#else /* DUK_USE_REFERENCE_COUNTING */
duk_uidx_t count;
duk_tval *tv_end;

6
src-input/duk_heap.h

@ -569,6 +569,7 @@ DUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_ge
DUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);
#ifdef DUK_USE_REFERENCE_COUNTING
DUK_INTERNAL_DECL void duk_refzero_free_pending(duk_hthread *thr);
#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);
#endif
@ -576,6 +577,7 @@ DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);
DUK_INTERNAL_DECL void duk_tval_incref_allownull(duk_tval *tv);
#endif
DUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);
DUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv);
#if 0 /* unused */
DUK_INTERNAL_DECL void duk_tval_decref_allownull(duk_hthread *thr, duk_tval *tv);
#endif
@ -586,8 +588,12 @@ DUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);
DUK_INTERNAL_DECL void duk_heaphdr_incref_allownull(duk_heaphdr *h);
#endif
DUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);
#if 0 /* unused */
DUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h);
#endif
DUK_INTERNAL_DECL void duk_heaphdr_decref_allownull(duk_hthread *thr, duk_heaphdr *h);
DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);
DUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h);
DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize(duk_hthread *thr, duk_heaphdr *hdr);
#else
/* no refcounting */

68
src-input/duk_heap_refcount.c

@ -241,7 +241,7 @@ DUK_LOCAL void duk__refcount_run_torture_finalizer(duk_hthread *thr, duk_hobject
* early and resume at a future alloc/decref/refzero.
*/
DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
DUK_INTERNAL void duk_refzero_free_pending(duk_hthread *thr) {
duk_heaphdr *h1, *h2;
duk_heap *heap;
duk_int_t count = 0;
@ -418,10 +418,9 @@ DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr) {
*
* Decref may trigger immediate refzero handling, which may free and finalize
* an arbitrary number of objects.
*
*/
DUK_INTERNAL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {
DUK_LOCAL DUK_ALWAYS_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) {
duk_heap *heap;
DUK_ASSERT(thr != NULL);
@ -464,38 +463,45 @@ DUK_INTERNAL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {
switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {
case DUK_HTYPE_STRING:
/*
* Strings have no internal references but do have "weak"
* references in the string cache. Also note that strings
* are not on the heap_allocated list like other heap
* elements.
/* Strings have no internal references but do have "weak"
* references in the string cache. Also note that strings
* are not on the heap_allocated list like other heap
* elements.
*/
duk_heap_strcache_string_remove(heap, (duk_hstring *) h);
duk_heap_string_remove(heap, (duk_hstring *) h);
#if 0
duk_heap_free_heaphdr_raw(heap, h);
#endif
duk_free_hstring_inner(heap, (duk_hstring *) h);
DUK_FREE(heap, h);
break;
case DUK_HTYPE_OBJECT:
/*
* Objects have internal references. Must finalize through
* the "refzero" work list.
/* Objects have internal references. Must finalize through
* the "refzero" work list.
*/
duk_heap_remove_any_from_heap_allocated(heap, h);
duk__queue_refzero(heap, h);
duk__refzero_free_pending(thr);
if (!skip_free_pending) {
duk_refzero_free_pending(thr);
}
break;
case DUK_HTYPE_BUFFER:
/*
* Buffers have no internal references. However, a dynamic
* buffer has a separate allocation for the buffer. This is
* freed by duk_heap_free_heaphdr_raw().
/* Buffers have no internal references. However, a dynamic
* buffer has a separate allocation for the buffer. This is
* freed by duk_heap_free_heaphdr_raw().
*/
duk_heap_remove_any_from_heap_allocated(heap, h);
#if 0
duk_heap_free_heaphdr_raw(heap, h);
#endif
duk_free_hbuffer_inner(heap, (duk_hbuffer *) h);
DUK_FREE(heap, h);
break;
default:
@ -504,6 +510,14 @@ DUK_INTERNAL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {
}
}
DUK_INTERNAL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {
duk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/);
}
DUK_INTERNAL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) {
duk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/);
}
#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
DUK_INTERNAL void duk_tval_incref(duk_tval *tv) {
DUK_ASSERT(tv != NULL);
@ -541,7 +555,27 @@ DUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) {
duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);
DUK_ASSERT(h != NULL);
DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));
duk_heaphdr_decref(thr, h);
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);
if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {
return;
}
duk_heaphdr_refzero(thr, h);
}
}
DUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) {
DUK_ASSERT(thr != NULL);
DUK_ASSERT(tv != NULL);
if (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {
duk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);
DUK_ASSERT(h != NULL);
DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);
if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {
return;
}
duk_heaphdr_refzero_norz(thr, h);
}
}

90
src-input/duk_heaphdr.h

@ -101,11 +101,11 @@ struct duk_heaphdr_string {
#define DUK_HEAPHDR_FLAG_FINALIZED DUK_HEAPHDR_HEAP_FLAG(3) /* mark-and-sweep: finalized (on previous pass) */
#define DUK_HEAPHDR_FLAG_READONLY DUK_HEAPHDR_HEAP_FLAG(4) /* read-only object, in code section */
#define DUK_HTYPE_MIN 1
#define DUK_HTYPE_STRING 1
#define DUK_HTYPE_OBJECT 2
#define DUK_HTYPE_BUFFER 3
#define DUK_HTYPE_MAX 3
#define DUK_HTYPE_MIN 0
#define DUK_HTYPE_STRING 0
#define DUK_HTYPE_OBJECT 1
#define DUK_HTYPE_BUFFER 2
#define DUK_HTYPE_MAX 2
#if defined(DUK_USE_HEAPPTR16)
#define DUK_HEAPHDR_GET_NEXT(heap,h) \
@ -172,8 +172,10 @@ struct duk_heaphdr_string {
(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \
} while (0)
/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero
* and the comparison is unsigned, it's always true and generates warnings.
*/
#define DUK_HEAPHDR_HTYPE_VALID(h) ( \
DUK_HEAPHDR_GET_TYPE((h)) >= DUK_HTYPE_MIN && \
DUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \
)
@ -313,6 +315,19 @@ struct duk_heaphdr_string {
} \
} \
} while (0)
#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \
duk_tval *duk__tv = (tv); \
DUK_ASSERT(duk__tv != NULL); \
if (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \
duk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \
DUK_ASSERT(duk__h != NULL); \
DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \
if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \
duk_heaphdr_refzero_norz((thr), duk__h); \
} \
} \
} while (0)
#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \
duk_heaphdr *duk__h = (duk_heaphdr *) (h); \
DUK_ASSERT(duk__h != NULL); \
@ -332,6 +347,15 @@ struct duk_heaphdr_string {
} \
} \
} while (0)
#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) do { \
duk_heaphdr *duk__h = (duk_heaphdr *) (h); \
DUK_ASSERT(duk__h != NULL); \
DUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \
if (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \
duk_heaphdr_refzero_norz((thr), duk__h); \
} \
} while (0)
/* Slow variants, call to a helper to reduce code size.
* Can be used explicitly when size is always more important than speed.
@ -342,12 +366,18 @@ struct duk_heaphdr_string {
#define DUK_TVAL_DECREF_SLOW(thr,tv) do { \
duk_tval_decref((thr), (tv)); \
} while (0)
#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv) do { \
duk_tval_decref_norz((thr), (tv)); \
} while (0)
#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do { \
duk_heaphdr_incref((duk_heaphdr *) (h)); \
} while (0)
#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do { \
duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); \
} while (0)
#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do { \
duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); \
} while (0)
/* Default variants. Selection depends on speed/size preference.
* Concretely: with gcc 4.8.1 -Os x64 the difference in final binary
@ -356,30 +386,41 @@ struct duk_heaphdr_string {
#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
#define DUK_TVAL_INCREF(thr,tv) DUK_TVAL_INCREF_FAST((thr),(tv))
#define DUK_TVAL_DECREF(thr,tv) DUK_TVAL_DECREF_FAST((thr),(tv))
#define DUK_TVAL_DECREF_NORZ(thr,tv) DUK_TVAL_DECREF_NORZ_FAST((thr),(tv))
#define DUK_HEAPHDR_INCREF(thr,h) DUK_HEAPHDR_INCREF_FAST((thr),(h))
#define DUK_HEAPHDR_DECREF(thr,h) DUK_HEAPHDR_DECREF_FAST((thr),(h))
#define DUK_HEAPHDR_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ_FAST((thr),(h))
#else
#define DUK_TVAL_INCREF(thr,tv) DUK_TVAL_INCREF_SLOW((thr),(tv))
#define DUK_TVAL_DECREF(thr,tv) DUK_TVAL_DECREF_SLOW((thr),(tv))
#define DUK_TVAL_DECREF_NORZ(thr,tv) DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv))
#define DUK_HEAPHDR_INCREF(thr,h) DUK_HEAPHDR_INCREF_SLOW((thr),(h))
#define DUK_HEAPHDR_DECREF(thr,h) DUK_HEAPHDR_DECREF_SLOW((thr),(h))
#define DUK_HEAPHDR_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h))
#endif
/* Casting convenience. */
#define DUK_HSTRING_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))
#define DUK_HSTRING_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) (h))
#define DUK_HSTRING_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) (h))
#define DUK_HOBJECT_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))
#define DUK_HOBJECT_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) (h))
#define DUK_HOBJECT_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) (h))
#define DUK_HBUFFER_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))
#define DUK_HBUFFER_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) (h))
#define DUK_HBUFFER_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) (h))
#define DUK_HCOMPFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HCOMPFUNC_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HNATFUNC_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HNATFUNC_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HNATFUNC_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HBUFOBJ_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HBUFOBJ_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HBUFOB_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HTHREAD_INCREF(thr,h) DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HTHREAD_DECREF(thr,h) DUK_HEAPHDR_DECREF((thr),(duk_heaphdr *) &(h)->obj)
#define DUK_HTHREAD_DECREF_NORZ(thr,h) DUK_HEAPHDR_DECREF_NORZ((thr),(duk_heaphdr *) &(h)->obj)
/* Convenience for some situations; the above macros don't allow NULLs
* for performance reasons.
@ -394,6 +435,20 @@ struct duk_heaphdr_string {
DUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \
} \
} while (0)
#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \
if ((h) != NULL) { \
DUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \
} \
} while (0)
/* Free pending refzero entries; quick check to avoid call because often
* the queue is empty.
*/
#define DUK_REFZERO_CHECK(thr) do { \
if ((thr)->heap->refzero_list != NULL) { \
duk_refzero_free_pending((thr)); \
} \
} while (0)
/*
* Macros to set a duk_tval and update refcount of the target (decref the
@ -408,6 +463,13 @@ struct duk_heaphdr_string {
DUK_TVAL_DECREF((thr), &tv__tmp); /* side effects */ \
} while (0)
#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \
duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
DUK_TVAL_SET_UNDEFINED(tv__dst); \
DUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \
} while (0)
#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \
duk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \
DUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \
@ -551,6 +613,7 @@ struct duk_heaphdr_string {
/* XXX: no optimized variants yet */
#define DUK_TVAL_SET_UNDEFINED_UPDREF DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0
#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0
#define DUK_TVAL_SET_UNUSED_UPDREF DUK_TVAL_SET_UNUSED_UPDREF_ALT0
#define DUK_TVAL_SET_NULL_UPDREF DUK_TVAL_SET_NULL_UPDREF_ALT0
#define DUK_TVAL_SET_BOOLEAN_UPDREF DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0
@ -590,32 +653,47 @@ struct duk_heaphdr_string {
#define DUK_TVAL_INCREF_FAST(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF_FAST(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF_NORZ_FAST(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_INCREF_SLOW(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF_SLOW(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_INCREF(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF(thr,v) do {} while (0) /* nop */
#define DUK_TVAL_DECREF_NORZ(thr,v) do {} while (0) /* nop */
#define DUK_HEAPHDR_INCREF_FAST(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF_FAST(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_INCREF_SLOW(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF_SLOW(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HEAPHDR_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HSTRING_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HSTRING_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HSTRING_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HBUFFER_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HBUFFER_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HBUFFER_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HCOMPFUNC_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HCOMPFUNC_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HNATFUNC_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HNATFUNC_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HNATFUNC_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HBUFOBJ_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HBUFOBJ_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HBUFOBJ_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HTHREAD_INCREF(thr,h) do {} while (0) /* nop */
#define DUK_HTHREAD_DECREF(thr,h) do {} while (0) /* nop */
#define DUK_HTHREAD_DECREF_NORZ(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do {} while (0) /* nop */
#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do {} while (0) /* nop */
#define DUK_REFZERO_CHECK(thr) do {} while (0) /* nop */
#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \
duk_tval *tv__dst; tv__dst = (tvptr_dst); \

33
tests/perf/test-object-garbage-2.js

@ -0,0 +1,33 @@
function test() {
var i;
var t;
for (i = 0; i < 2e5; i++) {
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
t = { foo: 1, bar: 2, quux: 3, baz: 4, quuux: 5, quuuux: 6, quuuuux: 7, quuuuuux: 8, quuuuuuux: 9, quuuuuuuux: 10 };
t = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
}
}
try {
test();
} catch (e) {
print(e.stack || e);
}
Loading…
Cancel
Save