diff options
author | Steve MacLean <sdmaclea.qdt@qualcommdatacenter.com> | 2017-08-25 18:10:50 -0400 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-08-25 15:10:50 -0700 |
commit | f2bbee2ec637c7e2c87d9ab547f3e5ba7d6977e7 (patch) | |
tree | d2184b48fa0bc6010559fd7b920056740e842bcf /src/vm/arm64/asmhelpers.S | |
parent | ff3be834b81ee76736e0ddc1b292b7b2440848ff (diff) | |
download | coreclr-f2bbee2ec637c7e2c87d9ab547f3e5ba7d6977e7.tar.gz coreclr-f2bbee2ec637c7e2c87d9ab547f3e5ba7d6977e7.tar.bz2 coreclr-f2bbee2ec637c7e2c87d9ab547f3e5ba7d6977e7.zip |
[Arm64/Unix] Add JIT_Stelem_Ref helper (#13588)
Diffstat (limited to 'src/vm/arm64/asmhelpers.S')
-rw-r--r-- | src/vm/arm64/asmhelpers.S | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/vm/arm64/asmhelpers.S b/src/vm/arm64/asmhelpers.S index 7a64665b29..017cc50f68 100644 --- a/src/vm/arm64/asmhelpers.S +++ b/src/vm/arm64/asmhelpers.S @@ -1302,3 +1302,100 @@ LEAF_ENTRY JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain, _TEXT ldr x0, [x0, #DomainLocalModule__m_pGCStatics] ret lr LEAF_END JIT_GetSharedGCStaticBaseNoCtor_SingleAppDomain, _TEXT + +// ------------------------------------------------------------------ +// __declspec(naked) void F_CALL_CONV JIT_Stelem_Ref(PtrArray* array, unsigned idx, Object* val) +LEAF_ENTRY JIT_Stelem_Ref, _TEXT + // We retain arguments as they were passed and use x0 == array x1 == idx x2 == val + + // check for null array + cbz x0, LOCAL_LABEL(ThrowNullReferenceException) + + // idx bounds check + ldr x3,[x0,#ArrayBase__m_NumComponents] + cmp x3, x1 + bls LOCAL_LABEL(ThrowIndexOutOfRangeException) + + // fast path to null assignment (doesn't need any write-barriers) + cbz x2, LOCAL_LABEL(AssigningNull) + + // Verify the array-type and val-type matches before writing + ldr x12, [x0] // x12 = array MT + ldr x3, [x2] // x3 = val->GetMethodTable() + ldr x12, [x12, #MethodTable__m_ElementType] // array->GetArrayElementTypeHandle() + cmp x3, x12 + beq C_FUNC(JIT_Stelem_DoWrite) + + // Types didnt match but allow writing into an array of objects + ldr x3, =g_pObjectClass + ldr x3, [x3] // x3 = *g_pObjectClass + cmp x3, x12 // array type matches with Object* + beq C_FUNC(JIT_Stelem_DoWrite) + + // array type and val type do not exactly match. Raise frame and do detailed match + b C_FUNC(JIT_Stelem_Ref_NotExactMatch) + +LOCAL_LABEL(AssigningNull): + // Assigning null doesn't need write barrier + add x0, x0, x1, LSL #3 // x0 = x0 + (x1 x 8) = array->m_array[idx] + str x2, [x0, #PtrArray__m_Array] // array->m_array[idx] = val + ret + +LOCAL_LABEL(ThrowNullReferenceException): + // Tail call JIT_InternalThrow(NullReferenceException) + ldr x0, =CORINFO_NullReferenceException_ASM + b C_FUNC(JIT_InternalThrow) + +LOCAL_LABEL(ThrowIndexOutOfRangeException): + // Tail call JIT_InternalThrow(NullReferenceException) + ldr x0, =CORINFO_IndexOutOfRangeException_ASM + b C_FUNC(JIT_InternalThrow) + +LEAF_END JIT_Stelem_Ref, _TEXT + +// ------------------------------------------------------------------ +// __declspec(naked) void F_CALL_CONV JIT_Stelem_Ref_NotExactMatch(PtrArray* array, +// unsigned idx, Object* val) +// x12 = array->GetArrayElementTypeHandle() +// +NESTED_ENTRY JIT_Stelem_Ref_NotExactMatch, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -48 + // Spill callee saved registers + PROLOG_SAVE_REG_PAIR x0, x1, 16 + PROLOG_SAVE_REG x2, 32 + + // allow in case val can be casted to array element type + // call ObjIsInstanceOfNoGC(val, array->GetArrayElementTypeHandle()) + mov x1, x12 // array->GetArrayElementTypeHandle() + mov x0, x2 + bl C_FUNC(ObjIsInstanceOfNoGC) + cmp x0, TypeHandle_CanCast + beq LOCAL_LABEL(DoWrite) // ObjIsInstance returned TypeHandle::CanCast + + // check via raising frame +LOCAL_LABEL(NeedFrame): + add x1, sp, #16 // x1 = &array + add x0, sp, #32 // x0 = &val + + bl C_FUNC(ArrayStoreCheck) // ArrayStoreCheck(&val, &array) + +LOCAL_LABEL(DoWrite): + EPILOG_RESTORE_REG_PAIR x0, x1, 16 + EPILOG_RESTORE_REG x2, 32 + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 48 + b C_FUNC(JIT_Stelem_DoWrite) +NESTED_END JIT_Stelem_Ref_NotExactMatch, _TEXT + +// ------------------------------------------------------------------ +// __declspec(naked) void F_CALL_CONV JIT_Stelem_DoWrite(PtrArray* array, unsigned idx, Object* val) +LEAF_ENTRY JIT_Stelem_DoWrite, _TEXT + + // Setup args for JIT_WriteBarrier. x14 = &array->m_array[idx] x15 = val + add x14, x0, #PtrArray__m_Array // x14 = &array->m_array + add x14, x14, x1, LSL #3 + mov x15, x2 // x15 = val + + // Branch to the write barrier (which is already correctly overwritten with + // single or multi-proc code based on the current CPU + b C_FUNC(JIT_WriteBarrier) +LEAF_END JIT_Stelem_DoWrite, _TEXT |