@@ -2955,6 +2955,7 @@ typedef struct {
29552955 duk_reg_t reg_obj ;
29562956 duk_reg_t temp_start ;
29572957 duk_small_uint_t num_pairs ;
2958+ duk_small_uint_t num_total_pairs ;
29582959} duk__objlit_state ;
29592960
29602961DUK_LOCAL void duk__objlit_flush_keys (duk_compiler_ctx * comp_ctx , duk__objlit_state * st ) {
@@ -2975,6 +2976,7 @@ DUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_st
29752976 st -> reg_obj ,
29762977 st -> temp_start ,
29772978 st -> num_pairs * 2 );
2979+ st -> num_total_pairs += st -> num_pairs ;
29782980 st -> num_pairs = 0 ;
29792981 }
29802982 DUK__SETTEMP (comp_ctx , st -> temp_start );
@@ -3006,6 +3008,10 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
30063008 duk_small_uint_t max_init_pairs ; /* max # of key-value pairs initialized in one MPUTOBJ set */
30073009 duk_bool_t first ; /* first value: comma must not precede the value */
30083010 duk_bool_t is_set , is_get ; /* temps */
3011+ duk_int_t pc_newobj ;
3012+ #if !defined(DUK_USE_PREFER_SIZE )
3013+ duk_compiler_instr * instr ;
3014+ #endif
30093015
30103016 DUK_ASSERT (comp_ctx -> prev_token .t == DUK_TOK_LCURLY );
30113017
@@ -3014,8 +3020,10 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
30143020 st .reg_obj = DUK__ALLOCTEMP (comp_ctx ); /* target object */
30153021 st .temp_start = DUK__GETTEMP (comp_ctx ); /* start of MPUTOBJ argument list */
30163022 st .num_pairs = 0 ; /* number of key/value pairs emitted for current MPUTOBJ set */
3023+ st .num_total_pairs = 0 ; /* number of key/value pairs emitted overall */
30173024
3018- duk__emit_bc (comp_ctx , DUK_OP_NEWOBJ , st .reg_obj ); /* XXX: patch initial size hint afterwards? */
3025+ pc_newobj = duk__get_current_pc (comp_ctx );
3026+ duk__emit_bc (comp_ctx , DUK_OP_NEWOBJ , st .reg_obj );
30193027
30203028 /*
30213029 * Emit initializers in sets of maximum max_init_pairs keys.
@@ -3203,6 +3211,17 @@ DUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *r
32033211 DUK_ASSERT (st .num_pairs == 0 );
32043212 DUK_ASSERT (DUK__GETTEMP (comp_ctx ) == st .temp_start );
32053213
3214+ /* Update initial size for NEWOBJ. The init size doesn't need to be
3215+ * exact as the purpose is just to avoid object resizes in common
3216+ * cases. The size is capped to field A limit, and will be too high
3217+ * if the object literal contains duplicate keys (this is harmless but
3218+ * increases memory traffic if the object is compacted later on).
3219+ */
3220+ #if !defined(DUK_USE_PREFER_SIZE )
3221+ 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 );
3223+ #endif
3224+
32063225 DUK_ASSERT (comp_ctx -> curr_token .t == DUK_TOK_RCURLY );
32073226 duk__advance (comp_ctx );
32083227
0 commit comments