| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- #include "NativeEntryPointData.h"
- #include "JitTransferData.h"
- JITOutput::JITOutput(JITOutputIDL * outputData) :
- m_outputData(outputData),
- m_inProcAlloc(nullptr),
- m_func(nullptr)
- {
- }
- void
- JITOutput::SetHasJITStackClosure()
- {
- m_outputData->hasJittedStackClosure = true;
- }
- void
- JITOutput::SetVarSlotsOffset(int32 offset)
- {
- m_outputData->localVarSlotsOffset = offset;
- }
- void
- JITOutput::SetVarChangedOffset(int32 offset)
- {
- m_outputData->localVarChangedOffset = offset;
- }
- void
- JITOutput::SetHasBailoutInstr(bool val)
- {
- m_outputData->hasBailoutInstr = val;
- }
- void
- JITOutput::SetArgUsedForBranch(uint8 param)
- {
- Assert(param > 0);
- Assert(param < Js::Constants::MaximumArgumentCountForConstantArgumentInlining);
- m_outputData->argUsedForBranch |= (1 << (param - 1));
- }
- void
- JITOutput::SetFrameHeight(uint val)
- {
- m_outputData->frameHeight = val;
- }
- void
- JITOutput::RecordThrowMap(Js::ThrowMapEntry * throwMap, uint mapCount)
- {
- m_outputData->throwMapOffset = NativeCodeData::GetDataTotalOffset(throwMap);
- m_outputData->throwMapCount = mapCount;
- }
- bool
- JITOutput::IsTrackCompoundedIntOverflowDisabled() const
- {
- return m_outputData->disableTrackCompoundedIntOverflow != FALSE;
- }
- bool
- JITOutput::IsArrayCheckHoistDisabled() const
- {
- return m_outputData->disableArrayCheckHoist != FALSE;
- }
- bool
- JITOutput::IsStackArgOptDisabled() const
- {
- return m_outputData->disableStackArgOpt != FALSE;
- }
- bool
- JITOutput::IsSwitchOptDisabled() const
- {
- return m_outputData->disableSwitchOpt != FALSE;
- }
- bool
- JITOutput::IsAggressiveIntTypeSpecDisabled() const
- {
- return m_outputData->disableAggressiveIntTypeSpec != FALSE;
- }
- uint16
- JITOutput::GetArgUsedForBranch() const
- {
- return m_outputData->argUsedForBranch;
- }
- intptr_t
- JITOutput::GetCodeAddress() const
- {
- return (intptr_t)m_outputData->codeAddress;
- }
- void
- JITOutput::SetCodeAddress(intptr_t addr)
- {
- m_outputData->codeAddress = addr;
- }
- size_t
- JITOutput::GetCodeSize() const
- {
- return (size_t)m_outputData->codeSize;
- }
- ushort
- JITOutput::GetPdataCount() const
- {
- return m_outputData->pdataCount;
- }
- ushort
- JITOutput::GetXdataSize() const
- {
- return m_outputData->xdataSize;
- }
- EmitBufferAllocation<VirtualAllocWrapper, PreReservedVirtualAllocWrapper> *
- JITOutput::RecordInProcNativeCodeSize(Func *func, uint32 bytes, ushort pdataCount, ushort xdataSize)
- {
- m_func = func;
- #if defined(_M_ARM32_OR_ARM64)
- bool canAllocInPreReservedHeapPageSegment = false;
- #else
- bool canAllocInPreReservedHeapPageSegment = m_func->CanAllocInPreReservedHeapPageSegment();
- #endif
- BYTE *buffer = nullptr;
- m_inProcAlloc = m_func->GetInProcCodeGenAllocators()->emitBufferManager.AllocateBuffer(bytes, &buffer, pdataCount, xdataSize, canAllocInPreReservedHeapPageSegment, true);
- if (buffer == nullptr)
- {
- Js::Throw::OutOfMemory();
- }
- m_outputData->codeAddress = (intptr_t)buffer;
- m_outputData->codeSize = bytes;
- m_outputData->pdataCount = pdataCount;
- m_outputData->xdataSize = xdataSize;
- m_outputData->isInPrereservedRegion = m_inProcAlloc->inPrereservedRegion;
- return m_inProcAlloc;
- }
- #if ENABLE_OOP_NATIVE_CODEGEN
- EmitBufferAllocation<SectionAllocWrapper, PreReservedSectionAllocWrapper> *
- JITOutput::RecordOOPNativeCodeSize(Func *func, uint32 bytes, ushort pdataCount, ushort xdataSize)
- {
- m_func = func;
- #if defined(_M_ARM32_OR_ARM64)
- bool canAllocInPreReservedHeapPageSegment = false;
- #else
- bool canAllocInPreReservedHeapPageSegment = m_func->CanAllocInPreReservedHeapPageSegment();
- #endif
- BYTE *buffer = nullptr;
- m_oopAlloc = m_func->GetOOPCodeGenAllocators()->emitBufferManager.AllocateBuffer(bytes, &buffer, pdataCount, xdataSize, canAllocInPreReservedHeapPageSegment, true);
- if (buffer == nullptr)
- {
- Js::Throw::OutOfMemory();
- }
- m_outputData->codeAddress = (intptr_t)buffer;
- m_outputData->codeSize = bytes;
- m_outputData->pdataCount = pdataCount;
- m_outputData->xdataSize = xdataSize;
- m_outputData->isInPrereservedRegion = m_oopAlloc->inPrereservedRegion;
- return m_oopAlloc;
- }
- #endif
- void
- JITOutput::RecordNativeCode(const BYTE* sourceBuffer, BYTE* localCodeAddress)
- {
- #if ENABLE_OOP_NATIVE_CODEGEN
- if (JITManager::GetJITManager()->IsJITServer())
- {
- RecordNativeCode(sourceBuffer, localCodeAddress, m_oopAlloc, m_func->GetOOPCodeGenAllocators());
- }
- else
- #endif
- {
- RecordNativeCode(sourceBuffer, localCodeAddress, m_inProcAlloc, m_func->GetInProcCodeGenAllocators());
- }
- }
- template <typename TEmitBufferAllocation, typename TCodeGenAllocators>
- void
- JITOutput::RecordNativeCode(const BYTE* sourceBuffer, BYTE* localCodeAddress, TEmitBufferAllocation allocation, TCodeGenAllocators codeGenAllocators)
- {
- Assert(m_outputData->codeAddress == (intptr_t)allocation->allocation->address);
- if (!codeGenAllocators->emitBufferManager.CommitBuffer(allocation, allocation->bytesCommitted, localCodeAddress, m_outputData->codeSize, sourceBuffer))
- {
- Js::Throw::OutOfMemory();
- }
- #if DBG_DUMP
- if (m_func->IsLoopBody())
- {
- codeGenAllocators->emitBufferManager.totalBytesLoopBody += m_outputData->codeSize;
- }
- #endif
- }
- void
- JITOutput::RecordInlineeFrameOffsetsInfo(unsigned int offsetsArrayOffset, unsigned int offsetsArrayCount)
- {
- m_outputData->inlineeFrameOffsetArrayOffset = offsetsArrayOffset;
- m_outputData->inlineeFrameOffsetArrayCount = offsetsArrayCount;
- }
- #if TARGET_64
- void
- JITOutput::RecordUnwindInfo(BYTE *unwindInfo, size_t size, BYTE * xdataAddr, BYTE* localXdataAddr)
- {
- Assert(XDATA_SIZE >= size);
- memcpy_s(localXdataAddr, XDATA_SIZE, unwindInfo, size);
- m_outputData->xdataAddr = (intptr_t)xdataAddr;
- }
- #elif _M_ARM
- size_t
- JITOutput::RecordUnwindInfo(size_t offset, const BYTE *unwindInfo, size_t size, BYTE * xdataAddr)
- {
- BYTE *xdataFinal = xdataAddr + offset;
- Assert(xdataFinal);
- Assert(((ULONG_PTR)xdataFinal & 0x3) == 0); // 4 byte aligned
- memcpy_s(xdataFinal, size, unwindInfo, size);
- return (size_t)xdataFinal;
- }
- void
- JITOutput::RecordXData(BYTE * xdata)
- {
- m_outputData->xdataOffset = NativeCodeData::GetDataTotalOffset(xdata);
- }
- #endif
- void
- JITOutput::FinalizeNativeCode()
- {
- CustomHeap::Allocation * allocation = GetAllocation();
- #if ENABLE_OOP_NATIVE_CODEGEN
- if (JITManager::GetJITManager()->IsJITServer())
- {
- m_func->GetOOPCodeGenAllocators()->emitBufferManager.CompletePreviousAllocation(m_oopAlloc);
- #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
- if (!m_func->IsLoopBody() && CONFIG_FLAG(UseJITTrampoline))
- {
- allocation->thunkAddress = m_func->GetOOPThreadContext()->GetJITThunkEmitter()->CreateThunk(m_outputData->codeAddress);
- }
- #endif
- }
- else
- #endif
- {
- m_func->GetInProcCodeGenAllocators()->emitBufferManager.CompletePreviousAllocation(m_inProcAlloc);
- m_func->GetInProcJITEntryPointInfo()->GetInProcNativeEntryPointData()->SetNativeCodeData(m_func->GetNativeCodeDataAllocator()->Finalize());
- m_func->GetInProcJITEntryPointInfo()->GetJitTransferData()->SetRawData(m_func->GetTransferDataAllocator()->Finalize());
- #if !FLOATVAR
- CodeGenNumberChunk * numberChunks = m_func->GetNumberAllocator()->Finalize();
- m_func->GetInProcJITEntryPointInfo()->GetInProcNativeEntryPointData()->SetNumberChunks(numberChunks);
- #endif
- #if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
- if (!m_func->IsLoopBody() && CONFIG_FLAG(UseJITTrampoline))
- {
- allocation->thunkAddress = m_func->GetInProcThreadContext()->GetJITThunkEmitter()->CreateThunk(m_outputData->codeAddress);
- }
- #endif
- }
- m_outputData->thunkAddress = allocation->thunkAddress;
- if (!allocation->thunkAddress && CONFIG_FLAG(OOPCFGRegistration))
- {
- PVOID callTarget = (PVOID)m_outputData->codeAddress;
- #if ENABLE_OOP_NATIVE_CODEGEN
- if (JITManager::GetJITManager()->IsJITServer())
- {
- m_func->GetOOPCodeGenAllocators()->emitBufferManager.SetValidCallTarget(m_oopAlloc, callTarget, true);
- }
- else
- #endif
- {
- m_func->GetInProcCodeGenAllocators()->emitBufferManager.SetValidCallTarget(m_inProcAlloc, callTarget, true);
- }
- }
- }
- CustomHeap::Allocation *
- JITOutput::GetAllocation() const
- {
- #if ENABLE_OOP_NATIVE_CODEGEN
- if (JITManager::GetJITManager()->IsJITServer())
- {
- return m_oopAlloc->allocation;
- }
- #endif
- return m_inProcAlloc->allocation;
- }
- JITOutputIDL *
- JITOutput::GetOutputData()
- {
- return m_outputData;
- }
|