Skip to content

Commit e1370ea

Browse files
committed
Add init size for NEWARR opcode
1 parent 4688c17 commit e1370ea

4 files changed

Lines changed: 89 additions & 10 deletions

File tree

src-input/duk_hobject.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -868,9 +868,14 @@ DUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,
868868
duk_uint32_t new_a_size,
869869
duk_uint32_t new_h_size,
870870
duk_bool_t abandon_array);
871-
DUK_INTERNAL_DECL void duk_hobject_resize_props(duk_hthread *thr,
872-
duk_hobject *obj,
873-
duk_uint32_t new_e_size);
871+
DUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,
872+
duk_hobject *obj,
873+
duk_uint32_t new_e_size);
874+
#if 0 /*unused*/
875+
DUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,
876+
duk_hobject *obj,
877+
duk_uint32_t new_a_size);
878+
#endif
874879

875880
/* low-level property functions */
876881
DUK_INTERNAL_DECL void duk_hobject_find_existing_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);

src-input/duk_hobject_props.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,6 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
842842
DUK_ASSERT(new_h != NULL);
843843

844844
/* fill new_h with u32 0xff = UNUSED */
845-
DUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);
846845
DUK_ASSERT(new_h_size > 0);
847846
DUK_MEMSET(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);
848847

@@ -960,9 +959,9 @@ DUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,
960959
* Helpers to resize properties allocation on specific needs.
961960
*/
962961

963-
DUK_INTERNAL void duk_hobject_resize_props(duk_hthread *thr,
964-
duk_hobject *obj,
965-
duk_uint32_t new_e_size) {
962+
DUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,
963+
duk_hobject *obj,
964+
duk_uint32_t new_e_size) {
966965
duk_uint32_t old_e_size;
967966
duk_uint32_t new_a_size;
968967
duk_uint32_t new_h_size;
@@ -984,6 +983,31 @@ DUK_INTERNAL void duk_hobject_resize_props(duk_hthread *thr,
984983
duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
985984
}
986985

986+
#if 0 /*unused */
987+
DUK_INTERNAL void duk_hobject_resize_arraypart(duk_hthread *thr,
988+
duk_hobject *obj,
989+
duk_uint32_t new_a_size) {
990+
duk_uint32_t old_a_size;
991+
duk_uint32_t new_e_size;
992+
duk_uint32_t new_h_size;
993+
994+
DUK_ASSERT(thr != NULL);
995+
DUK_ASSERT(obj != NULL);
996+
997+
if (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {
998+
return;
999+
}
1000+
old_a_size = DUK_HOBJECT_GET_ASIZE(obj);
1001+
if (old_a_size > new_a_size) {
1002+
new_a_size = old_a_size;
1003+
}
1004+
new_e_size = DUK_HOBJECT_GET_ESIZE(obj);
1005+
new_h_size = DUK_HOBJECT_GET_HSIZE(obj);
1006+
1007+
duk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);
1008+
}
1009+
#endif
1010+
9871011
/* Grow entry part allocation for one additional entry. */
9881012
DUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {
9891013
duk_uint32_t old_e_used; /* actually used, non-NULL entries */

src-input/duk_js_compiler.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,13 +2818,20 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
28182818
duk_uarridx_t start_idx; /* start array index of current MPUTARR set */
28192819
duk_uarridx_t init_idx; /* last array index explicitly initialized, +1 */
28202820
duk_bool_t require_comma; /* next loop requires a comma */
2821+
#if !defined(DUK_USE_PREFER_SIZE)
2822+
duk_int_t pc_newarr;
2823+
duk_compiler_instr *instr;
2824+
#endif
28212825

28222826
/* DUK_TOK_LBRACKET already eaten, current token is right after that */
28232827
DUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);
28242828

28252829
max_init_values = DUK__MAX_ARRAY_INIT_VALUES; /* XXX: depend on available temps? */
28262830

28272831
reg_obj = DUK__ALLOCTEMP(comp_ctx);
2832+
#if !defined(DUK_USE_PREFER_SIZE)
2833+
pc_newarr = duk__get_current_pc(comp_ctx);
2834+
#endif
28282835
duk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj); /* XXX: patch initial size hint afterwards? */
28292836
temp_start = DUK__GETTEMP(comp_ctx);
28302837

@@ -2924,6 +2931,14 @@ DUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *re
29242931
}
29252932
}
29262933

2934+
/* Update initil size for NEWARR, doesn't need to be exact and is
2935+
* capped at A field limit.
2936+
*/
2937+
#if !defined(DUK_USE_PREFER_SIZE)
2938+
instr = duk__get_instr_ptr(comp_ctx, pc_newarr);
2939+
instr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);
2940+
#endif
2941+
29272942
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);
29282943
duk__advance(comp_ctx);
29292944

@@ -3008,8 +3023,8 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
30083023
duk_small_uint_t max_init_pairs; /* max # of key-value pairs initialized in one MPUTOBJ set */
30093024
duk_bool_t first; /* first value: comma must not precede the value */
30103025
duk_bool_t is_set, is_get; /* temps */
3011-
duk_int_t pc_newobj;
30123026
#if !defined(DUK_USE_PREFER_SIZE)
3027+
duk_int_t pc_newobj;
30133028
duk_compiler_instr *instr;
30143029
#endif
30153030

@@ -3022,7 +3037,9 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
30223037
st.num_pairs = 0; /* number of key/value pairs emitted for current MPUTOBJ set */
30233038
st.num_total_pairs = 0; /* number of key/value pairs emitted overall */
30243039

3040+
#if !defined(DUK_USE_PREFER_SIZE)
30253041
pc_newobj = duk__get_current_pc(comp_ctx);
3042+
#endif
30263043
duk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);
30273044

30283045
/*
@@ -3219,7 +3236,7 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
32193236
*/
32203237
#if !defined(DUK_USE_PREFER_SIZE)
32213238
instr = duk__get_instr_ptr(comp_ctx, pc_newobj);
3222-
instr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > 255 ? 255 : st.num_total_pairs);
3239+
instr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);
32233240
#endif
32243241

32253242
DUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);

src-input/duk_js_executor.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4741,15 +4741,48 @@ DUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *
47414741
case DUK_OP_NEWOBJ: {
47424742
duk_context *ctx = (duk_context *) thr;
47434743
duk_push_object(ctx);
4744+
#if defined(DUK_USE_ASSERTIONS)
4745+
{
4746+
duk_hobject *h;
4747+
h = duk_require_hobject(ctx, -1);
4748+
DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);
4749+
DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);
4750+
DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);
4751+
DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);
4752+
}
4753+
#endif
47444754
#if !defined(DUK_USE_PREFER_SIZE)
4745-
duk_hobject_resize_props(thr, duk_known_hobject(ctx, -1), DUK_DEC_A(ins));
4755+
/* XXX: could do a direct props realloc, but need hash size */
4756+
duk_hobject_resize_entrypart(thr, duk_known_hobject(ctx, -1), DUK_DEC_A(ins));
47464757
#endif
47474758
DUK__REPLACE_TOP_BC_BREAK();
47484759
}
47494760

47504761
case DUK_OP_NEWARR: {
47514762
duk_context *ctx = (duk_context *) thr;
47524763
duk_push_array(ctx);
4764+
#if defined(DUK_USE_ASSERTIONS)
4765+
{
4766+
duk_hobject *h;
4767+
h = duk_require_hobject(ctx, -1);
4768+
DUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);
4769+
DUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);
4770+
DUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);
4771+
DUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);
4772+
DUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));
4773+
}
4774+
#endif
4775+
#if !defined(DUK_USE_PREFER_SIZE)
4776+
duk_hobject_realloc_props(thr,
4777+
duk_known_hobject(ctx, -1),
4778+
0 /*new_e_size*/,
4779+
DUK_DEC_A(ins) /*new_a_size*/,
4780+
0 /*new_h_size*/,
4781+
0 /*abandon_array*/);
4782+
#if 0
4783+
duk_hobject_resize_arraypart(thr, duk_known_hobject(ctx, -1), DUK_DEC_A(ins));
4784+
#endif
4785+
#endif
47534786
DUK__REPLACE_TOP_BC_BREAK();
47544787
}
47554788

0 commit comments

Comments
 (0)