summaryrefslogtreecommitdiff
path: root/src/vm/amd64
diff options
context:
space:
mode:
authorXiangyang (Mark) Guo <xiangyang.guo@intel.com>2016-06-03 18:51:17 -0700
committerJan Kotas <jkotas@microsoft.com>2016-06-03 18:51:17 -0700
commitc1c508157493c5ccef30285eaa65630254ddf479 (patch)
treeedda46ada93223a6c413d431bcbe14ce256ec095 /src/vm/amd64
parent2507807811cf6a33a946c2382e6d56961e4bff74 (diff)
downloadcoreclr-c1c508157493c5ccef30285eaa65630254ddf479.tar.gz
coreclr-c1c508157493c5ccef30285eaa65630254ddf479.tar.bz2
coreclr-c1c508157493c5ccef30285eaa65630254ddf479.zip
Added JIT_Stelem_Ref helper function for Linux (#5390)
Diffstat (limited to 'src/vm/amd64')
-rw-r--r--src/vm/amd64/asmconstants.h2
-rw-r--r--src/vm/amd64/cgencpu.h3
-rw-r--r--src/vm/amd64/jithelpers_fast.S142
3 files changed, 146 insertions, 1 deletions
diff --git a/src/vm/amd64/asmconstants.h b/src/vm/amd64/asmconstants.h
index d58bd5703d..32b23c83c3 100644
--- a/src/vm/amd64/asmconstants.h
+++ b/src/vm/amd64/asmconstants.h
@@ -663,7 +663,9 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__TransitionBlock__m_argumentRegisters == offsetof
#undef ASMCONSTANTS_RUNTIME_ASSERT
#undef ASMCONSTANTS_C_ASSERT
+#ifndef UNIX_AMD64_ABI
#undef DBG_FRE
+#endif // UNIX_AMD64_ABI
//#define USE_COMPILE_TIME_CONSTANT_FINDER // Uncomment this line to use the constant finder
diff --git a/src/vm/amd64/cgencpu.h b/src/vm/amd64/cgencpu.h
index 3d99b6f7f0..409b8e5159 100644
--- a/src/vm/amd64/cgencpu.h
+++ b/src/vm/amd64/cgencpu.h
@@ -554,8 +554,9 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
#define JIT_IsInstanceOfClass JIT_IsInstanceOfClass
#define JIT_ChkCastInterface JIT_ChkCastInterface
#define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface
-#define JIT_Stelem_Ref JIT_Stelem_Ref
#endif // FEATURE_PAL
+#define JIT_Stelem_Ref JIT_Stelem_Ref
+
#endif // __cgencpu_h__
diff --git a/src/vm/amd64/jithelpers_fast.S b/src/vm/amd64/jithelpers_fast.S
index 6edcd25249..8076655ad9 100644
--- a/src/vm/amd64/jithelpers_fast.S
+++ b/src/vm/amd64/jithelpers_fast.S
@@ -4,6 +4,7 @@
.intel_syntax noprefix
#include "unixasmmacros.inc"
+#include "asmconstants.h"
// Mark start of the code region that we patch at runtime
LEAF_ENTRY JIT_PatchedCodeStart, _TEXT
@@ -329,3 +330,144 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT
add rsi, 8h
ret
LEAF_END JIT_ByRefWriteBarrier, _TEXT
+
+// TODO: put definition for this in asmconstants.h
+#define CanCast 1
+
+//__declspec(naked) void F_CALL_CONV JIT_Stelem_Ref(PtrArray* array, unsigned idx, Object* val)
+.balign 16
+LEAF_ENTRY JIT_Stelem_Ref, _TEXT
+ // check for null PtrArray*
+ test rdi, rdi
+ je LOCAL_LABEL(ThrowNullReferenceException)
+
+ // we only want the lower 32-bits of rsi, it might be dirty
+ or esi, esi
+
+ // check that index is in bounds
+ cmp esi, dword ptr [rdi + OFFSETOF__PtrArray__m_NumComponents] // 8h -> array size offset
+ jae LOCAL_LABEL(ThrowIndexOutOfRangeException)
+
+ // r10 = Array MT
+ mov r10, [rdi]
+
+ // if we're assigning a null object* then we don't need a write barrier
+ test rdx, rdx
+ jz LOCAL_LABEL(AssigningNull)
+
+#ifdef CHECK_APP_DOMAIN_LEAKS
+ // get Array TypeHandle
+ mov rcx, [r10 + OFFSETOF__MethodTable__m_ElementType] // 10h -> typehandle offset,
+ // check for non-MT
+ test rcx, 2
+ jnz LOCAL_LABEL(NoCheck)
+
+ // Check VMflags of element type
+ mov rcx, [rcx + OFFSETOF__MethodTable__m_pEEClass]
+ mov ecx, dword ptr [rcx + OFFSETOF__EEClass__m_wAuxFlags]
+ test ecx, EEClassFlags
+ jnz C_FUNC(ArrayStoreCheck_Helper)
+
+ LOCAL_LABEL(NoCheck):
+#endif
+
+ mov rcx, [r10 + OFFSETOF__MethodTable__m_ElementType] // 10h -> typehandle offset
+
+ // check for exact match
+ cmp rcx, [rdx]
+ jne LOCAL_LABEL(NotExactMatch)
+
+ LOCAL_LABEL(DoWrite):
+ lea rdi, [rdi + 8*rsi]
+ add rdi, OFFSETOF__PtrArray__m_Array
+ mov rsi, rdx
+
+ // JIT_WriteBarrier(Object** dst, Object* src)
+ jmp C_FUNC(JIT_WriteBarrier)
+
+ LOCAL_LABEL(AssigningNull):
+ // write barrier is not needed for assignment of NULL references
+ mov [rdi + 8*rsi + OFFSETOF__PtrArray__m_Array], rdx
+ ret
+
+ LOCAL_LABEL(NotExactMatch):
+ PREPARE_EXTERNAL_VAR g_pObjectClass, r11
+ cmp rcx, [r11]
+ je LOCAL_LABEL(DoWrite)
+
+ jmp C_FUNC(JIT_Stelem_Ref__ObjIsInstanceOfNoGC_Helper)
+
+ LOCAL_LABEL(ThrowNullReferenceException):
+ mov rdi, CORINFO_NullReferenceException_ASM
+ jmp C_FUNC(JIT_InternalThrow)
+
+ LOCAL_LABEL(ThrowIndexOutOfRangeException):
+ mov rdi, CORINFO_IndexOutOfRangeException_ASM
+ jmp C_FUNC(JIT_InternalThrow)
+LEAF_END JIT_Stelem_Ref, _TEXT
+
+LEAF_ENTRY JIT_Stelem_Ref__ObjIsInstanceOfNoGC_Helper, _TEXT
+ push_nonvol_reg rbp
+ mov rbp, rsp
+ set_cfa_register rbp, 16
+
+ sub rsp, 0x20
+ mov [rbp - 0x08], rdi
+ mov [rbp - 0x10], rsi
+ mov [rbp - 0x18], rdx
+
+ // need to get TypeHandle before setting rcx to be the Obj* because that trashes the PtrArray*
+ mov rsi, rcx
+ mov rdi, rdx
+
+ // TypeHandle::CastResult ObjIsInstanceOfNoGC(Object *pElement, TypeHandle toTypeHnd)
+ call C_FUNC(ObjIsInstanceOfNoGC)
+
+ mov rdi, [rbp - 0x08]
+ mov rsi, [rbp - 0x10]
+ mov rdx, [rbp - 0x18]
+
+ RESET_FRAME_WITH_RBP
+
+ cmp eax, CanCast
+ jne LOCAL_LABEL(NeedCheck)
+
+ lea rdi, [rdi + 8*rsi]
+ add rdi, OFFSETOF__PtrArray__m_Array
+ mov rsi, rdx
+
+ // JIT_WriteBarrier(Object** dst, Object* src)
+ jmp C_FUNC(JIT_WriteBarrier)
+
+ LOCAL_LABEL(NeedCheck):
+ jmp C_FUNC(JIT_Stelem_Ref__ArrayStoreCheck_Helper)
+LEAF_END JIT_Stelem_Ref__ObjIsInstanceOfNoGC_Helper, _TEXT
+
+// Need to save reg to provide a stack address for the Object*
+LEAF_ENTRY JIT_Stelem_Ref__ArrayStoreCheck_Helper, _TEXT
+ push_nonvol_reg rbp
+ mov rbp, rsp
+ set_cfa_register rbp, 16
+
+ sub rsp, 0x20
+ mov [rbp - 0x10], rdi
+ mov [rbp - 0x18], rsi
+ mov [rbp - 0x20], rdx
+
+ mov rdi, rsp
+ lea rsi, [rbp - 0x10]
+ // HCIMPL2(FC_INNER_RET, ArrayStoreCheck, Object** pElement, PtrArray** pArray)
+ call C_FUNC(ArrayStoreCheck)
+ mov rdi, [rbp - 0x10]
+ mov rsi, [rbp - 0x18]
+ mov rdx, [rbp - 0x20]
+
+ lea rdi, [rdi + 8*rsi]
+ add rdi, OFFSETOF__PtrArray__m_Array
+ mov rsi, rdx
+
+ RESET_FRAME_WITH_RBP
+
+ // JIT_WriteBarrier(Object** dst, Object* src)
+ jmp C_FUNC(JIT_WriteBarrier)
+LEAF_END JIT_Stelem_Ref__ArrayStoreCheck_Helper, _TEXT