diff options
author | sergey ignatov <sergign60@mail.ru> | 2017-08-04 16:17:35 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-08-04 16:17:35 +0300 |
commit | 0c8701cc5d0ee947a3eb78a977d9581ac667eeac (patch) | |
tree | 6f63178f608186b14ae0b41f048355decf6fd39e /src/Native/Runtime/arm | |
parent | 6953f03fdd6621db40a63f545aa2d8c2f798dc9d (diff) |
[armel tizen] Implemented StubDispatch.S stubs (#4265)
Diffstat (limited to 'src/Native/Runtime/arm')
-rw-r--r-- | src/Native/Runtime/arm/StubDispatch.S | 196 |
1 files changed, 150 insertions, 46 deletions
diff --git a/src/Native/Runtime/arm/StubDispatch.S b/src/Native/Runtime/arm/StubDispatch.S index 7c79a11b8..d6293dc80 100644 --- a/src/Native/Runtime/arm/StubDispatch.S +++ b/src/Native/Runtime/arm/StubDispatch.S @@ -2,81 +2,185 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#include <unixasmmacros.inc> - .syntax unified .thumb +#include <unixasmmacros.inc> +#include <AsmOffsets.inc> // generated by the build from AsmOffsets.cpp + +#ifdef FEATURE_CACHED_INTERFACE_DISPATCH + // TODO: Implement Arm support +#ifdef _DEBUG +.rodata +AssertMsg: .asciz "__FILE__:%s: %s is not implemented\n" +FileName: .asciz "StubDispatch.S" +RhpCastableObjectDispatch_CommonStubName: .asciz "RhpCastableObjectDispatch_CommonStub" +RhpTailCallTLSDispatchCellName: .asciz "RhpTailCallTLSDispatchCell" +RhpCastableObjectDispatchHelper_TailCalledName: .asciz "RhpCastableObjectDispatchHelper_TailCalled" +RhpCastableObjectDispatchHelperName: .asciz "RhpCastableObjectDispatchHelper" +RhpVTableOffsetDispatchName: .asciz "RhpVTableOffsetDispatch" +.text +.macro GEN_ASSERT_FUNC func + GEN_ASSERT AssertMsg, FileName, \func +.endm +#endif + LEAF_ENTRY RhpCastableObjectDispatch_CommonStub, _TEXT - // UNIXTODO: Implement this function - //int 3 +#ifdef _DEBUG + GEN_ASSERT_FUNC RhpCastableObjectDispatch_CommonStubName +#else + // UNIXTODO: Implement this function + EMIT_BREAKPOINT +#endif LEAF_END RhpCastableObjectDispatch_CommonStub, _TEXT LEAF_ENTRY RhpTailCallTLSDispatchCell, _TEXT - // UNIXTODO: Implement this function - // int 3 +#ifdef _DEBUG + GEN_ASSERT_FUNC RhpTailCallTLSDispatchCellName +#else + // UNIXTODO: Implement this function + EMIT_BREAKPOINT +#endif LEAF_END RhpTailCallTLSDispatchCell, _TEXT LEAF_ENTRY RhpCastableObjectDispatchHelper_TailCalled, _TEXT - // UNIXTODO: Implement this function - // int 3 +#ifdef _DEBUG + GEN_ASSERT_FUNC RhpCastableObjectDispatchHelper_TailCalledName +#else + // UNIXTODO: Implement this function + EMIT_BREAKPOINT +#endif LEAF_END RhpCastableObjectDispatchHelper_TailCalled, _TEXT LEAF_ENTRY RhpCastableObjectDispatchHelper, _TEXT - // UNIXTODO: Implement this function - // int 3 +#ifdef _DEBUG + GEN_ASSERT_FUNC RhpCastableObjectDispatchHelperName +#else + // UNIXTODO: Implement this function + EMIT_BREAKPOINT +#endif LEAF_END RhpCastableObjectDispatchHelper, _TEXT +// Macro that generates a stub consuming a cache with the given number of entries. +.macro DEFINE_INTERFACE_DISPATCH_STUB entries + +LEAF_ENTRY RhpInterfaceDispatch\entries, _TEXT + // r12 currently contains the indirection cell address. But we need more scratch registers and + // we may A/V on a null this. Both of these suggest we need a real prolog and epilog. + PROLOG_PUSH {r1-r2} + + // r12 currently holds the indirection cell address. We need to get the cache structure instead. + ldr r2, [r12, #OFFSETOF__InterfaceDispatchCell__m_pCache] + + // Load the EEType from the object instance in r0. + ldr r1, [r0] + + CurrentOffset = OFFSETOF__InterfaceDispatchCache__m_rgEntries + // For each entry in the cache, see if its EEType type matches the EEType in r1. + // If so, call the second cache entry. If not, skip the InterfaceDispatchCacheEntry. + // R1 : Instance EEType* + // R2: Cache data structure + // R12 : Trashed. On succesful check, set to the target address to jump to. + .rept \entries + ldr r12, [r2, #CurrentOffset] + cmp r1, r12 + bne 0f + ldr r12, [r2, #(CurrentOffset + 4)] + b LOCAL_LABEL(99_\entries) + 0: + CurrentOffset = CurrentOffset + 8 + .endr + + // Point r12 to the indirection cell using the back pointer in the cache block + ldr r12, [r2, #OFFSETOF__InterfaceDispatchCache__m_pCell] + + EPILOG_POP {r1-r2} + b C_FUNC(RhpInterfaceDispatchSlow) + + // Common epilog for cache hits. Have to out of line it here due to limitation on the number of + // epilogs imposed by the unwind code macros. +LOCAL_LABEL(99_\entries): + // R2 contains address of the cache block. We store it in the red zone in case the target we jump + // to needs it. Currently the RhpCastableObjectDispatchHelper is the only such target. + // R12 contains the target address to jump to + EPILOG_POP {r1} + // The red zone is only 8 bytes long, so we have to store r2 into it between the pops. + str r2, [sp, #-4] + EPILOG_POP {r2} + EPILOG_BRANCH_REG r12 + +LEAF_END RhpInterfaceDispatch\entries, _TEXT + +.endm // DEFINE_INTERFACE_DISPATCH_STUB + +// Define all the stub routines we currently need. +// +// The mrt100dbi requires these be exported to identify mrt100 code that dispatches back into managed. +// If you change or add any new dispatch stubs, please also change slr.def and dbi\process.cpp CordbProcess::GetExportStepInfo +// +DEFINE_INTERFACE_DISPATCH_STUB 1 +DEFINE_INTERFACE_DISPATCH_STUB 2 +DEFINE_INTERFACE_DISPATCH_STUB 4 +DEFINE_INTERFACE_DISPATCH_STUB 8 +DEFINE_INTERFACE_DISPATCH_STUB 16 +DEFINE_INTERFACE_DISPATCH_STUB 32 +DEFINE_INTERFACE_DISPATCH_STUB 64 // Stub dispatch routine for dispatch to a vtable slot LEAF_ENTRY RhpVTableOffsetDispatch, _TEXT - // UNIXTODO: Implement this function - // int 3 + // On input we have the indirection cell data structure in r12. But we need more scratch registers and + // we may A/V on a null this. Both of these suggest we need a real prolog and epilog. + PROLOG_PUSH {r1} + + // r12 currently holds the indirection cell address. We need to update it to point to the vtable + // offset instead. + ldr r12, [r12, #OFFSETOF__InterfaceDispatchCell__m_pCache] + + // Load the EEType from the object instance in r0. + ldr r1, [r0] + + // add the vtable offset to the EEType pointer + add r12, r1, r12 + + // Load the target address of the vtable into r12 + ldr r12, [r12] + + EPILOG_POP {r1} + EPILOG_BRANCH_REG r12 LEAF_END RhpVTableOffsetDispatch, _TEXT // Initial dispatch on an interface when we don't have a cache yet. LEAF_ENTRY RhpInitialInterfaceDispatch, _TEXT -ALTERNATE_ENTRY RhpInitialDynamicInterfaceDispatch - - // Just tail call to the cache miss helper. - // jmp C_FUNC(RhpInterfaceDispatchSlow) + // The stub that jumped here pushed r12, which contains the interface dispatch cell + // we need to pop it here + pop { r12 } + // Just tail call to the cache miss helper. + b C_FUNC(RhpInterfaceDispatchSlow) LEAF_END RhpInitialInterfaceDispatch, _TEXT +// No as alternate entry due to missed thumb bit in this case +// See https://github.com/dotnet/coreclr/issues/12953 +LEAF_ENTRY RhpInitialDynamicInterfaceDispatch, _TEXT + // Just tail call to the cache miss helper. + b C_FUNC(RhpInterfaceDispatchSlow) +LEAF_END RhpInitialDynamicInterfaceDispatch, _TEXT + // Cache miss case, call the runtime to resolve the target and update the cache. // Use universal transition helper to allow an exception to flow out of resolution LEAF_ENTRY RhpInterfaceDispatchSlow, _TEXT - // jmp C_FUNC(RhpUniversalTransition_DebugStepTailCall) - + // r12 has the interface dispatch cell address in it. + // The calling convention of the universal thunk is that the parameter + // for the universal thunk target is to be placed in sp-8 + // and the universal thunk target address is to be placed in sp-4 + str r12, [sp, #-8] + ldr r12, =C_FUNC(RhpCidResolve) + str r12, [sp, #-4] + + // jump to universal transition thunk + b C_FUNC(RhpUniversalTransition_DebugStepTailCall) LEAF_END RhpInterfaceDispatchSlow, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch1, _TEXT - -LEAF_END RhpInterfaceDispatch1, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch2, _TEXT - -LEAF_END RhpInterfaceDispatch2, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch4, _TEXT - -LEAF_END RhpInterfaceDispatch4, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch8, _TEXT - -LEAF_END RhpInterfaceDispatch8, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch16, _TEXT - -LEAF_END RhpInterfaceDispatch16, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch32, _TEXT - -LEAF_END RhpInterfaceDispatch32, _TEXT - -LEAF_ENTRY RhpInterfaceDispatch64, _TEXT - -LEAF_END RhpInterfaceDispatch64, _TEXT +#endif // FEATURE_CACHED_INTERFACE_DISPATCH |