Commit 09b0aae8 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

Reland "cppgc: Stack scanning support for Windows native"

Assumes that (is_clang = false && is_win) => Windows native (MSVC).

Cross-compile builds will use clang and not the native tools and thus
not fall into this category.

This CL adds x86 and x64 MASM trampolines that can be used with the
native Windows toolchain (ml.exe, ml64.exe), when using is_clang =
false.

This reverts commit 8e4a5e97.

Bug: chromium:1056170
Change-Id: I7204f15898ec5eddcc5892d4d08266a69d84ab85
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2139211
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67036}
parent 7b322ce4
...@@ -349,12 +349,16 @@ config("libbase_config") { ...@@ -349,12 +349,16 @@ config("libbase_config") {
# This config should be applied to code using the cppgc_base. # This config should be applied to code using the cppgc_base.
config("cppgc_base_config") { config("cppgc_base_config") {
# Assume is_clang = false means GCC or other compilers that are compatible # Assume is_clang = false means GCC or other compilers that are compatible
# with gas inline assembly on non-Windows builds. # with gas inline assembly on non-Windows builds. Cross builds for
# Linux->Windows are covered as they use clang.
if (is_clang || !is_win) { if (is_clang || !is_win) {
if (target_cpu == "x64" || target_cpu == "x86" || target_cpu == "arm" || if (target_cpu == "x64" || target_cpu == "x86" || target_cpu == "arm" ||
target_cpu == "arm64") { target_cpu == "arm64") {
defines = [ "CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN" ] defines = [ "CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN" ]
} }
} else if (is_win) {
# Assume that non-clang builds on Windows use native tools.
defines = [ "CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN" ]
} }
} }
...@@ -3980,6 +3984,12 @@ v8_source_set("cppgc_base") { ...@@ -3980,6 +3984,12 @@ v8_source_set("cppgc_base") {
} else if (target_cpu == "arm64") { } else if (target_cpu == "arm64") {
sources += [ "src/heap/cppgc/asm/arm64/push_registers_asm.cc" ] sources += [ "src/heap/cppgc/asm/arm64/push_registers_asm.cc" ]
} }
} else if (is_win) {
if (target_cpu == "x64") {
sources += [ "src/heap/cppgc/asm/x64/push_registers_masm.S" ]
} else if (target_cpu == "x86") {
sources += [ "src/heap/cppgc/asm/ia32/push_registers_masm.S" ]
}
} }
configs = [ configs = [
......
;; 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
;; 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
...@@ -48,11 +48,21 @@ TEST_F(GCHeapTest, PreciseGCReclaimsObjectOnStack) { ...@@ -48,11 +48,21 @@ TEST_F(GCHeapTest, PreciseGCReclaimsObjectOnStack) {
EXPECT_EQ(1u, Foo::destructor_callcount); EXPECT_EQ(1u, Foo::destructor_callcount);
} }
namespace {
const void* ConservativeGCReturningObject(cppgc::Heap* heap,
const void* volatile object) {
internal::Heap::From(heap)->CollectGarbage(
{Heap::GCConfig::StackState::kNonEmpty});
return object;
}
} // namespace
TEST_F(GCHeapTest, ConservaitveGCRetainsObjectOnStack) { TEST_F(GCHeapTest, ConservaitveGCRetainsObjectOnStack) {
Foo* volatile do_not_access = MakeGarbageCollected<Foo>(GetHeap()); Foo* volatile object = MakeGarbageCollected<Foo>(GetHeap());
USE(do_not_access);
EXPECT_EQ(0u, Foo::destructor_callcount); EXPECT_EQ(0u, Foo::destructor_callcount);
ConservativeGC(); EXPECT_EQ(object, ConservativeGCReturningObject(GetHeap(), object));
EXPECT_EQ(0u, Foo::destructor_callcount); EXPECT_EQ(0u, Foo::destructor_callcount);
PreciseGC(); PreciseGC();
EXPECT_EQ(1u, Foo::destructor_callcount); EXPECT_EQ(1u, Foo::destructor_callcount);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment