From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 4D61E6F175; Wed, 20 Apr 2022 15:58:41 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 4D61E6F175 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1650459521; bh=AXDiJfMYYyRxhSkHS2uR/MVbSzrx1Ge4MiRe5IhowOE=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Tnj3+Y6orA/qj7/xNNrSTdSNttkO8+aGlq/ZJ44GkhVvnzHuwtWVTDWflEoViBH0Z /gDs4ZmkXd2MH04X20IXhztOhXN5OmFhqwp0PDwXqvg7NzKhcULswF/GiqZGFSrTHX SJoaTWVB+BQhZ5cbraJhCH29DJpj84PtBda4/z1o= Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 327186F175 for ; Wed, 20 Apr 2022 15:58:11 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 327186F175 Received: by mail-lf1-f50.google.com with SMTP id w1so2841379lfa.4 for ; Wed, 20 Apr 2022 05:58:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HRqKyDuEiV/ZPnkjudljLlD7ItYWIyXU79Y6iVSXGUM=; b=zGmKI4BFWlHYA9iW7DMVMA5zEJV1aVst0DPCBuDqlsDCXECDR2vVNw2bn7ikISs87e uISLLY5P+hiUqxrptAArwvO6IqHbOytmZx8odFDEkB8xGsEhBoYpQv07zTfqq0lnLmbp o50ylRDkq81vYJ1XBgoukoI6uHwiTMuq3cDeWUP/zXkzP3eqnKC3N4qsGyAsNUO/7AZS BtLTiBQMRyJVeYHeBautNSU0oBXx1H82dSkxDUh+kVEgLO+qiofITHL7Klv/3jvQ5nZN foQGha4OXO0idoGgnYlqSUskzr3xAhaKmDqoEIN8OdiW+ErEQdbF21ekEVz36QobVmhz w/KQ== X-Gm-Message-State: AOAM530Dx0EulkpvROOXFblV3/jNC09F9+NBMBsCzPC/A9Uk/dTeI039 QFjP93L3UmErWNLPHq4bjl+SkWP7482kzw== X-Google-Smtp-Source: ABdhPJysLl+BYYQkwT5ypf8ss2gotjSzEor2quX4AX+kxrBMka1p1/5mxq5ASuFJwWGBmHXnsv8tDQ== X-Received: by 2002:a05:6512:38c5:b0:471:c17e:59a9 with SMTP id p5-20020a05651238c500b00471c17e59a9mr1185705lft.137.1650459490377; Wed, 20 Apr 2022 05:58:10 -0700 (PDT) Received: from localhost.localdomain ([93.175.28.57]) by smtp.gmail.com with ESMTPSA id o3-20020a198c03000000b00448b7b1780csm1824076lfd.63.2022.04.20.05.58.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Apr 2022 05:58:10 -0700 (PDT) X-Google-Original-From: Maxim Kokryashkin To: tarantool-patches@dev.tarantool.org, imun@tarantool.org, skaplun@tarantool.org Date: Wed, 20 Apr 2022 15:57:57 +0300 Message-Id: <2e93b9a969554ad7105df5dc9d7e040144b75a2c.1650459246.git.m.kokryashkin@tarantool.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH luajit v5 1/7] vm: save topframe info into global_State X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Maxim Kokryashkin via Tarantool-patches Reply-To: Maxim Kokryashkin Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mikhail Shishatskiy Since commit 111d377d524e54e02187148a1832683291d620b2 ('vm: introduce VM states for Lua and fast functions') the VM has LFUNC and FFUNC states. The upcoming sampling profiler uses these vmstates to determine if the guest stack is valid and can be dumped or not. But even if it meets vmstates considered `valid`, it needs a consistent stack base pointer to dump the Lua calling stack: the cur_L->base syncs only when the control is passed from the VM to users code, but the sampling signal may arrive at any moment of time, so cur_L->base may be inconsistent. This patch extends the global_State structure with a field `top_frame`, which stores a valid stack base pointer while VM is in LFUNC, CFUNC or FFUNC states. For this reason, a new macros `set_vmstate_sync_base` added to vm_x64 and vm_x86 (other architectures are NYI) to sync the BASE register before setting the VM state. Part of tarantool/tarantool#781 --- src/lj_obj.h | 1 + src/vm_x64.dasc | 38 ++++++++++++++++++++++++++++---------- src/vm_x86.dasc | 41 +++++++++++++++++++++++++++++++---------- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/lj_obj.h b/src/lj_obj.h index d26e60be..197d735a 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -674,6 +674,7 @@ typedef struct global_State { MRef jit_base; /* Current JIT code L->base or NULL. */ MRef ctype_state; /* Pointer to C type state. */ GCRef gcroot[GCROOT_MAX]; /* GC roots. */ + TValue *top_frame; /* Top frame for sysprof. */ } global_State; #define mainthread(g) (&gcref(g->mainthref)->th) diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc index 974047d3..5bd946ee 100644 --- a/src/vm_x64.dasc +++ b/src/vm_x64.dasc @@ -345,6 +345,20 @@ | mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st |.endmacro | +|// Stash interpreter's internal base and set current VM state. +|// XXX: Each time profiler sees LFUNC, CFUNC or FFUNC state, it tries +|// to dump Lua calling stack, so it needs a stack base pointer. +|// If the sampling signal arriving during the execution of the VM code, +|// base pointer stored in the current lua_State can be irrelevant, as +|// it syncs with the BASE register only when the control is passed to +|// user code. So we need to sync the BASE on each vmstate change to +|// keep it consistent. +|.macro set_vmstate_sync_base, st +| set_vmstate INTERP // Guard for non-atomic VM context restoration +| mov qword [DISPATCH+DISPATCH_GL(top_frame)], BASE +| set_vmstate st +|.endmacro +| |// Uses TMPRd (r10d). |.macro save_vmstate |.if not WIN @@ -356,6 +370,10 @@ |// Uses r10d. |.macro restore_vmstate |.if not WIN +| set_vmstate INTERP +| mov TMPR, SAVE_L +| mov TMPR, L:TMPR->base +| mov qword [DISPATCH+DISPATCH_GL(top_frame)], TMPR | mov TMPRd, SAVE_VMSTATE | mov dword [DISPATCH+DISPATCH_GL(vmstate)], TMPRd |.endif // WIN @@ -435,7 +453,7 @@ static void build_subroutines(BuildCtx *ctx) | jnz ->vm_returnp | | // Return to C. - | set_vmstate CFUNC + | set_vmstate_sync_base CFUNC | and PC, -8 | sub PC, BASE | neg PC // Previous base = BASE - delta. @@ -725,7 +743,7 @@ static void build_subroutines(BuildCtx *ctx) | cleartp LFUNC:KBASE | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | // BASE = base, RC = result, RB = meta base | jmp RA // Jump to continuation. | @@ -1166,7 +1184,7 @@ static void build_subroutines(BuildCtx *ctx) | |.macro .ffunc, name |->ff_ .. name: - | set_vmstate FFUNC + | set_vmstate_sync_base FFUNC |.endmacro | |.macro .ffunc_1, name @@ -1748,7 +1766,7 @@ static void build_subroutines(BuildCtx *ctx) | movzx RAd, PC_RA | neg RA | lea BASE, [BASE+RA*8-16] // base = base - (RA+2)*8 - | set_vmstate LFUNC // LFUNC state after BASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC state after BASE restoration. | ins_next | |6: // Fill up results with nil. @@ -2513,7 +2531,7 @@ static void build_subroutines(BuildCtx *ctx) | mov KBASE, [KBASE+PC2PROTO(k)] | mov L:RB->base, BASE | mov qword [DISPATCH+DISPATCH_GL(jit_base)], 0 - | set_vmstate LFUNC // LFUNC after BASE & KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after BASE & KBASE restoration. | // Modified copy of ins_next which handles function header dispatch, too. | mov RCd, [PC] | movzx RAd, RCH @@ -2730,7 +2748,7 @@ static void build_subroutines(BuildCtx *ctx) | call extern lj_ccallback_enter // (CTState *cts, void *cf) | // lua_State * returned in eax (RD). | mov BASE, L:RD->base - | set_vmstate LFUNC // LFUNC after BASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after BASE restoration. | mov RD, L:RD->top | sub RD, BASE | mov LFUNC:RB, [BASE-16] @@ -4299,7 +4317,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] | // LFUNC after the old BASE & KBASE is restored. - | set_vmstate LFUNC + | set_vmstate_sync_base LFUNC | ins_next | |6: // Fill up results with nil. @@ -4591,7 +4609,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | ins_AD // BASE = new base, RA = framesize, RD = nargs+1 | mov KBASE, [PC-4+PC2PROTO(k)] | mov L:RB, SAVE_L - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | lea RA, [BASE+RA*8] // Top of frame. | cmp RA, L:RB->maxstack | ja ->vm_growstack_f @@ -4629,7 +4647,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov [RD-8], RB // Store delta + FRAME_VARG. | mov [RD-16], LFUNC:KBASE // Store copy of LFUNC. | mov L:RB, SAVE_L - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | lea RA, [RD+RA*8] | cmp RA, L:RB->maxstack | ja ->vm_growstack_v // Need to grow stack. @@ -4685,7 +4703,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov CARG1, L:RB // Caveat: CARG1 may be RA. } | ja ->vm_growstack_c // Need to grow stack. - | set_vmstate CFUNC // CFUNC before entering C function. + | set_vmstate_sync_base CFUNC // CFUNC before entering C function. if (op == BC_FUNCC) { | call KBASE // (lua_State *L) } else { diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index ab8e6f27..92140cec 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc @@ -443,6 +443,20 @@ | mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st |.endmacro | +|// Stash interpreter's internal base and set current VM state. +|// XXX: Each time profiler sees LFUNC, CFUNC or FFUNC state, it tries +|// to dump Lua calling stack, so it needs a stack base pointer. +|// If the sampling signal arriving during the execution of the VM code, +|// base pointer stored in the current lua_State can be irrelevant, as +|// it syncs with the BASE register only when the control is passed to +|// user code. So we need to sync the BASE on each vmstate change to +|// keep it consistent. +|.macro set_vmstate_sync_base, st +| set_vmstate INTERP // Guard for non-atomic VM context restoration +| mov dword [DISPATCH+DISPATCH_GL(top_frame)], BASE +| set_vmstate st +|.endmacro +| |// Uses spilled ecx on x86 or XCHGd (r11d) on x64. |.macro save_vmstate |.if not WIN @@ -461,12 +475,19 @@ |// Uses spilled ecx on x86 or XCHGd (r11d) on x64. |.macro restore_vmstate |.if not WIN +| set_vmstate INTERP |.if not X64 | mov SPILLECX, ecx +| mov ecx, SAVE_L +| mov ecx, L:ecx->base +| mov dword [DISPATCH+DISPATCH_GL(top_frame)], ecx | mov ecx, SAVE_VMSTATE | mov dword [DISPATCH+DISPATCH_GL(vmstate)], ecx | mov ecx, SPILLECX |.else // X64 +| mov XCHGd, SAVE_L +| mov XCHGd, L:XCHGd->base +| mov dword [DISPATCH+DISPATCH_GL(top_frame)], XCHGd | mov XCHGd, SAVE_VMSTATE | mov dword [DISPATCH+DISPATCH_GL(vmstate)], XCHGd |.endif // X64 @@ -560,7 +581,7 @@ static void build_subroutines(BuildCtx *ctx) | jnz ->vm_returnp | | // Return to C. - | set_vmstate CFUNC + | set_vmstate_sync_base CFUNC | and PC, -8 | sub PC, BASE | neg PC // Previous base = BASE - delta. @@ -934,7 +955,7 @@ static void build_subroutines(BuildCtx *ctx) | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] | // BASE = base, RC = result, RB = meta base - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | jmp RAa // Jump to continuation. | |.if FFI @@ -1459,7 +1480,7 @@ static void build_subroutines(BuildCtx *ctx) | |.macro .ffunc, name |->ff_ .. name: - | set_vmstate FFUNC + | set_vmstate_sync_base FFUNC |.endmacro | |.macro .ffunc_1, name @@ -2141,7 +2162,7 @@ static void build_subroutines(BuildCtx *ctx) | movzx RA, PC_RA | not RAa // Note: ~RA = -(RA+1) | lea BASE, [BASE+RA*8] // base = base - (RA+1)*8 - | set_vmstate LFUNC // LFUNC state after BASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC state after BASE restoration. | ins_next | |6: // Fill up results with nil. @@ -2986,7 +3007,7 @@ static void build_subroutines(BuildCtx *ctx) | mov KBASE, [KBASE+PC2PROTO(k)] | mov L:RB->base, BASE | mov dword [DISPATCH+DISPATCH_GL(jit_base)], 0 - | set_vmstate LFUNC // LFUNC after BASE & KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after BASE & KBASE restoration. | // Modified copy of ins_next which handles function header dispatch, too. | mov RC, [PC] | movzx RA, RCH @@ -3257,7 +3278,7 @@ static void build_subroutines(BuildCtx *ctx) | call extern lj_ccallback_enter@8 // (CTState *cts, void *cf) | // lua_State * returned in eax (RD). | mov BASE, L:RD->base - | set_vmstate LFUNC // LFUNC after BASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after BASE restoration. | mov RD, L:RD->top | sub RD, BASE | mov LFUNC:RB, [BASE-8] @@ -5103,7 +5124,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov KBASE, LFUNC:KBASE->pc | mov KBASE, [KBASE+PC2PROTO(k)] | // LFUNC after the old BASE & KBASE is restored. - | set_vmstate LFUNC + | set_vmstate_sync_base LFUNC | ins_next | |6: // Fill up results with nil. @@ -5391,7 +5412,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | ins_AD // BASE = new base, RA = framesize, RD = nargs+1 | mov KBASE, [PC-4+PC2PROTO(k)] | mov L:RB, SAVE_L - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | lea RA, [BASE+RA*8] // Top of frame. | cmp RA, L:RB->maxstack | ja ->vm_growstack_f @@ -5429,7 +5450,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | mov [RD-4], RB // Store delta + FRAME_VARG. | mov [RD-8], LFUNC:KBASE // Store copy of LFUNC. | mov L:RB, SAVE_L - | set_vmstate LFUNC // LFUNC after KBASE restoration. + | set_vmstate_sync_base LFUNC // LFUNC after KBASE restoration. | lea RA, [RD+RA*8] | cmp RA, L:RB->maxstack | ja ->vm_growstack_v // Need to grow stack. @@ -5494,7 +5515,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) |.endif } | ja ->vm_growstack_c // Need to grow stack. - | set_vmstate CFUNC // CFUNC before entering C function. + | set_vmstate_sync_base CFUNC // CFUNC before entering C function. if (op == BC_FUNCC) { | call KBASEa // (lua_State *L) } else { -- 2.35.1