You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2026/06/03 18:29:55 UTC
(couchdb) 01/01: QuickJS Update: fix gcc perf regression, faster test262 runs
This is an automated email from the ASF dual-hosted git repository.
nickva pushed a commit to branch quickjs-update-jun-3
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 3704eac597d2bdb6a0517592af305a8f4383a55e
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Wed Jun 3 14:27:13 2026 -0400
QuickJS Update: fix gcc perf regression, faster test262 runs
* Add optional define to add asm labels for each opcode to ease code inspection
and profiling
https://github.com/bellard/quickjs/commit/e2c01dff615c0df4d65ed545e4a80ad40b94ea28
* Fixed large performance regression with recent GCC versions
https://github.com/bellard/quickjs/commit/10c81b1989de2d2e8d482d252b160a34f215d3e2
* Exclude few very slow and currently useless test262 tests
https://github.com/bellard/quickjs/commit/594f965146308f4bc8260bd7d91c0eb92b8990d1
---
src/couch_quickjs/patches/01-spidermonkey-185-mode.patch | 6 +++---
src/couch_quickjs/patches/02-test262-errors.patch | 4 ++--
src/couch_quickjs/quickjs/quickjs.c | 15 +++++++++++++++
src/couch_quickjs/quickjs/quickjs.h | 10 ++++++----
src/couch_quickjs/quickjs/test262.conf | 10 ++++++++++
5 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/src/couch_quickjs/patches/01-spidermonkey-185-mode.patch b/src/couch_quickjs/patches/01-spidermonkey-185-mode.patch
index a1aebbc08..5466852aa 100644
--- a/src/couch_quickjs/patches/01-spidermonkey-185-mode.patch
+++ b/src/couch_quickjs/patches/01-spidermonkey-185-mode.patch
@@ -1,6 +1,6 @@
---- quickjs-master/quickjs.c 2026-06-02 12:12:02
-+++ quickjs/quickjs.c 2026-06-02 12:36:47
-@@ -31858,10 +31858,24 @@
+--- quickjs-master/quickjs.c 2026-06-03 10:18:26
++++ quickjs/quickjs.c 2026-06-03 14:25:58
+@@ -31873,10 +31873,24 @@
if (s->token.val == TOK_FUNCTION ||
(token_is_pseudo_keyword(s, JS_ATOM_async) &&
peek_token(s, TRUE) == TOK_FUNCTION)) {
diff --git a/src/couch_quickjs/patches/02-test262-errors.patch b/src/couch_quickjs/patches/02-test262-errors.patch
index 72aee327d..f1ee61e58 100644
--- a/src/couch_quickjs/patches/02-test262-errors.patch
+++ b/src/couch_quickjs/patches/02-test262-errors.patch
@@ -1,5 +1,5 @@
---- quickjs-master/test262_errors.txt 2026-06-02 12:12:02
-+++ quickjs/test262_errors.txt 2026-06-02 12:36:47
+--- quickjs-master/test262_errors.txt 2026-06-03 10:18:26
++++ quickjs/test262_errors.txt 2026-06-03 14:25:58
@@ -23,6 +23,8 @@
test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-export-star-as-from-and-import-star-as-and-export.js:74: SyntaxError: export 'foo' in module 'test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-import-star-as-and-export.js' is ambiguous
test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-export-star-as-from.js:75: SyntaxError: export 'foo' in module 'test262/test/language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-export-star-as-from.js' is ambiguous
diff --git a/src/couch_quickjs/quickjs/quickjs.c b/src/couch_quickjs/quickjs/quickjs.c
index d831d47e4..05d4fd031 100644
--- a/src/couch_quickjs/quickjs/quickjs.c
+++ b/src/couch_quickjs/quickjs/quickjs.c
@@ -107,6 +107,8 @@
//#define DUMP_PROMISE
//#define DUMP_READ_OBJECT
//#define DUMP_ROPE_REBALANCE
+/* add asm labels to each opcode so that it is easier to see the generated code */
+//#define OPCODE_ASM_LABEL
/* test the GC by forcing it before each object allocation */
//#define FORCE_GC_AT_MALLOC
@@ -17761,6 +17763,11 @@ typedef enum {
#define FUNC_RET_YIELD_STAR 2
#define FUNC_RET_INITIAL_YIELD 3
+#ifdef OPCODE_ASM_LABEL
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-label"
+#endif
+
/* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */
static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
JSValueConst this_obj, JSValueConst new_target,
@@ -17794,7 +17801,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
[ OP_COUNT ... 255 ] = &&case_default
};
#define SWITCH(pc) goto *dispatch_table[opcode = *pc++];
+#ifdef OPCODE_ASM_LABEL
+#define CASE(op) case_ ## op: asm volatile("label_" #op ":\n.globl label_" #op); dummy_case_ ## op
+#else
#define CASE(op) case_ ## op
+#endif
#define DEFAULT case_default
#define BREAK SWITCH(pc)
#endif
@@ -20535,6 +20546,10 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
return ret_val;
}
+#ifdef OPCODE_ASM_LABEL
+#pragma GCC diagnostic pop
+#endif
+
JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv)
{
diff --git a/src/couch_quickjs/quickjs/quickjs.h b/src/couch_quickjs/quickjs/quickjs.h
index 57574e6b8..476d73513 100644
--- a/src/couch_quickjs/quickjs/quickjs.h
+++ b/src/couch_quickjs/quickjs/quickjs.h
@@ -216,7 +216,7 @@ static inline JSValue __JS_NewShortBigInt(JSContext *ctx, int32_t d)
#else /* !JS_NAN_BOXING */
typedef union JSValueUnion {
- int32_t int32;
+ uint64_t uint64;
double float64;
void *ptr;
#if JS_SHORT_BIG_INT_BITS == 32
@@ -236,13 +236,15 @@ typedef struct JSValue {
#define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)
/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
-#define JS_VALUE_GET_INT(v) ((v).u.int32)
-#define JS_VALUE_GET_BOOL(v) ((v).u.int32)
+#define JS_VALUE_GET_INT(v) ((int)(v).u.uint64)
+#define JS_VALUE_GET_BOOL(v) ((int)(v).u.uint64)
#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
#define JS_VALUE_GET_SHORT_BIG_INT(v) ((v).u.short_big_int)
#define JS_VALUE_GET_PTR(v) ((v).u.ptr)
-#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
+/* avoid uninitialized data by using a 64 bit field even if only 32
+ bits are needed because some compilers generate slower code */
+#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .uint64 = (uint32_t)(val) }, tag }
#define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag }
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
diff --git a/src/couch_quickjs/quickjs/test262.conf b/src/couch_quickjs/quickjs/test262.conf
index 8fe86cc6f..af5cd6474 100644
--- a/src/couch_quickjs/quickjs/test262.conf
+++ b/src/couch_quickjs/quickjs/test262.conf
@@ -300,5 +300,15 @@ test262/test/staging/sm/syntax/syntax-parsed-arrow-then-directive.js
# returning "bound fn" as initialName for a function is permitted by the spec
test262/test/staging/sm/Function/function-toString-builtin.js
+# very slow tests which only test DST offset caching (QuickJS does not optimize it)
+test262/test/staging/sm/Date/dst-offset-caching-1-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-2-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-3-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-4-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-5-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-6-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-7-of-8.js
+test262/test/staging/sm/Date/dst-offset-caching-8-of-8.js
+
[tests]
# list test files or use config.testdir