Browse Source

rename object LAYOUT_2 to LAYOUT_3 to make space for a less modified version of LAYOUT_1, add a portable align trick to duk_hbuffer_fixed which doesn't increase struct size unnecessarily, rename ALIGN4/8 to ALIGN_4/ALIGN_8

pull/2/head
Sami Vaarala 11 years ago
parent
commit
015ac29d6f
  1. 2
      src/duk_bi_error.c
  2. 25
      src/duk_features.h
  3. 35
      src/duk_hbuffer.h
  4. 8
      src/duk_hobject.h
  5. 8
      src/duk_hobject_pc2line.c
  6. 4
      src/duk_hobject_props.c
  7. 6
      src/duk_hthread_builtins.c
  8. 4
      src/duk_selftest.c

2
src/duk_bi_error.c

@ -177,7 +177,7 @@ static int duk__traceback_getter_helper(duk_context *ctx, int output_type) {
duk_get_prop_stridx(ctx, -4, DUK_STRIDX_INT_PC2LINE);
if (duk_is_buffer(ctx, -1)) {
pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(pc2line));
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line));
line = duk_hobject_pc2line_query(pc2line, (duk_uint_fast32_t) pc);
} else {
line = 0;

25
src/duk_features.h

@ -678,34 +678,34 @@ typedef double duk_double_t;
*/
#undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
#undef DUK_USE_ALIGN4
#undef DUK_USE_ALIGN8
#undef DUK_USE_ALIGN_4
#undef DUK_USE_ALIGN_8
#if defined(DUK_F_EMSCRIPTEN)
/* Required on at least some targets, so use whenever Emscripten used,
* regardless of compilation target.
*/
#define DUK_USE_ALIGN8
#define DUK_USE_ALIGN_8
#elif defined(DUK_F_ARM)
#define DUK_USE_ALIGN4
#define DUK_USE_ALIGN_4
#elif defined(DUK_F_MIPS)
#define DUK_USE_ALIGN4
#define DUK_USE_ALIGN_4
#elif defined(DUK_F_X86) || defined(DUK_F_X64)
#define DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
#else
/* unknown, use safe default */
#define DUK_USE_ALIGN8
#define DUK_USE_ALIGN_8
#endif
/* User forced alignment to 4 or 8. */
#if defined(DUK_OPT_FORCE_ALIGN)
#undef DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
#undef DUK_USE_ALIGN4
#undef DUK_USE_ALIGN8
#undef DUK_USE_ALIGN_4
#undef DUK_USE_ALIGN_8
#if (DUK_OPT_FORCE_ALIGN == 4)
#define DUK_USE_ALIGN4
#define DUK_USE_ALIGN_4
#elif (DUK_OPT_FORCE_ALIGN == 8)
#define DUK_USE_ALIGN8
#define DUK_USE_ALIGN_8
#else
#error invalid DUK_OPT_FORCE_ALIGN value
#endif
@ -735,8 +735,9 @@ typedef double duk_double_t;
#undef DUK_USE_HOBJECT_LAYOUT_1
#undef DUK_USE_HOBJECT_LAYOUT_2
#undef DUK_USE_HOBJECT_LAYOUT_3
#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE) && \
!defined(DUK_USE_ALIGN4) && !defined(DUK_USE_ALIGN8)
!defined(DUK_USE_ALIGN_4) && !defined(DUK_USE_ALIGN_8)
/* On platforms without any alignment issues, layout 1 is preferable
* because it compiles to slightly less code and provides direct access
* to property keys.
@ -746,7 +747,7 @@ typedef double duk_double_t;
/* Otherwise layout is used by default, as it is compact even on
* platforms with alignment requirements.
*/
#define DUK_USE_HOBJECT_LAYOUT_2
#define DUK_USE_HOBJECT_LAYOUT_3
#endif
/*

35
src/duk_hbuffer.h

@ -28,6 +28,7 @@
#define DUK_HBUFFER_CLEAR_DYNAMIC(x) DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)
#define DUK_HBUFFER_FIXED_GET_DATA_PTR(x) ((duk_uint8_t *) (((duk_hbuffer_fixed *) (x)) + 1))
#define DUK_HBUFFER_FIXED_GET_SIZE(x) ((x)->u.s.size)
#define DUK_HBUFFER_DYNAMIC_GET_ALLOC_SIZE(x) ((x)->usable_size + 1)
#define DUK_HBUFFER_DYNAMIC_GET_USABLE_SIZE(x) ((x)->usable_size)
@ -81,12 +82,29 @@ struct duk_hbuffer {
*/
};
#if defined(DUK_USE_ALIGN8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
#if defined(DUK_USE_ALIGN_8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
#pragma pack(push, 8)
#endif
struct duk_hbuffer_fixed {
duk_heaphdr hdr;
size_t size;
/* A union is used here as a portable struct size / alignment trick:
* by adding a 32-bit or a 64-bit (unused) union member, the size of
* the struct is effectively forced to be a multiple of 4 or 8 bytes
* (respectively) without increasing the size of the struct unless
* necessary.
*/
union {
struct {
duk_heaphdr hdr;
size_t size;
} s;
#if defined(DUK_USE_ALIGN_4)
duk_uint32_t dummy_for_align4;
#elif defined(DUK_USE_ALIGN_8)
duk_uint64_t dummy_for_align8;
#else
/* no extra padding */
#endif
} u;
/*
* Data follows the struct header. The struct size is padded by the
@ -100,19 +118,14 @@ struct duk_hbuffer_fixed {
* Duktape itself breaks (e.g. the compiler stores duk_tvals in a
* dynamic buffer).
*/
#if defined(DUK_USE_ALIGN8) && defined(DUK_USE_PACK_DUMMY_MEMBER)
/* Portable but very wasteful approach to ensuring alignment by 8. */
duk_uint64_t dummy_for_align8;
#endif
}
#if defined(DUK_USE_ALIGN8) && defined(DUK_USE_PACK_GCC_ATTR)
#if defined(DUK_USE_ALIGN_8) && defined(DUK_USE_PACK_GCC_ATTR)
__attribute__ ((aligned (8)))
#elif defined(DUK_USE_ALIGN8) && defined(DUK_USE_PACK_CLANG_ATTR)
#elif defined(DUK_USE_ALIGN_8) && defined(DUK_USE_PACK_CLANG_ATTR)
__attribute__ ((aligned (8)))
#endif
;
#if defined(DUK_USE_ALIGN8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
#if defined(DUK_USE_ALIGN_8) && defined(DUK_USE_PACK_MSVC_PRAGMA)
#pragma pack(pop)
#endif

8
src/duk_hobject.h

@ -228,7 +228,7 @@
(set_a) = (duk_tval *) ((set_e_f) + (set_e_size)); \
(set_h) = (duk_uint32_t *) ((set_a) + (set_a_size)); \
} while(0)
#elif defined(DUK_USE_HOBJECT_LAYOUT_2)
#elif defined(DUK_USE_HOBJECT_LAYOUT_3)
#define DUK_HOBJECT_E_GET_KEY_BASE(h) \
((duk_hstring **) ( \
(h)->p + \
@ -419,9 +419,9 @@
#define DUK_HOBJECT_A_ABANDON_LIMIT 2 /* 25%, i.e. less than 25% used -> abandon */
/* internal align target for props allocation, must be 2*n for some n */
#if defined(DUK_USE_ALIGN4)
#if defined(DUK_USE_ALIGN_4)
#define DUK_HOBJECT_ALIGN_TARGET 4
#elif defined(DUK_USE_ALIGN8)
#elif defined(DUK_USE_ALIGN_8)
#define DUK_HOBJECT_ALIGN_TARGET 8
#else
#define DUK_HOBJECT_ALIGN_TARGET 1
@ -491,7 +491,7 @@ struct duk_hobject {
* h_size * sizeof(duk_uint32_t) bytes of (opt) hash indexes to entries (e_size),
* 0xffffffffU = unused, 0xfffffffeU = deleted
*
* Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):
* Layout 2 (DUK_USE_HOBJECT_LAYOUT_3):
*
* e_size * sizeof(duk_propvalue) bytes of entry values (e_used gc reachable)
* a_size * sizeof(duk_tval) bytes of (opt) array values (plain only) (all gc reachable)

8
src/duk_hobject_pc2line.c

@ -136,13 +136,13 @@ duk_uint_fast32_t duk_hobject_pc2line_query(duk_hbuffer_fixed *buf, duk_uint_fas
duk_uint_fast32_t curr_line;
DUK_ASSERT(buf != NULL);
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(buf));
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf));
hdr_index = pc / DUK_PC2LINE_SKIP;
pc_base = hdr_index * DUK_PC2LINE_SKIP;
n = pc - pc_base;
if (DUK_HBUFFER_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {
if (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {
DUK_DDPRINT("pc2line lookup failed: buffer is smaller than minimal header");
goto error;
}
@ -158,7 +158,7 @@ duk_uint_fast32_t duk_hobject_pc2line_query(duk_hbuffer_fixed *buf, duk_uint_fas
curr_line = hdr[1 + hdr_index * 2];
start_offset = hdr[1 + hdr_index * 2 + 1];
if ((duk_size_t) start_offset > DUK_HBUFFER_GET_SIZE(buf)) {
if ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) {
DUK_DDPRINT("pc2line lookup failed: start_offset out of bounds (start_offset=%d, buffer_size=%d)",
(int) start_offset, (int) DUK_HBUFFER_GET_SIZE(buf));
goto error;
@ -166,7 +166,7 @@ duk_uint_fast32_t duk_hobject_pc2line_query(duk_hbuffer_fixed *buf, duk_uint_fas
DUK_MEMSET(bd_ctx, 0, sizeof(*bd_ctx));
bd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;
bd_ctx->length = (duk_size_t) (DUK_HBUFFER_GET_SIZE(buf) - start_offset);
bd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);
#if 0
DUK_DDDPRINT("pc2line lookup: pc=%d -> hdr_index=%d, pc_base=%d, n=%d, start_offset=%d",

4
src/duk_hobject_props.c

@ -292,8 +292,8 @@ static void duk__realloc_props(duk_hthread *thr,
* on low RAM platforms requiring alignment.
*/
#if defined(DUK_USE_HOBJECT_LAYOUT_2)
DUK_DDDPRINT("using layout 2, no need to pad e_size: %d", (int) new_e_size);
#if defined(DUK_USE_HOBJECT_LAYOUT_3)
DUK_DDDPRINT("using layout 3, no need to pad e_size: %d", (int) new_e_size);
new_e_size_adjusted = new_e_size;
#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)
DUK_DDDPRINT("using layout 1, but no need to pad e_size: %d", (int) new_e_size);

6
src/duk_hthread_builtins.c

@ -483,13 +483,15 @@ void duk_hthread_create_builtin_objects(duk_hthread *thr) {
"p1"
#elif defined(DUK_USE_HOBJECT_LAYOUT_2)
"p2"
#elif defined(DUK_USE_HOBJECT_LAYOUT_3)
"p3"
#else
"p?"
#endif
" "
#if defined(DUK_USE_ALIGN4)
#if defined(DUK_USE_ALIGN_4)
"a4"
#elif defined(DUK_USE_ALIGN8)
#elif defined(DUK_USE_ALIGN_8)
"a8"
#else
"a1"

4
src/duk_selftest.c

@ -144,11 +144,11 @@ static void duk__selftest_double_zero_sign(void) {
*/
static void duk__selftest_struct_align(void) {
#if defined(DUK_USE_ALIGN4)
#if defined(DUK_USE_ALIGN_4)
if ((sizeof(duk_hbuffer_fixed) % 4) != 0) {
DUK_PANIC(DUK_ERR_INTERNAL_ERROR, "self test failed: sizeof(duk_hbuffer_fixed) not aligned to 4");
}
#elif defined(DUK_USE_ALIGN8)
#elif defined(DUK_USE_ALIGN_8)
if ((sizeof(duk_hbuffer_fixed) % 8) != 0) {
DUK_PANIC(DUK_ERR_INTERNAL_ERROR, "self test failed: sizeof(duk_hbuffer_fixed) not aligned to 8");
}

Loading…
Cancel
Save