Repository: nodejs/node
Pull request: deps: V8: cherry-pick 6b1b9bca2a8 [loong64][codegen] Avoid memory access under stack pointer

Fixed occasional cpu-prof test errors in loongarch64 CI.
Reference: https://ci.nodejs.org/job/node-test-commit-loongarch64/nodes=clfs23-64/710/

This issue has been haunting me for a long time (node v20.x to the latest version).

Origin commit message:

    [loong64][codegen] Avoid memory access under stack pointer

    According to LoongArch ABI doc chapter 8.2:
      "Procedures must not assume the persistence on-stack data of which
       the addresses lie below the stack pointer."

    Change-Id: I92735e052227495ac9884c4290b57eaffbf905e1
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6786372
    Auto-Submit: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
    Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
    Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#101634}

Refs: https://github.com/v8/v8/commit/6b1b9bca2a8fe9824bcc815a9ce642da904b91c3

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: common.gypi
patch: @@ -38,7 +38,7 @@
 
     # Reset this number to 0 on major V8 upgrades.
     # Increment by one for each non-official patch applied to deps/v8.
-    'v8_embedder_string': '-node.20',
+    'v8_embedder_string': '-node.21',
 
     ##### V8 defaults for Node.js #####
 

filename: deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
patch: @@ -1626,21 +1626,24 @@ void MacroAssembler::LoadIsolateField(Register dst, IsolateFieldId id) {
 }
 
 void MacroAssembler::MultiPush(RegList regs) {
-  int16_t stack_offset = 0;
+  int16_t num_to_push = regs.Count();
+  int16_t stack_offset = num_to_push * kSystemPointerSize;
 
+  Sub_d(sp, sp, Operand(stack_offset));
   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
     if ((regs.bits() & (1 << i)) != 0) {
       stack_offset -= kSystemPointerSize;
       St_d(ToRegister(i), MemOperand(sp, stack_offset));
     }
   }
-  addi_d(sp, sp, stack_offset);
 }
 
 void MacroAssembler::MultiPush(RegList regs1, RegList regs2) {
   DCHECK((regs1 & regs2).is_empty());
-  int16_t stack_offset = 0;
+  int16_t num_to_push = regs1.Count() + regs2.Count();
+  int16_t stack_offset = num_to_push * kSystemPointerSize;
 
+  Sub_d(sp, sp, Operand(stack_offset));
   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
     if ((regs1.bits() & (1 << i)) != 0) {
       stack_offset -= kSystemPointerSize;
@@ -1653,15 +1656,16 @@ void MacroAssembler::MultiPush(RegList regs1, RegList regs2) {
       St_d(ToRegister(i), MemOperand(sp, stack_offset));
     }
   }
-  addi_d(sp, sp, stack_offset);
 }
 
 void MacroAssembler::MultiPush(RegList regs1, RegList regs2, RegList regs3) {
   DCHECK((regs1 & regs2).is_empty());
   DCHECK((regs1 & regs3).is_empty());
   DCHECK((regs2 & regs3).is_empty());
-  int16_t stack_offset = 0;
+  int16_t num_to_push = regs1.Count() + regs2.Count() + regs3.Count();
+  int16_t stack_offset = num_to_push * kSystemPointerSize;
 
+  Sub_d(sp, sp, Operand(stack_offset));
   for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
     if ((regs1.bits() & (1 << i)) != 0) {
       stack_offset -= kSystemPointerSize;
@@ -1680,7 +1684,6 @@ void MacroAssembler::MultiPush(RegList regs1, RegList regs2, RegList regs3) {
       St_d(ToRegister(i), MemOperand(sp, stack_offset));
     }
   }
-  addi_d(sp, sp, stack_offset);
 }
 
 void MacroAssembler::MultiPop(RegList regs) {
@@ -4125,9 +4128,8 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) {
 
 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
   ASM_CODE_COMMENT(this);
-  addi_d(sp, fp, 2 * kSystemPointerSize);
-  Ld_d(ra, MemOperand(fp, 1 * kSystemPointerSize));
-  Ld_d(fp, MemOperand(fp, 0 * kSystemPointerSize));
+  Move(sp, fp);
+  Pop(ra, fp);
 }
 
 void MacroAssembler::EnterExitFrame(Register scratch, int stack_space,