From nobody Tue Sep 16 05:34:42 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1756727907; cv=none; d=zohomail.com; s=zohoarc; b=fvIEo7UQFfv/q2u1xurvK1wV/2kkd0qkfLjslhwX+CqPavBZuTW1snnrTouEg0ot+XYLWLCLYOynp6Kv7lV/RCUtayCdRHlNAOkf93z9Z3QO3dyEiKR799TuMMURiMBEj096cyz9TFkw7UHfynaJK50KZ315Vvw6tuzV6Dhw5Zs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1756727907; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FrnKzdEd+MTfG/VxM7WMSinaKjZRPI/Ikt1qARO7ThI=; b=NdfESeHsP2Bb5QfsgJ3Hu+6mPALmMZqj3FIw6LrqhwyTlykkmKt9Qhwkg0E6m8ZEgKCwmko9h3Yb9Ct75XVeXZhrPDKmeAEL8Z9famVfTVVxDuSTQC0TsNLu4hmxVrJ5L0GVYGGYKFyNX2ODFrGOlBvB7jnznnnip0mfKLFhQgk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1756727907778690.8912096636449; Mon, 1 Sep 2025 04:58:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ut33m-0006kB-P5; Mon, 01 Sep 2025 07:50:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ut31V-0003e4-Fv; Mon, 01 Sep 2025 07:48:36 -0400 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ut31L-0001ra-CX; Mon, 01 Sep 2025 07:48:31 -0400 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-2445805aa2eso43022645ad.1; Mon, 01 Sep 2025 04:48:16 -0700 (PDT) Received: from ktock.. ([240d:1a:3b6:8b00:750a:cb0b:f0f9:68f4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-249065a8036sm103038775ad.129.2025.09.01.04.48.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Sep 2025 04:48:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1756727295; x=1757332095; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FrnKzdEd+MTfG/VxM7WMSinaKjZRPI/Ikt1qARO7ThI=; b=XFnkYwO78Kv/Ygzvx0zJVRCpDsXkqwRqDa6gziqB8gtB3Np2rYCpCQkgSmGDgfRhhT DOc5us2YygBh8darHPQkRSuMrT8BPb5I9FEpoWDr370TE7GZYJdgtB7tvl9YiSfPtzaK H0d0G3NbAZB5zVs4V3ET3KSI0pAxpXVTldlSsoQAN0u82l4Paeo4lvFZphifRibx2YaT MMt90EFfNQPstCbksAhpe+VO/pTX1ov6BYQNIcigLKG66Khj5yqVbORU5uRcIwnFt2nC pd654HbIt/p20lrUry9R2P3P1Q5z6ugBiuShKABa4f4iL1OmBjZ7fl+VI4bQqgR/rHEu +f8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1756727295; x=1757332095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FrnKzdEd+MTfG/VxM7WMSinaKjZRPI/Ikt1qARO7ThI=; b=bvBlfzrNP1ctRLBZxsHsdrTeV6ykmYnF05HtleAeOkcWPv4iVxTKbHYAAfnpiLb5Zb ymfRbr+9Ym3bSRU5Yka/R3QZGewvdmG0qn9xSkGISJv8ciToGsE0+YquFlZJLw2Ttsdy wwfdAymovJd214G5FfxrXpH7RFER3FOnkCO5Fl50SA2RurGV0uM6PNaQLucZe+Si9Ucj 617AeNxCe5u+zGX8PexCDDTEm3B+sVqOhyqgw06nIJArfNCM3SY9emrZ56vwi7UDakRY 5EZEDylaorhY0ekozfTxn9i0SEr61Iy+RQCPVIGVhu6vo4+5pfPFvOKEheTRySfDUqj5 82hw== X-Forwarded-Encrypted: i=1; AJvYcCUsBnfrTqPGTXtg4tt9SShmuaJQAhGwtaxJF7FTU77JTW5GpIY5nZ8E0iHR1+7HbqJiAFcVmn/dlA==@nongnu.org, AJvYcCV2t8GK9jqSBD8E8J5oG0Mfkg7hYMA7lJ1L44JybeNvDxyiUjE+w6Jf0m2aC+FsIoU+DPpcnqg7szGD+w==@nongnu.org X-Gm-Message-State: AOJu0YxCk/bxlK1VHQEPNIVlje99jly6277T1NTtWqJ+txEdNWcA31dk HJJP1f2i11Dp9m9lnedrjs5lEG/a4yXPCJdbFGOmPE+BaKF/JBERvWf5IC5O1w== X-Gm-Gg: ASbGnct4WICfPfFabzpCz8mkIRQNRJ7MLy1Oiw88pnt1hVTeE6gG1SNTUAf+6sghq2P aA3jDuryYXeEeDKk3zcb8XfMwUzCSQYSiksh+Iyp9YmEzS0dS3+RpqJUVhXnjg+O4d5KQPchous Wi1lJegqspkfhDEWs7gIU3bzE4HXgaDq3Vc0Qd2/eCDEt6CfXqnKXVD+qhZewMJR6KGeAJ4j8rw nyWkmuVb6NAmuCZKKMSRK+rYdgfBWd0WPDdaY2hJggOaOlD19tw0J1nX/vPNtlB/b/HwXpUSW0n KN2Le0alJCAPAigf8+yhRTa+flNq+AxXX6S0micMT7lI1RK93M81ZpWPD2eLj5GAgFkMKfq0yQb vyiWPIQeOsDW4nDi2/rzQtt7bJ3okCdIs X-Google-Smtp-Source: AGHT+IH8eAqlOi/gK2WG49ASJm9/0n1ujHDsC4592zhn0zFAfT6BGAEKWE+3NlatvfsauHPb2SjqMQ== X-Received: by 2002:a17:903:41d0:b0:249:27b9:2a06 with SMTP id d9443c01a7336-2494488a758mr110173015ad.2.1756727294946; Mon, 01 Sep 2025 04:48:14 -0700 (PDT) From: Kohei Tokunaga To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , Paolo Bonzini , Richard Henderson , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , WANG Xuerui , Aurelien Jarno , Huacai Chen , Jiaxun Yang , Aleksandar Rikalo , Palmer Dabbelt , Alistair Francis , Stefan Weil , qemu-arm@nongnu.org, qemu-riscv@nongnu.org, Stefan Hajnoczi , Pierrick Bouvier , ktokunaga.mail@gmail.com Subject: [PATCH v3 30/35] tcg/wasm: Enable instantiation of TBs executed many times Date: Mon, 1 Sep 2025 20:44:32 +0900 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=ktokunaga.mail@gmail.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1756727912425124100 Content-Type: text/plain; charset="utf-8" This commit enables the instantiation and execution of TBs in wasm.c. As in TCI, the tcg_qemu_tb_exec function serves as the entrypoint for the TB execution, handling both instantiation and invocation of the Wasm module. Since browsers cause out of memory error if too many Wasm instances are created, this commit restricts instantiation to TBs that are called many times. This commit adds a counter (or its array if there are multiple threads) to the TB. Each time a TB is executed on TCI, the counter on TB is incremented. If it reaches to a threshold, that TB is instantiated as Wasm via instantiate_wasm. The total number of instances are tracked by the instances_global variable and its maximum number is limited by MAX_INSTANCES. When a Wasm module is instantiated, instances_global is incremented and the instance's function pointer is recorded to an array of WasmInstanceInfo. Each TB refers to the WasmInstanceInfo entry via WasmTBHeader's info_ptr (or its array if there are multiple threads). This allows tcg_qemu_tb_exec to resolve the instance's function pointer from the TB. When a new instantiation would exceed the limit, the Wasm backend doesn't perform instantiation (i.e. TB continues execution on TCI). Instead, it triggers the removal of older Wasm instances using Emscripten's removeFunction function. Once the removal is completed and detected via FinalizationRegistry API[1], instances_global is decremented, allowing new modules to be instantiated. [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Globa= l_Objects/FinalizationRegistry Signed-off-by: Kohei Tokunaga --- tcg/wasm.c | 244 +++++++++++++++++++++++++++++++++++++- tcg/wasm.h | 45 +++++++ tcg/wasm/tcg-target.c.inc | 21 ++++ 3 files changed, 307 insertions(+), 3 deletions(-) V3: - Fixed init_wasm_js to correctly cast pointers to Numbers when passing the arguments to the getInt32 and setInt32 methods. - Lowered the the maximum number of instances (MAX_INSTANCES) to avoid the out of memory error in recent versions of FireFox. diff --git a/tcg/wasm.c b/tcg/wasm.c index 82987e9dff..00f4222183 100644 --- a/tcg/wasm.c +++ b/tcg/wasm.c @@ -24,6 +24,10 @@ #include "tcg/helper-info.h" #include #include +#include "wasm.h" + +/* TBs executed more than this value will be compiled to wasm */ +#define INSTANTIATE_NUM 1500 =20 #define EM_JS_PRE(ret, name, args, body...) EM_JS(ret, name, args, body) =20 @@ -61,6 +65,8 @@ EM_JS_PRE(void*, instantiate_wasm, (void *wasm_begin, "helper" : helper, }); =20 + Module.__wasm_tb.inst_gc_registry.register(inst, "tbinstance"); + return ENC_PTR(addFunction(inst.exports.start, 'ii')); }); =20 @@ -288,9 +294,53 @@ static void tci_qemu_st(CPUArchState *env, uint64_t ta= ddr, uint64_t val, } } =20 -static uintptr_t tcg_qemu_tb_exec_tci(CPUArchState *env, const void *v_tb_= ptr) +static __thread int thread_idx; + +static inline int32_t get_counter_local(void *tb_ptr) +{ + return get_counter(tb_ptr, thread_idx); +} + +static inline void set_counter_local(void *tb_ptr, int v) +{ + set_counter(tb_ptr, thread_idx, v); +} + +static inline struct WasmInstanceInfo *get_info_local(void *tb_ptr) +{ + return get_info(tb_ptr, thread_idx); +} + +static inline void set_info_local(void *tb_ptr, struct WasmInstanceInfo *i= nfo) +{ + set_info(tb_ptr, thread_idx, info); +} + +/* + * inc_counter increments the execution counter in the specified TB. + * If the counter reaches the limit, it returns true otherwise returns fal= se. + */ +static inline bool inc_counter(void *tb_ptr) { - const uint32_t *tb_ptr =3D v_tb_ptr; + int32_t counter =3D get_counter_local(tb_ptr); + if ((counter >=3D 0) && (counter < INSTANTIATE_NUM)) { + set_counter_local(tb_ptr, counter + 1); + } else { + return true; /* enter to wasm TB */ + } + return false; +} + +static __thread struct WasmContext ctx =3D { + .tb_ptr =3D 0, + .stack =3D NULL, + .do_init =3D 1, + .buf128 =3D NULL, +}; + +static uintptr_t tcg_qemu_tb_exec_tci(CPUArchState *env) +{ + uint32_t *tb_ptr =3D get_tci_ptr(ctx.tb_ptr); tcg_target_ulong regs[TCG_TARGET_NB_REGS]; uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE) / sizeof(uint64_t)]; @@ -583,18 +633,32 @@ static uintptr_t tcg_qemu_tb_exec_tci(CPUArchState *e= nv, const void *v_tb_ptr) break; case INDEX_op_exit_tb: tci_args_l(insn, tb_ptr, &ptr); + ctx.tb_ptr =3D 0; return (uintptr_t)ptr; case INDEX_op_goto_tb: tci_args_l(insn, tb_ptr, &ptr); - tb_ptr =3D *(void **)ptr; + if (tb_ptr !=3D *(void **)ptr) { + tb_ptr =3D *(void **)ptr; + ctx.tb_ptr =3D tb_ptr; + if (inc_counter(tb_ptr)) { + return 0; /* enter to wasm TB */ + } + tb_ptr =3D get_tci_ptr(tb_ptr); + } break; case INDEX_op_goto_ptr: tci_args_r(insn, &r0); ptr =3D (void *)regs[r0]; if (!ptr) { + ctx.tb_ptr =3D 0; return 0; } tb_ptr =3D ptr; + ctx.tb_ptr =3D tb_ptr; + if (inc_counter(tb_ptr)) { + return 0; /* enter to wasm TB */ + } + tb_ptr =3D get_tci_ptr(tb_ptr); break; case INDEX_op_qemu_ld: tci_args_rrm(insn, &r0, &r1, &oi); @@ -615,3 +679,177 @@ static uintptr_t tcg_qemu_tb_exec_tci(CPUArchState *e= nv, const void *v_tb_ptr) } } } + +/* + * The maximum number of instances that can exist simultaneously + * + * If this limit is reached and a new instance is required, older instance= s are + * removed to allow creation of new ones without exceeding the browser's l= imit. + */ +#define MAX_INSTANCES 12000 + +static int instances_global; + +/* Avoid overwrapping of begin/end pointers */ +#define INSTANCES_BUF_MAX (MAX_INSTANCES + 1) + +static __thread struct WasmInstanceInfo instances[INSTANCES_BUF_MAX]; +static __thread int instances_begin; +static __thread int instances_end; + +static void add_instance(wasm_tb_func tb_func, void *tb_ptr) +{ + instances[instances_end].tb_func =3D tb_func; + instances[instances_end].tb_ptr =3D tb_ptr; + set_info_local(tb_ptr, &(instances[instances_end])); + instances_end =3D (instances_end + 1) % INSTANCES_BUF_MAX; + + qatomic_inc(&instances_global); +} + +static __thread int instance_pending_gc; +static __thread int instance_done_gc; + +static void remove_old_instances(void) +{ + int num; + if (instance_pending_gc > 0) { + return; + } + if (instances_begin <=3D instances_end) { + num =3D instances_end - instances_begin; + } else { + num =3D instances_end + (INSTANCES_BUF_MAX - instances_begin); + } + /* removes the half of the oldest instances in the buffer */ + num /=3D 2; + for (int i =3D 0; i < num; i++) { + EM_ASM({ removeFunction($0); }, instances[instances_begin].tb_func= ); + instances[instances_begin].tb_ptr =3D NULL; + instances_begin =3D (instances_begin + 1) % INSTANCES_BUF_MAX; + } + instance_pending_gc +=3D num; +} + +static bool can_add_instance(void) +{ + return qatomic_read(&instances_global) < MAX_INSTANCES; +} + +static wasm_tb_func get_instance_from_tb(void *tb_ptr) +{ + struct WasmInstanceInfo *elm =3D get_info_local(tb_ptr); + if (elm =3D=3D NULL) { + return NULL; + } + if (elm->tb_ptr !=3D tb_ptr) { + /* + * This TB was instantiated before, but has been removed. Set coun= ter to + * the max value so that this will be instantiated. + */ + set_counter_local(tb_ptr, INSTANTIATE_NUM); + set_info_local(tb_ptr, NULL); + return NULL; + } + return elm->tb_func; +} + +static void check_gc_completion(void) +{ + if (instance_done_gc > 0) { + qatomic_sub(&instances_global, instance_done_gc); + instance_pending_gc -=3D instance_done_gc; + instance_done_gc =3D 0; + } +} + +EM_JS_PRE(void, init_wasm_js, (void *instance_done_gc), +{ + Module.__wasm_tb =3D { + inst_gc_registry: new FinalizationRegistry((i) =3D> { + if (i =3D=3D "tbinstance") { + const memory_v =3D new DataView(HEAP8.buffer); + let v =3D memory_v.getInt32(DEC_PTR(instance_done_gc), tru= e); + memory_v.setInt32(DEC_PTR(instance_done_gc), v + 1, true); + } + }) + }; +}); + +#define MAX_EXEC_NUM 50000 +static __thread int exec_cnt =3D MAX_EXEC_NUM; +static inline void trysleep(void) +{ + /* + * Even during running TBs continuously, try to return the control + * to the browser periodically and allow browsers doing tasks. + */ + if (--exec_cnt =3D=3D 0) { + if (!can_add_instance()) { + emscripten_sleep(0); + check_gc_completion(); + } + exec_cnt =3D MAX_EXEC_NUM; + } +} + +static int thread_idx_max; + +static void init_wasm(void) +{ + thread_idx =3D qatomic_fetch_inc(&thread_idx_max); + ctx.stack =3D g_malloc(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SI= ZE); + ctx.buf128 =3D g_malloc(16); + ctx.tci_tb_ptr =3D (uint32_t *)&tci_tb_ptr; + init_wasm_js(&instance_done_gc); +} + +static __thread bool initdone; + +uintptr_t tcg_qemu_tb_exec(CPUArchState *env, const void *v_tb_ptr) +{ + if (!initdone) { + init_wasm(); + initdone =3D true; + } + ctx.env =3D env; + ctx.tb_ptr =3D (void *)v_tb_ptr; + while (true) { + trysleep(); + uintptr_t res; + wasm_tb_func tb_func =3D get_instance_from_tb(ctx.tb_ptr); + if (tb_func) { + /* + * Call the Wasm instance + */ + res =3D call_wasm_tb(tb_func, &ctx); + } else if (!inc_counter(ctx.tb_ptr)) { + /* + * Run it on TCI because the counter value is small + */ + res =3D tcg_qemu_tb_exec_tci(env); + } else if (!can_add_instance()) { + /* + * Too many instances has been created, try removing older + * instances and keep running this TB on TCI + */ + remove_old_instances(); + check_gc_completion(); + res =3D tcg_qemu_tb_exec_tci(env); + } else { + /* + * Instantiate and run the Wasm module + */ + struct WasmTBHeader *header =3D (struct WasmTBHeader *)ctx.tb_= ptr; + tb_func =3D (wasm_tb_func)instantiate_wasm(header->wasm_ptr, + header->wasm_size, + header->import_ptr, + header->import_size); + add_instance(tb_func, ctx.tb_ptr); + res =3D call_wasm_tb(tb_func, &ctx); + } + if (!ctx.tb_ptr) { + return res; + } + } +} diff --git a/tcg/wasm.h b/tcg/wasm.h index fdde908557..88163c28df 100644 --- a/tcg/wasm.h +++ b/tcg/wasm.h @@ -46,6 +46,14 @@ static inline uintptr_t call_wasm_tb(wasm_tb_func f, str= uct WasmContext *ctx) return f(ctx); } =20 +/* + * WasmInstanceInfo holds the relationship between TB and Wasm instance. + */ +struct WasmInstanceInfo { + void *tb_ptr; + wasm_tb_func tb_func; +}; + /* * A TB of the Wasm backend starts from a header which contains pointers f= or * each data stored in the following region in the TB. @@ -67,6 +75,43 @@ struct WasmTBHeader { */ void *import_ptr; int import_size; + + /* + * Counter holds how many times the TB is executed before the instanti= ation + * for each thread. + */ + int32_t *counter_ptr; + + /* + * Pointer to the instance information on each thread. + */ + struct WasmInstanceInfo **info_ptr; }; =20 +static inline void *get_tci_ptr(void *tb_ptr) +{ + return ((struct WasmTBHeader *)tb_ptr)->tci_ptr; +} + +static inline int32_t get_counter(void *tb_ptr, int idx) +{ + return ((struct WasmTBHeader *)tb_ptr)->counter_ptr[idx]; +} + +static inline void set_counter(void *tb_ptr, int idx, int v) +{ + ((struct WasmTBHeader *)tb_ptr)->counter_ptr[idx] =3D v; +} + +static inline struct WasmInstanceInfo *get_info(void *tb_ptr, int idx) +{ + return ((struct WasmTBHeader *)tb_ptr)->info_ptr[idx]; +} + +static inline void set_info(void *tb_ptr, int idx, + struct WasmInstanceInfo *info) +{ + ((struct WasmTBHeader *)tb_ptr)->info_ptr[idx] =3D info; +} + #endif diff --git a/tcg/wasm/tcg-target.c.inc b/tcg/wasm/tcg-target.c.inc index 6af4d6eb07..784df9e630 100644 --- a/tcg/wasm/tcg-target.c.inc +++ b/tcg/wasm/tcg-target.c.inc @@ -28,6 +28,9 @@ #include "qemu/queue.h" #include "../wasm.h" =20 +/* This is included to get the number of threads via tcg_max_ctxs. */ +#include "../tcg-internal.h" + /* Used for function call generation. */ #define TCG_TARGET_CALL_STACK_OFFSET 0 #define TCG_TARGET_STACK_ALIGN 8 @@ -2295,6 +2298,11 @@ static void tcg_out_set_carry(TCGContext *s) g_assert_not_reached(); } =20 +/* Generate global QEMU prologue and epilogue code. */ +static inline void tcg_target_qemu_prologue(TCGContext *s) +{ +} + static const uint8_t mod_1[] =3D { 0x0, 0x61, 0x73, 0x6d, /* magic */ 0x01, 0x0, 0x0, 0x0, /* version */ @@ -2443,6 +2451,7 @@ static int write_mod_code(TCGContext *s) =20 static void tcg_out_tb_start(TCGContext *s) { + int size; intptr_t ofs; struct WasmTBHeader *h; =20 @@ -2457,6 +2466,18 @@ static void tcg_out_tb_start(TCGContext *s) h =3D (struct WasmTBHeader *)(s->code_ptr); s->code_ptr +=3D sizeof(struct WasmTBHeader); =20 + /* locate counters */ + h->counter_ptr =3D (int32_t *)s->code_ptr; + size =3D tcg_max_ctxs * sizeof(int32_t); + memset(s->code_ptr, 0, size); + s->code_ptr +=3D size; + + /* locate the instance information */ + h->info_ptr =3D (struct WasmInstanceInfo **)s->code_ptr; + size =3D tcg_max_ctxs * sizeof(void *); + memset(s->code_ptr, 0, size); + s->code_ptr +=3D size; + /* Followed by TCI code */ h->tci_ptr =3D s->code_ptr; =20 --=20 2.43.0