Skip to content

Optimize {__proto__:null} object literal creation #1118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -16449,6 +16449,7 @@ typedef enum {
OP_SPECIAL_OBJECT_HOME_OBJECT,
OP_SPECIAL_OBJECT_VAR_OBJECT,
OP_SPECIAL_OBJECT_IMPORT_META,
OP_SPECIAL_OBJECT_NULL_PROTO,
} OPSpecialObjectEnum;

#define FUNC_RET_AWAIT 0
Expand Down Expand Up @@ -16748,6 +16749,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
if (unlikely(JS_IsException(sp[-1])))
goto exception;
break;
case OP_SPECIAL_OBJECT_NULL_PROTO:
*sp++ = JS_NewObjectProtoClass(ctx, JS_NULL, JS_CLASS_OBJECT);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried caching the shape for prototype-less objects on the JSContext (like it's done for ctx->array_shape) and calling JS_NewObjectFromShape(ctx, js_dup_shape(ctx->null_proto_shape), JS_CLASS_OBJECT) but it has no measurable impact on the micro-benchmark.

if (unlikely(JS_IsException(sp[-1])))
goto exception;
break;
default:
abort();
}
Expand Down Expand Up @@ -33490,6 +33496,18 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
}
goto no_change;

case OP_object:
if (code_match(&cc, pos_next, OP_null, OP_set_proto, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
if (cc.col_num >= 0) col_num = cc.col_num;
add_pc2line_info(s, bc_out.size, line_num, col_num);
dbuf_putc(&bc_out, OP_special_object);
dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_NULL_PROTO);
pos_next = cc.pos;
break;
}
goto no_change;

default:
no_change:
add_pc2line_info(s, bc_out.size, line_num, col_num);
Expand Down
10 changes: 10 additions & 0 deletions tests/microbench.js
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,15 @@ function math_min(n)
return n * 1000;
}

function object_null(n)
{
var j;
for(j = 0; j < n; j++) {
global_res = {__proto__: null};
}
return n;
}

function regexp_ascii(n)
{
var i, j, r, s;
Expand Down Expand Up @@ -1098,6 +1107,7 @@ function main(argc, argv, g)
array_for_in,
array_for_of,
math_min,
object_null,
regexp_ascii,
regexp_utf16,
string_build1,
Expand Down