blob: 8f0a889fde231e3f68414e124e8515d7c32e27b6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
// 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.
// ===========================================================================
// File: JITHelpers.CPP
// ===========================================================================
// This contains JITinterface routines that are specific to the
// AMD64 platform. They are modeled after the X86 specific routines
// found in JIThelp.asm
#include "common.h"
#include "jitinterface.h"
#include "eeconfig.h"
#include "excep.h"
#include "ecall.h"
#include "asmconstants.h"
EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
TailCallFrame * TailCallFrame::GetFrameFromContext(CONTEXT * pContext)
{
_ASSERTE((void*)::GetIP(pContext) == JIT_TailCallHelperStub_ReturnAddress);
return (TailCallFrame*)(pContext->R13 + sizeof(GSCookie));
}
// Assuming pContext is a plain generic call-site, adjust it to look like
// it called into TailCallHelperStub, and is at the point of the call.
TailCallFrame * TailCallFrame::AdjustContextForTailCallHelperStub(CONTEXT * pContext, size_t cbNewArgArea, Thread * pThread)
{
TailCallFrame * pNewFrame = (TailCallFrame *)(GetSP(pContext) - sizeof(TailCallFrame));
// R13 is the frame pointer (for popping the stack)
pContext->R13 = (size_t)pNewFrame - sizeof(GSCookie);
// R12 is the previous stack pointer, so we can determine if a return buffer from the
// immediate caller (and thus being discarded via the tail call), or someplace else
pContext->R12 = GetSP(pContext);
// for the args and pushed return address of the 'call'
SetSP(pContext, (size_t)pNewFrame - (cbNewArgArea + sizeof(void*) + sizeof(GSCookie)));
// For popping the Frame, store the Thread
pContext->R14 = (DWORD_PTR)pThread;
// And the current head/top
pContext->R15 = (DWORD_PTR)pThread->GetFrame(); // m_Next
return (TailCallFrame *) pNewFrame;
}
|