コード例 #1
0
ファイル: unwindamd64.cpp プロジェクト: Fred-Lee/coreclr
//------------------------------------------------------------------------
// Compiler::unwindEmitFuncHelper: Report the unwind information to the VM for a
// given main function or funclet, for either the hot or cold section.
//
// Arguments:
//    func      - The main function or funclet to reserve unwind info for.
//    pHotCode  - Pointer to the beginning of the memory with the function and funclet hot  code.
//    pColdCode - Pointer to the beginning of the memory with the function and funclet cold code.
//                Ignored if 'isHotCode' is true.
//    isHotCode - 'true' to report the hot section, 'false' to report the cold section.
//
void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode)
{
    UNATIVE_OFFSET startOffset;
    UNATIVE_OFFSET endOffset;
    DWORD unwindCodeBytes = 0;
    BYTE* pUnwindBlock = nullptr;

    if (isHotCode)
    {
        if (func->startLoc == nullptr)
        {
            startOffset = 0;
        }
        else
        {
            startOffset = func->startLoc->CodeOffset(genEmitter);
        }

        if (func->endLoc == nullptr)
        {
            endOffset = info.compNativeCodeSize;
        }
        else
        {
            endOffset = func->endLoc->CodeOffset(genEmitter);
        }

#ifdef UNIX_AMD64_ABI
        if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0)
        {
            int size = func->cfiCodes->size();
            if (size > 0)
            {
                unwindCodeBytes = size * sizeof(CFI_CODE);
                pUnwindBlock = (BYTE*)&(*func->cfiCodes)[0];
            }
        }
        else
#endif // UNIX_AMD64_ABI
        {
            unwindCodeBytes = sizeof(func->unwindCodes) - func->unwindCodeSlot;

#ifdef DEBUG
            UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *)(&func->unwindCodes[func->unwindCodeSlot]);
            DWORD unwindCodeBytesSpecified = offsetof(UNWIND_INFO, UnwindCode) + pUnwindInfo->CountOfUnwindCodes * sizeof(UNWIND_CODE); // This is what the unwind codes themselves say; it better match what we tell the VM.
            assert(unwindCodeBytes == unwindCodeBytesSpecified);
#endif // DEBUG

            pUnwindBlock = &func->unwindCodes[func->unwindCodeSlot];
        }
    }
    else
    {
        assert(fgFirstColdBlock != nullptr);
        assert(func->funKind == FUNC_ROOT); // No splitting of funclets.

        if (func->coldStartLoc == nullptr)
        {
            startOffset = 0;
        }
        else
        {
            startOffset = func->coldStartLoc->CodeOffset(genEmitter);
        }

        if (func->coldEndLoc == nullptr)
        {
            endOffset = info.compNativeCodeSize;
        }
        else
        {
            endOffset = func->coldEndLoc->CodeOffset(genEmitter);
        }
    }

#ifdef DEBUG
    if (opts.dspUnwind)
    {
#ifdef UNIX_AMD64_ABI
        if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0)
        {
            DumpCfiInfo(isHotCode, startOffset, endOffset, unwindCodeBytes, (const CFI_CODE * const)pUnwindBlock);
        }
        else
#endif // UNIX_AMD64_ABI
        {
            DumpUnwindInfo(isHotCode, startOffset, endOffset, (const UNWIND_INFO * const)pUnwindBlock);
        }
    }
#endif // DEBUG

    // Adjust for cold or hot code:
    // 1. The VM doesn't want the cold code pointer unless this is cold code.
    // 2. The startOffset and endOffset need to be from the base of the hot section for hot code
    //    and from the base of the cold section for cold code

    if (isHotCode)
    {
        assert(endOffset <= info.compTotalHotCodeSize);
        pColdCode = nullptr;
    }
    else
    {
        assert(startOffset >= info.compTotalHotCodeSize);
        startOffset -= info.compTotalHotCodeSize;
        endOffset   -= info.compTotalHotCodeSize;
    }

    eeAllocUnwindInfo((BYTE*)pHotCode,
                      (BYTE*)pColdCode,
                      startOffset,
                      endOffset,
                      unwindCodeBytes,
                      pUnwindBlock,
                      (CorJitFuncKind)func->funKind);
}
コード例 #2
0
ファイル: unwind.cpp プロジェクト: joshfree/coreclr
void Compiler::unwindEmitFuncCFI(FuncInfoDsc* func, void* pHotCode, void* pColdCode)
{
    UNATIVE_OFFSET startOffset;
    UNATIVE_OFFSET endOffset;
    DWORD          unwindCodeBytes = 0;
    BYTE*          pUnwindBlock    = nullptr;

    if (func->startLoc == nullptr)
    {
        startOffset = 0;
    }
    else
    {
        startOffset = func->startLoc->CodeOffset(genEmitter);
    }

    if (func->endLoc == nullptr)
    {
        endOffset = info.compNativeCodeSize;
    }
    else
    {
        endOffset = func->endLoc->CodeOffset(genEmitter);
    }

    DWORD size = (DWORD)func->cfiCodes->size();
    if (size > 0)
    {
        unwindCodeBytes = size * sizeof(CFI_CODE);
        pUnwindBlock    = (BYTE*)&(*func->cfiCodes)[0];
    }

#ifdef DEBUG
    if (opts.dspUnwind)
    {
        DumpCfiInfo(true /*isHotCode*/, startOffset, endOffset, unwindCodeBytes, (const CFI_CODE* const)pUnwindBlock);
    }
#endif // DEBUG

    assert(endOffset <= info.compTotalHotCodeSize);

    eeAllocUnwindInfo((BYTE*)pHotCode, nullptr /* pColdCode */, startOffset, endOffset, unwindCodeBytes, pUnwindBlock,
                      (CorJitFuncKind)func->funKind);

    if (pColdCode != nullptr)
    {
        assert(fgFirstColdBlock != nullptr);
        assert(func->funKind == FUNC_ROOT); // No splitting of funclets.

        unwindCodeBytes = 0;
        pUnwindBlock    = nullptr;

        if (func->coldStartLoc == nullptr)
        {
            startOffset = 0;
        }
        else
        {
            startOffset = func->coldStartLoc->CodeOffset(genEmitter);
        }

        if (func->coldEndLoc == nullptr)
        {
            endOffset = info.compNativeCodeSize;
        }
        else
        {
            endOffset = func->coldEndLoc->CodeOffset(genEmitter);
        }

#ifdef DEBUG
        if (opts.dspUnwind)
        {
            DumpCfiInfo(false /*isHotCode*/, startOffset, endOffset, unwindCodeBytes,
                        (const CFI_CODE* const)pUnwindBlock);
        }
#endif // DEBUG

        assert(startOffset >= info.compTotalHotCodeSize);
        startOffset -= info.compTotalHotCodeSize;
        endOffset -= info.compTotalHotCodeSize;

        eeAllocUnwindInfo((BYTE*)pHotCode, (BYTE*)pColdCode, startOffset, endOffset, unwindCodeBytes, pUnwindBlock,
                          (CorJitFuncKind)func->funKind);
    }
}