Browse Source

Merge pull request #1615 from svaarala/rename-spare-to-slack

Rename buffer spare to slack for clarity
pull/1619/head
Sami Vaarala 7 years ago
committed by GitHub
parent
commit
2b21ce4247
  1. 2
      RELEASES.rst
  2. 6
      config/config-options/DUK_USE_VALSTACK_GROW_SHIFT.yaml
  3. 2
      config/config-options/DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.yaml
  4. 10
      config/config-options/DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT.yaml
  5. 10
      config/config-options/DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT.yaml
  6. 6
      config/examples/low_memory.yaml
  7. 5
      doc/buffers.rst
  8. 24
      src-input/duk_api_stack.c
  9. 2
      src-input/duk_bi_date_unix.c
  10. 2
      src-input/duk_bi_json.c
  11. 5
      src-input/duk_hbuffer.h
  12. 6
      src-input/duk_hbuffer_ops.c
  13. 2
      src-input/duk_hnatfunc.h
  14. 4
      src-input/duk_hobject_pc2line.c
  15. 4
      src-input/duk_hthread.h
  16. 4
      src-input/duk_js_compiler.c
  17. 4
      src-input/duk_numconv.c
  18. 2
      src-input/duk_regexp_executor.c
  19. 14
      src-input/duk_util.h
  20. 4
      src-input/duk_util_bufwriter.c
  21. 2
      tests/ecmascript/test-dev-16bit-overflows.js
  22. 2
      tests/ecmascript/test-dev-exec-valstack-size.js

2
RELEASES.rst

@ -2986,6 +2986,8 @@ Planned
* Internal change: simple freelists for duk_activation and duk_catcher
(GH-1491)
* Internal change: terminology, use 'slack' rather than 'spare' (GH-1615)
* Miscellaneous footprint improvements: rework call handling to improve
code sharing (GH-1552); optional lazy charlen (GH-1337)

6
config/config-options/DUK_USE_VALSTACK_GROW_SHIFT.yaml

@ -6,8 +6,8 @@ tags:
- lowmemory
description: >
When growing the value stack, shift minimum size right by this amount to
come up with a spare which is allocated on top of the minimum required
size. The spare increases memory usage a bit, but reduces value stack
come up with a slack which is allocated on top of the minimum required
size. The slack increases memory usage a bit, but reduces value stack
reallocations when the minimum size grows. A value of 2 means that a
25% spare is used. Undefine to remove any spare, value stack is then
25% slack is used. Undefine to remove any slack, value stack is then
always grown by the minimum amount possible.

2
config/config-options/DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.yaml

@ -10,4 +10,4 @@ description: >
(curr_size >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT) bytes. A value of 2
means that the difference must be at least 25% for a shrink to happen.
If undefined, value stack is always shrunk to the minimum reserved size
with no spare.
with no slack.

10
config/config-options/DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT.yaml

@ -0,0 +1,10 @@
define: DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT
introduced: 2.2.0
default: 4
tags:
- performance
- lowmemory
description: >
When shrinking, leave (curr_size >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)
bytes as a slack. This shift count must be larger than
DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.

10
config/config-options/DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT.yaml

@ -1,10 +0,0 @@
define: DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT
introduced: 2.2.0
default: 4
tags:
- performance
- lowmemory
description: >
When shrinking, leave (curr_size >> DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT)
bytes as a spare. This shift count must be larger than
DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.

6
config/examples/low_memory.yaml

@ -42,12 +42,12 @@ DUK_USE_JC: false
DUK_USE_DEBUG_BUFSIZE: 2048
DUK_USE_LIGHTFUNC_BUILTINS: true
# Grow value stack without any spare, and shrink to minimum reserved size with
# no spare. Increases allocation traffic but avoids allocating space not
# Grow value stack without any slack, and shrink to minimum reserved size with
# no slack. Increases allocation traffic but avoids allocating space not
# actually needed.
DUK_USE_VALSTACK_GROW_SHIFT: false
DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT: false
DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT: false
DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT: false
# Using the same minsize and maxsize drops code footprint by around 400 bytes
# (string table resize code is omitted). Enabling DUK_USE_STRTAB_PTRCOMP

5
doc/buffers.rst

@ -88,9 +88,8 @@ object. Plain buffers can be fixed, dynamic, or external:
* Fixed buffers cannot be resized but have a stable data pointer.
* Dynamic buffers can be resized at the cost of an unstable data pointer.
They also have an internal spare area to minimize realloc operations
(this spare is currently not exposed to user code). You can also "steal"
the current buffer allocation through the duk_steal_buffer() API call.
You can also "steal" the current buffer allocation through the
duk_steal_buffer() API call.
* External buffers point to user-allocated external data area whose pointer
and length can be changed but Duktape won't resize or automatically free

24
src-input/duk_api_stack.c

@ -626,7 +626,7 @@ DUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {
*/
/* Low level valstack resize primitive, used for both grow and shrink. All
* adjustments for spares etc have already been done. Doesn't throw but does
* adjustments for slack etc have already been done. Doesn't throw but does
* have allocation side effects.
*/
DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {
@ -784,12 +784,12 @@ DUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr,
min_size = min_bytes / sizeof(duk_tval); /* from bytes to slots */
#if defined(DUK_USE_VALSTACK_GROW_SHIFT)
/* New size is minimum size plus a proportional spare, e.g. shift of
* 2 means a 25% spare.
/* New size is minimum size plus a proportional slack, e.g. shift of
* 2 means a 25% slack.
*/
new_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);
#else
/* New size is tight with no spare. This is sometimes preferred in
/* New size is tight with no slack. This is sometimes preferred in
* low memory environments.
*/
new_size = min_size;
@ -873,7 +873,7 @@ DUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t
if (snug) {
shrink_bytes = reserve_bytes;
} else {
duk_size_t proportion, spare;
duk_size_t proportion, slack;
/* Require that value stack shrinks by at least X% of its
* current size. For example, shift of 2 means at least
@ -886,18 +886,18 @@ DUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t
return;
}
/* Keep a spare after shrinking. The spare is again a
/* Keep a slack after shrinking. The slack is again a
* proportion of the current size (the proportion should
* of course be smaller than the check proportion above).
*/
#if defined(DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT)
DUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);
spare = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SPARE_SHIFT;
#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)
DUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);
slack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;
#else
spare = 0;
slack = 0;
#endif
shrink_bytes = reserve_bytes +
spare / sizeof(duk_tval) * sizeof(duk_tval); /* multiple of duk_tval */
slack / sizeof(duk_tval) * sizeof(duk_tval); /* multiple of duk_tval */
}
#else /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */
/* Always snug, useful in some low memory environments. */
@ -4568,7 +4568,7 @@ DUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {
/* default prototype */
DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
/* Initial stack size satisfies the stack spare constraints so there
/* Initial stack size satisfies the stack slack constraints so there
* is no need to require stack here.
*/
DUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=

2
src-input/duk_bi_date_unix.c

@ -199,7 +199,7 @@ DUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, cons
time_t t;
char buf[DUK__STRPTIME_BUF_SIZE];
/* copy to buffer with spare to avoid Valgrind gripes from strptime */
/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */
DUK_ASSERT(str != NULL);
DUK_MEMZERO(buf, sizeof(buf)); /* valgrind whine without this */
DUK_SNPRINTF(buf, sizeof(buf), "%s", (const char *) str);

2
src-input/duk_bi_json.c

@ -1577,7 +1577,7 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff
DUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);
/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,
* with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28. 32 has some spare.
* with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28. 32 has some slack.
*
* Note that because the output buffer is reallocated from time to time,
* side effects (such as finalizers) affecting the buffer 'h' must be

5
src-input/duk_hbuffer.h

@ -55,9 +55,6 @@
* Field access
*/
/* Get/set the current user visible size, without accounting for a dynamic
* buffer's "spare" (= usable size).
*/
#if defined(DUK_USE_BUFLEN16)
/* size stored in duk_heaphdr unused flag bits */
#define DUK_HBUFFER_GET_SIZE(x) ((x)->hdr.h_flags >> 16)
@ -177,7 +174,7 @@ struct duk_hbuffer {
* it is useful for writing robust native code.
*/
/* Current size (not counting a dynamic buffer's "spare"). */
/* Current size. */
#if defined(DUK_USE_BUFLEN16)
/* Stored in duk_heaphdr unused flags. */
#else

6
src-input/duk_hbuffer_ops.c

@ -1,12 +1,6 @@
/*
* duk_hbuffer operations such as resizing and inserting/appending data to
* a dynamic buffer.
*
* Append operations append to the end of the buffer and they are relatively
* efficient: the buffer is grown with a "spare" part relative to the buffer
* size to minimize reallocations. Insert operations need to move existing
* data forward in the buffer with memmove() and are not very efficient.
* They are used e.g. by the regexp compiler to "backpatch" regexp bytecode.
*/
#include "duk_internal.h"

2
src-input/duk_hnatfunc.h

@ -25,7 +25,7 @@ struct duk_hnatfunc {
* versa.
*
* Note: cannot place nargs/magic into the heaphdr flags, because
* duk_hobject takes almost all flags already (and needs the spare).
* duk_hobject takes almost all flags already.
*/
};

4
src-input/duk_hobject_pc2line.c

@ -26,10 +26,6 @@ DUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr
DUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);
/* XXX: add proper spare handling to dynamic buffer, to minimize
* reallocs; currently there is no spare at all.
*/
num_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;
curr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);

4
src-input/duk_hthread.h

@ -301,12 +301,12 @@ struct duk_hthread {
* initialized as 'undefined'. [valstack,valstack_end[ is the
* guaranteed/reserved space and the valstack cannot be resized to
* a smaller size. [valstack_end,valstack_alloc_end[ is currently
* allocated spare that can be used to grow the current guaranteed
* allocated slack that can be used to grow the current guaranteed
* space but may be shrunk away without notice.
*
*
* <----------------------- guaranteed --->
* <---- spare --->
* <---- slack --->
* <--- frame --->
* .-------------+=============+----------+--------------.
* |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|

4
src-input/duk_js_compiler.c

@ -287,7 +287,7 @@ DUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, d
#define DUK__TOKEN_LBP_BP_MASK 0x1f
#define DUK__TOKEN_LBP_FLAG_NO_REGEXP (1 << 5) /* regexp literal must not follow this token */
#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6) /* terminates expression; e.g. post-increment/-decrement */
#define DUK__TOKEN_LBP_FLAG_UNUSED (1 << 7) /* spare */
#define DUK__TOKEN_LBP_FLAG_UNUSED (1 << 7) /* unused */
#define DUK__TOKEN_LBP_GET_BP(x) ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))
@ -2626,7 +2626,7 @@ DUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label,
new_size = (n + 1) * sizeof(duk_labelinfo);
duk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);
/* XXX: spare handling, slow now */
/* XXX: slack handling, slow now */
/* relookup after possible realloc */
p = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);

4
src-input/duk_numconv.c

@ -626,10 +626,10 @@ DUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_in
*/
/* Maximum number of digits generated. */
#define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + spare */
#define DUK__MAX_OUTPUT_DIGITS 1040 /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */
/* Maximum number of characters in formatted value. */
#define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + spare */
#define DUK__MAX_FORMATTED_LENGTH 1040 /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */
/* Number and (minimum) size of bigints in the nc_ctx structure. */
#define DUK__NUMCONV_CTX_NUM_BIGINTS 7

2
src-input/duk_regexp_executor.c

@ -544,7 +544,7 @@ DUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const
* The temporary save buffer is pushed on to the valstack to handle
* errors correctly. Each lookahead causes a C recursion and pushes
* more stuff on the value stack. If the C recursion limit is less
* than the value stack spare, there is no need to check the stack.
* than the value stack slack, there is no need to check the stack.
* We do so regardless, just in case.
*/

14
src-input/duk_util.h

@ -105,10 +105,10 @@ struct duk_bitencoder_ctx {
/*
* Buffer writer (dynamic buffer only)
*
* Helper for writing to a dynamic buffer with a concept of a "spare" area
* Helper for writing to a dynamic buffer with a concept of a "slack" area
* to reduce resizes. You can ensure there is enough space beforehand and
* then write for a while without further checks, relying on a stable data
* pointer. Spare handling is automatic so call sites only indicate how
* pointer. Slack handling is automatic so call sites only indicate how
* much data they need right now.
*
* There are several ways to write using bufwriter. The best approach
@ -135,11 +135,11 @@ struct duk_bufwriter_ctx {
};
#if defined(DUK_USE_PREFER_SIZE)
#define DUK_BW_SPARE_ADD 64
#define DUK_BW_SPARE_SHIFT 4 /* 2^4 -> 1/16 = 6.25% spare */
#define DUK_BW_SLACK_ADD 64
#define DUK_BW_SLACK_SHIFT 4 /* 2^4 -> 1/16 = 6.25% slack */
#else
#define DUK_BW_SPARE_ADD 64
#define DUK_BW_SPARE_SHIFT 2 /* 2^2 -> 1/4 = 25% spare */
#define DUK_BW_SLACK_ADD 64
#define DUK_BW_SLACK_SHIFT 2 /* 2^2 -> 1/4 = 25% slack */
#endif
/* Initialization and finalization (compaction), converting to other types. */
@ -238,7 +238,7 @@ struct duk_bufwriter_ctx {
duk_bw_compact((thr), (bw_ctx)); \
} while (0)
/* Fast write calls which assume you control the spare beforehand.
/* Fast write calls which assume you control the slack beforehand.
* Multibyte write variants exist and use a temporary write pointer
* because byte writes alias with anything: with a stored pointer
* explicit pointer load/stores get generated (e.g. gcc -Os).

4
src-input/duk_util_bufwriter.c

@ -1,5 +1,5 @@
/*
* Fast buffer writer with spare management.
* Fast buffer writer with slack management.
*/
#include "duk_internal.h"
@ -57,7 +57,7 @@ DUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_
*/
curr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);
add_sz = (curr_off >> DUK_BW_SPARE_SHIFT) + DUK_BW_SPARE_ADD;
add_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;
new_sz = curr_off + sz + add_sz;
if (DUK_UNLIKELY(new_sz < curr_off)) {
/* overflow */

2
tests/ecmascript/test-dev-16bit-overflows.js

@ -77,7 +77,7 @@ function objectPropertyLimitTest() {
//
// To test the object property limit, define OBJSIZES16 but don't define
// BUFLEN16. Even in this case the property limit is triggered before
// 65536 because the "spare" allocated during a property table resize is
// 65536 because the "slack" allocated during a property table resize is
// counted towards the limit. (Right now the highest property count
// reached is 64231 but that limit depends on tuning.)

2
tests/ecmascript/test-dev-exec-valstack-size.js

@ -8,7 +8,7 @@ try finished
===*/
/* This was broken at one point: executor left temp values on valstack
* which eventually ran out of spare.
* which eventually ran out of slack.
*/
try {

Loading…
Cancel
Save