My working unpac space for OCaml projects in development
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fixed fast array extension optimization when there are multiple realms

+49 -38
+49 -38
vendor/git/quickjs-c/quickjs.c
··· 451 451 452 452 uint16_t binary_object_count; 453 453 int binary_object_size; 454 - /* TRUE if the array prototype is "normal": 455 - - no small index properties which are get/set or non writable 456 - - its prototype is Object.prototype 457 - - Object.prototype has no small index properties which are get/set or non writable 458 - - the prototype of Object.prototype is null (always true as it is immutable) 459 - */ 460 - uint8_t std_array_prototype; 461 454 462 455 JSShape *array_shape; /* initial shape for Array objects */ 463 456 JSShape *arguments_shape; /* shape for arguments objects */ ··· 936 929 struct { 937 930 int __gc_ref_count; /* corresponds to header.ref_count */ 938 931 uint8_t __gc_mark : 7; /* corresponds to header.mark/gc_obj_type */ 939 - uint8_t is_prototype : 1; /* object may be used as prototype */ 932 + /* TRUE if the array prototype is "normal": 933 + - no small index properties which are get/set or non writable 934 + - its prototype is Object.prototype 935 + - Object.prototype has no small index properties which are get/set or non writable 936 + - the prototype of Object.prototype is null (always true as it is immutable) 937 + */ 938 + uint8_t is_std_array_prototype : 1; 940 939 941 940 uint8_t extensible : 1; 942 941 uint8_t free_mark : 1; /* only used when freeing objects with cycles */ ··· 5206 5205 if (unlikely(!p)) 5207 5206 goto fail; 5208 5207 p->class_id = class_id; 5209 - p->is_prototype = 0; 5208 + p->is_std_array_prototype = 0; 5210 5209 p->extensible = TRUE; 5211 5210 p->free_mark = 0; 5212 5211 p->is_exotic = 0; ··· 7566 7565 if (sh->proto) 7567 7566 JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, sh->proto)); 7568 7567 sh->proto = proto; 7569 - if (proto) 7570 - proto->is_prototype = TRUE; 7571 - if (p->is_prototype) { 7572 - /* track modification of Array.prototype */ 7573 - if (unlikely(p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]))) { 7574 - ctx->std_array_prototype = FALSE; 7575 - } 7576 - } 7568 + p->is_std_array_prototype = FALSE; 7577 7569 return TRUE; 7578 7570 } 7579 7571 ··· 8773 8765 { 8774 8766 JSShape *sh, *new_sh; 8775 8767 8776 - if (unlikely(p->is_prototype)) { 8777 - /* track addition of small integer properties to Array.prototype and Object.prototype */ 8778 - if (unlikely((p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) || 8779 - p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_OBJECT])) && 8780 - __JS_AtomIsTaggedInt(prop))) { 8781 - ctx->std_array_prototype = FALSE; 8768 + if (unlikely(__JS_AtomIsTaggedInt(prop))) { 8769 + /* update is_std_array_prototype */ 8770 + if (unlikely(p->is_std_array_prototype)) { 8771 + p->is_std_array_prototype = FALSE; 8772 + } else if (unlikely(p->has_immutable_prototype)) { 8773 + struct list_head *el; 8774 + 8775 + /* modifying Object.prototype : reset the corresponding is_std_array_prototype */ 8776 + list_for_each(el, &ctx->rt->context_list) { 8777 + JSContext *ctx1 = list_entry(el, JSContext, link); 8778 + if (JS_IsObject(ctx1->class_proto[JS_CLASS_OBJECT]) && 8779 + JS_VALUE_GET_OBJ(ctx1->class_proto[JS_CLASS_OBJECT]) == p) { 8780 + if (JS_IsObject(ctx1->class_proto[JS_CLASS_ARRAY])) { 8781 + JSObject *p1 = JS_VALUE_GET_OBJ(ctx1->class_proto[JS_CLASS_ARRAY]); 8782 + p1->is_std_array_prototype = FALSE; 8783 + } 8784 + break; 8785 + } 8786 + } 8782 8787 } 8783 8788 } 8784 8789 sh = p->shape; ··· 8860 8865 p->u.array.u.values = NULL; /* fail safe */ 8861 8866 p->u.array.u1.size = 0; 8862 8867 p->fast_array = 0; 8863 - 8864 - /* track modification of Array.prototype */ 8865 - if (unlikely(p == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]))) { 8866 - ctx->std_array_prototype = FALSE; 8867 - } 8868 + p->is_std_array_prototype = FALSE; 8868 8869 return 0; 8869 8870 } 8870 8871 ··· 9509 9510 } 9510 9511 } 9511 9512 9513 + /* return true if an element can be added to a fast array without further tests */ 9514 + static force_inline BOOL can_extend_fast_array(JSObject *p) 9515 + { 9516 + JSObject *proto; 9517 + if (!p->extensible) 9518 + return FALSE; 9519 + proto = p->shape->proto; 9520 + if (!proto) 9521 + return TRUE; 9522 + return proto->is_std_array_prototype; 9523 + } 9524 + 9512 9525 /* flags can be JS_PROP_THROW or JS_PROP_THROW_STRICT */ 9513 9526 static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, 9514 9527 JSValue prop, JSValue val, int flags) ··· 9529 9542 /* fast path to add an element to the array */ 9530 9543 if (unlikely(idx != (uint32_t)p->u.array.count || 9531 9544 !p->fast_array || 9532 - !p->extensible || 9533 - p->shape->proto != JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) || 9534 - !ctx->std_array_prototype)) { 9545 + !can_extend_fast_array(p))) { 9535 9546 goto slow_path; 9536 9547 } 9537 9548 /* add element */ ··· 19142 19153 uint32_t new_len, array_len; 19143 19154 if (unlikely(idx != (uint32_t)p->u.array.count || 19144 19155 !p->fast_array || 19145 - !p->extensible || 19146 - p->shape->proto != JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) || 19147 - !ctx->std_array_prototype)) { 19156 + !can_extend_fast_array(p))) { 19148 19157 goto put_array_el_slow_path; 19149 19158 } 19150 19159 if (likely(JS_VALUE_GET_TAG(p->prop[0].u.value) != JS_TAG_INT)) ··· 42117 42126 if (likely(JS_VALUE_GET_TAG(this_val) == JS_TAG_OBJECT && !unshift)) { 42118 42127 JSObject *p = JS_VALUE_GET_OBJ(this_val); 42119 42128 if (likely(p->class_id == JS_CLASS_ARRAY && p->fast_array && 42120 - p->extensible && 42121 - p->shape->proto == JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]) && 42122 - ctx->std_array_prototype && 42129 + can_extend_fast_array(p) && 42123 42130 JS_VALUE_GET_TAG(p->prop[0].u.value) == JS_TAG_INT && 42124 42131 JS_VALUE_GET_INT(p->prop[0].u.value) == p->u.array.count && 42125 42132 (get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE) != 0)) { ··· 55408 55415 return -1; 55409 55416 ctx->array_ctor = obj; 55410 55417 55418 + { 55419 + JSObject *p = JS_VALUE_GET_OBJ(ctx->class_proto[JS_CLASS_ARRAY]); 55420 + p->is_std_array_prototype = TRUE; 55421 + } 55422 + 55411 55423 ctx->array_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_ARRAY]), 55412 55424 JS_PROP_INITIAL_HASH_SIZE, 1); 55413 55425 if (!ctx->array_shape) ··· 55415 55427 if (add_shape_property(ctx, &ctx->array_shape, NULL, 55416 55428 JS_ATOM_length, JS_PROP_WRITABLE | JS_PROP_LENGTH)) 55417 55429 return -1; 55418 - ctx->std_array_prototype = TRUE; 55419 55430 55420 55431 ctx->arguments_shape = js_new_shape2(ctx, get_proto_obj(ctx->class_proto[JS_CLASS_OBJECT]), 55421 55432 JS_PROP_INITIAL_HASH_SIZE, 3);