summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/heap/base
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/heap/base
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/heap/base')
-rw-r--r--chromium/v8/src/heap/base/asm/arm/push_registers_asm.cc39
-rw-r--r--chromium/v8/src/heap/base/asm/arm64/push_registers_asm.cc52
-rw-r--r--chromium/v8/src/heap/base/asm/arm64/push_registers_masm.S32
-rw-r--r--chromium/v8/src/heap/base/asm/ia32/push_registers_asm.cc53
-rw-r--r--chromium/v8/src/heap/base/asm/ia32/push_registers_masm.S48
-rw-r--r--chromium/v8/src/heap/base/asm/mips/push_registers_asm.cc48
-rw-r--r--chromium/v8/src/heap/base/asm/mips64/push_registers_asm.cc48
-rw-r--r--chromium/v8/src/heap/base/asm/ppc/push_registers_asm.cc94
-rw-r--r--chromium/v8/src/heap/base/asm/s390/push_registers_asm.cc35
-rw-r--r--chromium/v8/src/heap/base/asm/x64/push_registers_asm.cc94
-rw-r--r--chromium/v8/src/heap/base/asm/x64/push_registers_masm.S45
-rw-r--r--chromium/v8/src/heap/base/stack.cc129
-rw-r--r--chromium/v8/src/heap/base/stack.h43
13 files changed, 760 insertions, 0 deletions
diff --git a/chromium/v8/src/heap/base/asm/arm/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/arm/push_registers_asm.cc
new file mode 100644
index 00000000000..5246c3f6c3e
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/arm/push_registers_asm.cc
@@ -0,0 +1,39 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+//
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+
+// We maintain 8-byte alignment at calls by pushing an additional
+// non-callee-saved register (r3).
+//
+// Calling convention source:
+// https://en.wikipedia.org/wiki/Calling_convention#ARM_(A32)
+// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html
+asm(".globl PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+ // Push all callee-saved registers and save return address.
+ // Only {r4-r11} are callee-saved registers. Push r3 in addition to align
+ // the stack back to 8 bytes.
+ " push {r3-r11, lr} \n"
+ // Pass 1st parameter (r0) unchanged (Stack*).
+ // Pass 2nd parameter (r1) unchanged (StackVisitor*).
+ // Save 3rd parameter (r2; IterateStackCallback).
+ " mov r3, r2 \n"
+ // Pass 3rd parameter as sp (stack pointer).
+ " mov r2, sp \n"
+ // Call the callback.
+ " blx r3 \n"
+ // Discard all the registers.
+ " add sp, sp, #36 \n"
+ // Pop lr into pc which returns and switches mode if needed.
+ " pop {pc} \n");
diff --git a/chromium/v8/src/heap/base/asm/arm64/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/arm64/push_registers_asm.cc
new file mode 100644
index 00000000000..30d4de1f308
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/arm64/push_registers_asm.cc
@@ -0,0 +1,52 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+//
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+
+// We maintain 16-byte alignment.
+//
+// Calling convention source:
+// https://en.wikipedia.org/wiki/Calling_convention#ARM_(A64)
+
+asm(
+#if defined(__APPLE__)
+ ".globl _PushAllRegistersAndIterateStack \n"
+ ".private_extern _PushAllRegistersAndIterateStack \n"
+ "_PushAllRegistersAndIterateStack: \n"
+#else // !defined(__APPLE__)
+ ".globl PushAllRegistersAndIterateStack \n"
+#if !defined(_WIN64)
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+#endif // !defined(_WIN64)
+ "PushAllRegistersAndIterateStack: \n"
+#endif // !defined(__APPLE__)
+ // x19-x29 are callee-saved.
+ " stp x19, x20, [sp, #-16]! \n"
+ " stp x21, x22, [sp, #-16]! \n"
+ " stp x23, x24, [sp, #-16]! \n"
+ " stp x25, x26, [sp, #-16]! \n"
+ " stp x27, x28, [sp, #-16]! \n"
+ " stp fp, lr, [sp, #-16]! \n"
+ // Maintain frame pointer.
+ " mov fp, sp \n"
+ // Pass 1st parameter (x0) unchanged (Stack*).
+ // Pass 2nd parameter (x1) unchanged (StackVisitor*).
+ // Save 3rd parameter (x2; IterateStackCallback)
+ " mov x7, x2 \n"
+ // Pass 3rd parameter as sp (stack pointer).
+ " mov x2, sp \n"
+ " blr x7 \n"
+ // Load return address.
+ " ldr lr, [sp, #8] \n"
+ // Restore frame pointer and pop all callee-saved registers.
+ " ldr fp, [sp], #96 \n"
+ " ret \n");
diff --git a/chromium/v8/src/heap/base/asm/arm64/push_registers_masm.S b/chromium/v8/src/heap/base/asm/arm64/push_registers_masm.S
new file mode 100644
index 00000000000..9773654ffcf
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/arm64/push_registers_masm.S
@@ -0,0 +1,32 @@
+; Copyright 2020 the V8 project authors. All rights reserved.
+; Use of this source code is governed by a BSD-style license that can be
+; found in the LICENSE file.
+
+; This file is exactly the same as push_registers_asm.cc, just formatted for
+; the Microsoft Arm Assembler.
+
+ AREA |.text|, CODE, ALIGN=4, READONLY
+ EXPORT PushAllRegistersAndIterateStack
+PushAllRegistersAndIterateStack
+ ; x19-x29 are callee-saved
+ STP x19, x20, [sp, #-16]!
+ STP x21, x22, [sp, #-16]!
+ STP x23, x24, [sp, #-16]!
+ STP x25, x26, [sp, #-16]!
+ STP x27, x28, [sp, #-16]!
+ STP fp, lr, [sp, #-16]!
+ ; Maintain frame pointer
+ MOV fp, sp
+ ; Pass 1st parameter (x0) unchanged (Stack*).
+ ; Pass 2nd parameter (x1) unchanged (StackVisitor*).
+ ; Save 3rd parameter (x2; IterateStackCallback)
+ MOV x7, x2
+ ; Pass 3rd parameter as sp (stack pointer)
+ MOV x2, sp
+ BLR x7
+ ; Load return address
+ LDR lr, [sp, #8]
+ ; Restore frame pointer and pop all callee-saved registers.
+ LDR fp, [sp], #96
+ RET
+ END \ No newline at end of file
diff --git a/chromium/v8/src/heap/base/asm/ia32/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/ia32/push_registers_asm.cc
new file mode 100644
index 00000000000..ed9c14a50e9
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/ia32/push_registers_asm.cc
@@ -0,0 +1,53 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+//
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+
+// We maintain 16-byte alignment at calls. There is an 4-byte return address
+// on the stack and we push 28 bytes which maintains 16-byte stack alignment
+// at the call.
+//
+// The following assumes cdecl calling convention.
+// Source: https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
+asm(
+#ifdef _WIN32
+ ".globl _PushAllRegistersAndIterateStack \n"
+ "_PushAllRegistersAndIterateStack: \n"
+#else // !_WIN32
+ ".globl PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+#endif // !_WIN32
+ // [ IterateStackCallback ]
+ // [ StackVisitor* ]
+ // [ Stack* ]
+ // [ ret ]
+ // ebp is callee-saved. Maintain proper frame pointer for debugging.
+ " push %ebp \n"
+ " movl %esp, %ebp \n"
+ " push %ebx \n"
+ " push %esi \n"
+ " push %edi \n"
+ // Save 3rd parameter (IterateStackCallback).
+ " movl 28(%esp), %ecx \n"
+ // Pass 3rd parameter as esp (stack pointer).
+ " push %esp \n"
+ // Pass 2nd parameter (StackVisitor*).
+ " push 28(%esp) \n"
+ // Pass 1st parameter (Stack*).
+ " push 28(%esp) \n"
+ " call *%ecx \n"
+ // Pop the callee-saved registers.
+ " addl $24, %esp \n"
+ // Restore rbp as it was used as frame pointer.
+ " pop %ebp \n"
+ " ret \n");
diff --git a/chromium/v8/src/heap/base/asm/ia32/push_registers_masm.S b/chromium/v8/src/heap/base/asm/ia32/push_registers_masm.S
new file mode 100644
index 00000000000..a35fd6e527d
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/ia32/push_registers_masm.S
@@ -0,0 +1,48 @@
+;; Copyright 2020 the V8 project authors. All rights reserved.
+;; Use of this source code is governed by a BSD-style license that can be
+;; found in the LICENSE file.
+
+;; MASM syntax
+;; https://docs.microsoft.com/en-us/cpp/assembler/masm/microsoft-macro-assembler-reference?view=vs-2019
+
+.model flat, C
+
+public PushAllRegistersAndIterateStack
+
+.code
+PushAllRegistersAndIterateStack:
+ ;; Push all callee-saved registers to get them on the stack for conservative
+ ;; stack scanning.
+ ;;
+ ;; We maintain 16-byte alignment at calls. There is an 8-byte return address
+ ;; on the stack and we push 72 bytes which maintains 16-byte stack alignment
+ ;; at the call.
+ ;;
+ ;; The following assumes cdecl calling convention.
+ ;; Source: https://docs.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019
+ ;;
+ ;; [ IterateStackCallback ]
+ ;; [ StackVisitor* ]
+ ;; [ Stack* ]
+ ;; [ ret ]
+ push ebp
+ mov ebp, esp
+ push ebx
+ push esi
+ push edi
+ ;; Save 3rd parameter (IterateStackCallback).
+ mov ecx, [ esp + 28 ]
+ ;; Pass 3rd parameter as esp (stack pointer).
+ push esp
+ ;; Pass 2nd parameter (StackVisitor*).
+ push [ esp + 28 ]
+ ;; Pass 1st parameter (Stack*).
+ push [ esp + 28 ]
+ call ecx
+ ;; Pop the callee-saved registers.
+ add esp, 24
+ ;; Restore rbp as it was used as frame pointer.
+ pop ebp
+ ret
+
+end
diff --git a/chromium/v8/src/heap/base/asm/mips/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/mips/push_registers_asm.cc
new file mode 100644
index 00000000000..4a46caa6c52
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/mips/push_registers_asm.cc
@@ -0,0 +1,48 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+//
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+asm(".set noreorder \n"
+ ".global PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+ // Push all callee-saved registers and save return address.
+ " addiu $sp, $sp, -48 \n"
+ " sw $ra, 44($sp) \n"
+ " sw $s8, 40($sp) \n"
+ " sw $sp, 36($sp) \n"
+ " sw $gp, 32($sp) \n"
+ " sw $s7, 28($sp) \n"
+ " sw $s6, 24($sp) \n"
+ " sw $s5, 20($sp) \n"
+ " sw $s4, 16($sp) \n"
+ " sw $s3, 12($sp) \n"
+ " sw $s2, 8($sp) \n"
+ " sw $s1, 4($sp) \n"
+ " sw $s0, 0($sp) \n"
+ // Maintain frame pointer.
+ " move $s8, $sp \n"
+ // Pass 1st parameter (a0) unchanged (Stack*).
+ // Pass 2nd parameter (a1) unchanged (StackVisitor*).
+ // Save 3rd parameter (a2; IterateStackCallback).
+ " move $a3, $a2 \n"
+ // Call the callback.
+ " jalr $a3 \n"
+ // Delay slot: Pass 3rd parameter as sp (stack pointer).
+ " move $a2, $sp \n"
+ // Load return address.
+ " lw $ra, 44($sp) \n"
+ // Restore frame pointer.
+ " lw $s8, 40($sp) \n"
+ " jr $ra \n"
+ // Delay slot: Discard all callee-saved registers.
+ " addiu $sp, $sp, 48 \n");
diff --git a/chromium/v8/src/heap/base/asm/mips64/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/mips64/push_registers_asm.cc
new file mode 100644
index 00000000000..6befa3bcc0c
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/mips64/push_registers_asm.cc
@@ -0,0 +1,48 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+//
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+asm(".set noreorder \n"
+ ".global PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+ // Push all callee-saved registers and save return address.
+ " daddiu $sp, $sp, -96 \n"
+ " sd $ra, 88($sp) \n"
+ " sd $s8, 80($sp) \n"
+ " sd $sp, 72($sp) \n"
+ " sd $gp, 64($sp) \n"
+ " sd $s7, 56($sp) \n"
+ " sd $s6, 48($sp) \n"
+ " sd $s5, 40($sp) \n"
+ " sd $s4, 32($sp) \n"
+ " sd $s3, 24($sp) \n"
+ " sd $s2, 16($sp) \n"
+ " sd $s1, 8($sp) \n"
+ " sd $s0, 0($sp) \n"
+ // Maintain frame pointer.
+ " move $s8, $sp \n"
+ // Pass 1st parameter (a0) unchanged (Stack*).
+ // Pass 2nd parameter (a1) unchanged (StackVisitor*).
+ // Save 3rd parameter (a2; IterateStackCallback).
+ " move $a3, $a2 \n"
+ // Call the callback.
+ " jalr $a3 \n"
+ // Delay slot: Pass 3rd parameter as sp (stack pointer).
+ " move $a2, $sp \n"
+ // Load return address.
+ " ld $ra, 88($sp) \n"
+ // Restore frame pointer.
+ " ld $s8, 80($sp) \n"
+ " jr $ra \n"
+ // Delay slot: Discard all callee-saved registers.
+ " daddiu $sp, $sp, 96 \n");
diff --git a/chromium/v8/src/heap/base/asm/ppc/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/ppc/push_registers_asm.cc
new file mode 100644
index 00000000000..6936819ba2b
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/ppc/push_registers_asm.cc
@@ -0,0 +1,94 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+
+// PPC ABI source:
+// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html
+
+// AIX Runtime process stack:
+// https://www.ibm.com/support/knowledgecenter/ssw_aix_71/assembler/idalangref_runtime_process.html
+asm(
+#if defined(_AIX)
+ ".globl .PushAllRegistersAndIterateStack, hidden \n"
+ ".csect .text[PR] \n"
+ ".PushAllRegistersAndIterateStack: \n"
+#else
+ ".globl PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+#endif
+ // Push all callee-saved registers.
+ // lr, TOC pointer, r16 to r31. 160 bytes.
+ // The parameter save area shall be allocated by the caller. 112 btes.
+ // At anytime, SP (r1) needs to be multiple of 16 (i.e. 16-aligned).
+ " mflr 0 \n"
+ " std 0, 16(1) \n"
+#if defined(_AIX)
+ " std 2, 40(1) \n"
+#else
+ " std 2, 24(1) \n"
+#endif
+ " stdu 1, -256(1) \n"
+ " std 14, 112(1) \n"
+ " std 15, 120(1) \n"
+ " std 16, 128(1) \n"
+ " std 17, 136(1) \n"
+ " std 18, 144(1) \n"
+ " std 19, 152(1) \n"
+ " std 20, 160(1) \n"
+ " std 21, 168(1) \n"
+ " std 22, 176(1) \n"
+ " std 23, 184(1) \n"
+ " std 24, 192(1) \n"
+ " std 25, 200(1) \n"
+ " std 26, 208(1) \n"
+ " std 27, 216(1) \n"
+ " std 28, 224(1) \n"
+ " std 29, 232(1) \n"
+ " std 30, 240(1) \n"
+ " std 31, 248(1) \n"
+ // Pass 1st parameter (r3) unchanged (Stack*).
+ // Pass 2nd parameter (r4) unchanged (StackVisitor*).
+ // Save 3rd parameter (r5; IterateStackCallback).
+ " mr 6, 5 \n"
+#if defined(_AIX)
+ // Set up TOC for callee.
+ " ld 2,8(5) \n"
+ // AIX uses function decorators, which means that
+ // pointers to functions do not point to code, but
+ // instead point to metadata about them, hence
+ // need to deterrence.
+ " ld 6,0(6) \n"
+#endif
+ // Pass 3rd parameter as sp (stack pointer).
+ " mr 5, 1 \n"
+#if !defined(_AIX)
+ // Set up r12 to be equal to the callee address (in order for TOC
+ // relocation). Only needed on LE Linux.
+ " mr 12, 6 \n"
+#endif
+ // Call the callback.
+ " mtctr 6 \n"
+ " bctrl \n"
+ // Discard all the registers.
+ " addi 1, 1, 256 \n"
+ // Restore lr.
+ " ld 0, 16(1) \n"
+ " mtlr 0 \n"
+#if defined(_AIX)
+ // Restore TOC pointer.
+ " ld 2, 40(1) \n"
+#else
+ " ld 2, 24(1) \n"
+#endif
+ " blr \n");
diff --git a/chromium/v8/src/heap/base/asm/s390/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/s390/push_registers_asm.cc
new file mode 100644
index 00000000000..6b9b2c08536
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/s390/push_registers_asm.cc
@@ -0,0 +1,35 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+
+// See asm/x64/push_registers_clang.cc for why the function is not generated
+// using clang.
+
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+
+// S390 ABI source:
+// http://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html
+asm(".globl PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+ // Push all callee-saved registers.
+ // r6-r13, r14 and sp(r15)
+ " stmg %r6, %sp, 48(%sp) \n"
+ // Allocate frame.
+ " lay %sp, -160(%sp) \n"
+ // Pass 1st parameter (r2) unchanged (Stack*).
+ // Pass 2nd parameter (r3) unchanged (StackVisitor*).
+ // Save 3rd parameter (r4; IterateStackCallback).
+ " lgr %r5, %r4 \n"
+ // Pass sp as 3rd parameter. 160+48 to point
+ // to callee saved region stored above.
+ " lay %r4, 208(%sp) \n"
+ // Call the callback.
+ " basr %r14, %r5 \n"
+ " lmg %r14,%sp, 272(%sp) \n"
+ " br %r14 \n");
diff --git a/chromium/v8/src/heap/base/asm/x64/push_registers_asm.cc b/chromium/v8/src/heap/base/asm/x64/push_registers_asm.cc
new file mode 100644
index 00000000000..68f7918c93c
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/x64/push_registers_asm.cc
@@ -0,0 +1,94 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Push all callee-saved registers to get them on the stack for conservative
+// stack scanning.
+//
+// We cannot rely on clang generating the function and right symbol mangling
+// as `__attribite__((naked))` does not prevent clang from generating TSAN
+// function entry stubs (`__tsan_func_entry`). Even with
+// `__attribute__((no_sanitize_thread)` annotation clang generates the entry
+// stub.
+// See https://bugs.llvm.org/show_bug.cgi?id=45400.
+
+// Do not depend on V8_TARGET_OS_* defines as some embedders may override the
+// GN toolchain (e.g. ChromeOS) and not provide them.
+// _WIN64 Defined as 1 when the compilation target is 64-bit ARM or x64.
+// Otherwise, undefined.
+#ifdef _WIN64
+
+// We maintain 16-byte alignment at calls. There is an 8-byte return address
+// on the stack and we push 72 bytes which maintains 16-byte stack alignment
+// at the call.
+// Source: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
+asm(".globl PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+ // rbp is callee-saved. Maintain proper frame pointer for debugging.
+ " push %rbp \n"
+ " mov %rsp, %rbp \n"
+ // Dummy for alignment.
+ " push $0xCDCDCD \n"
+ " push %rsi \n"
+ " push %rdi \n"
+ " push %rbx \n"
+ " push %r12 \n"
+ " push %r13 \n"
+ " push %r14 \n"
+ " push %r15 \n"
+ // Pass 1st parameter (rcx) unchanged (Stack*).
+ // Pass 2nd parameter (rdx) unchanged (StackVisitor*).
+ // Save 3rd parameter (r8; IterateStackCallback)
+ " mov %r8, %r9 \n"
+ // Pass 3rd parameter as rsp (stack pointer).
+ " mov %rsp, %r8 \n"
+ // Call the callback.
+ " call *%r9 \n"
+ // Pop the callee-saved registers.
+ " add $64, %rsp \n"
+ // Restore rbp as it was used as frame pointer.
+ " pop %rbp \n"
+ " ret \n");
+
+#else // !_WIN64
+
+// We maintain 16-byte alignment at calls. There is an 8-byte return address
+// on the stack and we push 56 bytes which maintains 16-byte stack alignment
+// at the call.
+// Source: https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
+asm(
+#ifdef __APPLE__
+ ".globl _PushAllRegistersAndIterateStack \n"
+ ".private_extern _PushAllRegistersAndIterateStack \n"
+ "_PushAllRegistersAndIterateStack: \n"
+#else // !__APPLE__
+ ".globl PushAllRegistersAndIterateStack \n"
+ ".type PushAllRegistersAndIterateStack, %function \n"
+ ".hidden PushAllRegistersAndIterateStack \n"
+ "PushAllRegistersAndIterateStack: \n"
+#endif // !__APPLE__
+ // rbp is callee-saved. Maintain proper frame pointer for debugging.
+ " push %rbp \n"
+ " mov %rsp, %rbp \n"
+ // Dummy for alignment.
+ " push $0xCDCDCD \n"
+ " push %rbx \n"
+ " push %r12 \n"
+ " push %r13 \n"
+ " push %r14 \n"
+ " push %r15 \n"
+ // Pass 1st parameter (rdi) unchanged (Stack*).
+ // Pass 2nd parameter (rsi) unchanged (StackVisitor*).
+ // Save 3rd parameter (rdx; IterateStackCallback)
+ " mov %rdx, %r8 \n"
+ // Pass 3rd parameter as rsp (stack pointer).
+ " mov %rsp, %rdx \n"
+ // Call the callback.
+ " call *%r8 \n"
+ // Pop the callee-saved registers.
+ " add $48, %rsp \n"
+ // Restore rbp as it was used as frame pointer.
+ " pop %rbp \n"
+ " ret \n");
+
+#endif // !_WIN64
diff --git a/chromium/v8/src/heap/base/asm/x64/push_registers_masm.S b/chromium/v8/src/heap/base/asm/x64/push_registers_masm.S
new file mode 100644
index 00000000000..627843830fa
--- /dev/null
+++ b/chromium/v8/src/heap/base/asm/x64/push_registers_masm.S
@@ -0,0 +1,45 @@
+;; Copyright 2020 the V8 project authors. All rights reserved.
+;; Use of this source code is governed by a BSD-style license that can be
+;; found in the LICENSE file.
+
+;; MASM syntax
+;; https://docs.microsoft.com/en-us/cpp/assembler/masm/microsoft-macro-assembler-reference?view=vs-2019
+
+public PushAllRegistersAndIterateStack
+
+.code
+PushAllRegistersAndIterateStack:
+ ;; Push all callee-saved registers to get them on the stack for conservative
+ ;; stack scanning.
+ ;;
+ ;; We maintain 16-byte alignment at calls. There is an 8-byte return address
+ ;; on the stack and we push 72 bytes which maintains 16-byte stack alignment
+ ;; at the call.
+ ;; Source: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
+ ;;
+ ;; rbp is callee-saved. Maintain proper frame pointer for debugging.
+ push rbp
+ mov rbp, rsp
+ push 0CDCDCDh ;; Dummy for alignment.
+ push rsi
+ push rdi
+ push rbx
+ push r12
+ push r13
+ push r14
+ push r15
+ ;; Pass 1st parameter (rcx) unchanged (Stack*).
+ ;; Pass 2nd parameter (rdx) unchanged (StackVisitor*).
+ ;; Save 3rd parameter (r8; IterateStackCallback)
+ mov r9, r8
+ ;; Pass 3rd parameter as rsp (stack pointer).
+ mov r8, rsp
+ ;; Call the callback.
+ call r9
+ ;; Pop the callee-saved registers.
+ add rsp, 64
+ ;; Restore rbp as it was used as frame pointer.
+ pop rbp
+ ret
+
+end
diff --git a/chromium/v8/src/heap/base/stack.cc b/chromium/v8/src/heap/base/stack.cc
new file mode 100644
index 00000000000..cd284444747
--- /dev/null
+++ b/chromium/v8/src/heap/base/stack.cc
@@ -0,0 +1,129 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/heap/base/stack.h"
+
+#include <limits>
+
+#include "src/base/platform/platform.h"
+#include "src/heap/cppgc/globals.h"
+#include "src/heap/cppgc/sanitizers.h"
+
+namespace heap {
+namespace base {
+
+using IterateStackCallback = void (*)(const Stack*, StackVisitor*, intptr_t*);
+extern "C" void PushAllRegistersAndIterateStack(const Stack*, StackVisitor*,
+ IterateStackCallback);
+
+Stack::Stack(const void* stack_start) : stack_start_(stack_start) {}
+
+bool Stack::IsOnStack(void* slot) const {
+ void* raw_slot = v8::base::Stack::GetStackSlot(slot);
+ return v8::base::Stack::GetCurrentStackPosition() <= raw_slot &&
+ raw_slot <= stack_start_;
+}
+
+namespace {
+
+#ifdef V8_USE_ADDRESS_SANITIZER
+
+// No ASAN support as accessing fake frames otherwise results in
+// "stack-use-after-scope" warnings.
+NO_SANITIZE_ADDRESS
+void IterateAsanFakeFrameIfNecessary(StackVisitor* visitor,
+ void* asan_fake_stack,
+ const void* stack_start,
+ const void* stack_end, void* address) {
+ // When using ASAN fake stack a pointer to the fake frame is kept on the
+ // native frame. In case |addr| points to a fake frame of the current stack
+ // iterate the fake frame. Frame layout see
+ // https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn
+ if (asan_fake_stack) {
+ void* fake_frame_begin;
+ void* fake_frame_end;
+ void* real_stack_frame = __asan_addr_is_in_fake_stack(
+ asan_fake_stack, address, &fake_frame_begin, &fake_frame_end);
+ if (real_stack_frame) {
+ // |address| points to a fake frame. Check that the fake frame is part
+ // of this stack.
+ if (stack_start >= real_stack_frame && real_stack_frame >= stack_end) {
+ // Iterate the fake frame.
+ for (void** current = reinterpret_cast<void**>(fake_frame_begin);
+ current < fake_frame_end; ++current) {
+ void* addr = *current;
+ if (addr == nullptr) continue;
+ visitor->VisitPointer(addr);
+ }
+ }
+ }
+ }
+}
+
+#endif // V8_USE_ADDRESS_SANITIZER
+
+void IterateSafeStackIfNecessary(StackVisitor* visitor) {
+#if defined(__has_feature)
+#if __has_feature(safe_stack)
+ // Source:
+ // https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/safestack/safestack.cpp
+ constexpr size_t kSafeStackAlignmentBytes = 16;
+ void* stack_end = __builtin___get_unsafe_stack_ptr();
+ void* stack_start = __builtin___get_unsafe_stack_top();
+ CHECK_GT(stack_start, stack_end);
+ CHECK_EQ(0u, reinterpret_cast<uintptr_t>(stack_end) &
+ (kSafeStackAlignmentBytes - 1));
+ CHECK_EQ(0u, reinterpret_cast<uintptr_t>(stack_start) &
+ (kSafeStackAlignmentBytes - 1));
+ void** current = reinterpret_cast<void**>(stack_end);
+ for (; current < stack_start; ++current) {
+ void* address = *current;
+ if (address == nullptr) continue;
+ visitor->VisitPointer(address);
+ }
+#endif // __has_feature(safe_stack)
+#endif // defined(__has_feature)
+}
+
+// Called by the trampoline that pushes registers on the stack. This method
+// should never be inlined to ensure that a possible redzone cannot contain
+// any data that needs to be scanned.
+V8_NOINLINE
+// No ASAN support as method accesses redzones while walking the stack.
+NO_SANITIZE_ADDRESS
+void IteratePointersImpl(const Stack* stack, StackVisitor* visitor,
+ intptr_t* stack_end) {
+#ifdef V8_USE_ADDRESS_SANITIZER
+ void* asan_fake_stack = __asan_get_current_fake_stack();
+#endif // V8_USE_ADDRESS_SANITIZER
+ // All supported platforms should have their stack aligned to at least
+ // sizeof(void*).
+ constexpr size_t kMinStackAlignment = sizeof(void*);
+ void** current = reinterpret_cast<void**>(stack_end);
+ CHECK_EQ(0u, reinterpret_cast<uintptr_t>(current) & (kMinStackAlignment - 1));
+ for (; current < stack->stack_start(); ++current) {
+ // MSAN: Instead of unpoisoning the whole stack, the slot's value is copied
+ // into a local which is unpoisoned.
+ void* address = *current;
+ MSAN_UNPOISON(&address, sizeof(address));
+ if (address == nullptr) continue;
+ visitor->VisitPointer(address);
+#ifdef V8_USE_ADDRESS_SANITIZER
+ IterateAsanFakeFrameIfNecessary(visitor, asan_fake_stack,
+ stack->stack_start(), stack_end, address);
+#endif // V8_USE_ADDRESS_SANITIZER
+ }
+}
+
+} // namespace
+
+void Stack::IteratePointers(StackVisitor* visitor) const {
+ PushAllRegistersAndIterateStack(this, visitor, &IteratePointersImpl);
+ // No need to deal with callee-saved registers as they will be kept alive by
+ // the regular conservative stack iteration.
+ IterateSafeStackIfNecessary(visitor);
+}
+
+} // namespace base
+} // namespace heap
diff --git a/chromium/v8/src/heap/base/stack.h b/chromium/v8/src/heap/base/stack.h
new file mode 100644
index 00000000000..a46e6e660ed
--- /dev/null
+++ b/chromium/v8/src/heap/base/stack.h
@@ -0,0 +1,43 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_HEAP_BASE_STACK_H_
+#define V8_HEAP_BASE_STACK_H_
+
+#include "src/base/macros.h"
+
+namespace heap {
+namespace base {
+
+class StackVisitor {
+ public:
+ virtual void VisitPointer(const void* address) = 0;
+};
+
+// Abstraction over the stack. Supports handling of:
+// - native stack;
+// - ASAN/MSAN;
+// - SafeStack: https://releases.llvm.org/10.0.0/tools/clang/docs/SafeStack.html
+class V8_EXPORT_PRIVATE Stack final {
+ public:
+ explicit Stack(const void* stack_start);
+
+ // Returns true if |slot| is part of the stack and false otherwise.
+ bool IsOnStack(void* slot) const;
+
+ // Word-aligned iteration of the stack. Slot values are passed on to
+ // |visitor|.
+ void IteratePointers(StackVisitor* visitor) const;
+
+ // Returns the start of the stack.
+ const void* stack_start() const { return stack_start_; }
+
+ private:
+ const void* stack_start_;
+};
+
+} // namespace base
+} // namespace heap
+
+#endif // V8_HEAP_BASE_STACK_H_