-//
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-//
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
.intel_syntax noprefix
#include "unixasmmacros.inc"
// Entry:
// RDI - address of ref-field (assigned to)
// RSI - address of the data (source)
-// RCX can be trashed
+//
+// Note: RyuJIT assumes that all volatile registers can be trashed by
+// the CORINFO_HELP_ASSIGN_BYREF helper (i.e. JIT_ByRefWriteBarrier).
+// The precise set is defined by RBM_CALLEE_TRASH.
+//
+// RCX is trashed
+// RAX is trashed
+// R10 is trashed on Debug build
+// R11 is trashed on Debug build
// Exit:
// RDI, RSI are incremented by SIZEOF(LPVOID)
LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT
- push rax
mov rcx, [rsi]
// If !WRITE_BARRIER_CHECK do the write first, otherwise we might have to do some ShadowGC stuff
jnb NotInHeap_ByRefWriteBarrier
#ifdef WRITE_BARRIER_CHECK
- // we can only trash rcx in this function so in _DEBUG we need to save
- // some scratch registers.
- push r10
- push r11
-
// **ALSO update the shadow GC heap if that is enabled**
// Do not perform the work if g_GCShadow is 0
PREPARE_EXTERNAL_VAR g_GCShadow, rax
mov rax, [r10]
cmp rax, r11
je DoneShadow_ByRefWriteBarrier
- mov r11, INVALIDGCVALUE
+ movabs r11, INVALIDGCVALUE
mov [r10], r11
jmp DoneShadow_ByRefWriteBarrier
// Additionally we know for sure that we are inside the heap and therefore don't
// need to replicate the above checks.
DoneShadow_ByRefWriteBarrier:
- pop r11
- pop r10
#endif
// See if we can just quick out
PREPARE_EXTERNAL_VAR g_card_table, rax
add rcx, [rax]
- pop rax
-
// Check if this card is dirty
cmp byte ptr [rcx], 0FFh
jne UpdateCardTable_ByRefWriteBarrier
// Increment the pointers before leaving
add rdi, 8h
add rsi, 8h
- pop rax
ret
LEAF_END JIT_ByRefWriteBarrier, _TEXT