blob: 6558e92de7a013080dfa1b1302eed38660bcf8df [file]
//-------------------------------------------------------------------------------------------------------
// 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"
#if ENABLE_OOP_NATIVE_CODEGEN
#include "JITServer/JITServer.h"
ServerThreadContext::ServerThreadContext(ThreadContextDataIDL * data) :
m_autoProcessHandle((HANDLE)data->processHandle),
m_threadContextData(*data),
m_refCount(0),
m_numericPropertyBV(nullptr),
m_preReservedSectionAllocator((HANDLE)data->processHandle),
m_sectionAllocator((HANDLE)data->processHandle),
m_thunkPageAllocators(nullptr, /* allocXData */ false, &m_sectionAllocator, nullptr, (HANDLE)data->processHandle),
m_codePageAllocators(nullptr, ALLOC_XDATA, &m_sectionAllocator, &m_preReservedSectionAllocator, (HANDLE)data->processHandle),
m_codeGenAlloc(nullptr, nullptr, &m_codePageAllocators, (HANDLE)data->processHandle),
#if defined(_CONTROL_FLOW_GUARD) && (_M_IX86 || _M_X64)
m_jitThunkEmitter(this, &m_sectionAllocator, (HANDLE)data->processHandle),
#endif
m_pageAlloc(nullptr, Js::Configuration::Global.flags, PageAllocatorType_BGJIT,
AutoSystemInfo::Data.IsLowMemoryProcess() ?
PageAllocator::DefaultLowMaxFreePageCount :
PageAllocator::DefaultMaxFreePageCount
)
{
ucrtC99MathApis.Ensure();
m_pid = GetProcessId((HANDLE)data->processHandle);
#if !_M_X64_OR_ARM64 && _CONTROL_FLOW_GUARD
m_codeGenAlloc.canCreatePreReservedSegment = data->allowPrereserveAlloc != FALSE;
#endif
m_numericPropertyBV = HeapNew(BVSparse<HeapAllocator>, &HeapAllocator::Instance);
}
ServerThreadContext::~ServerThreadContext()
{
if (this->m_numericPropertyBV != nullptr)
{
HeapDelete(m_numericPropertyBV);
this->m_numericPropertyBV = nullptr;
}
}
PreReservedSectionAllocWrapper *
ServerThreadContext::GetPreReservedSectionAllocator()
{
return &m_preReservedSectionAllocator;
}
intptr_t
ServerThreadContext::GetBailOutRegisterSaveSpaceAddr() const
{
return static_cast<intptr_t>(m_threadContextData.bailOutRegisterSaveSpaceAddr);
}
ptrdiff_t
ServerThreadContext::GetChakraBaseAddressDifference() const
{
return GetRuntimeChakraBaseAddress() - (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr();
}
ptrdiff_t
ServerThreadContext::GetCRTBaseAddressDifference() const
{
return GetRuntimeCRTBaseAddress() - GetJITCRTBaseAddress();
}
intptr_t
ServerThreadContext::GetDisableImplicitFlagsAddr() const
{
return static_cast<intptr_t>(m_threadContextData.disableImplicitFlagsAddr);
}
intptr_t
ServerThreadContext::GetImplicitCallFlagsAddr() const
{
return static_cast<intptr_t>(m_threadContextData.implicitCallFlagsAddr);
}
#if defined(ENABLE_SIMDJS) && (defined(_M_IX86) || defined(_M_X64))
intptr_t
ServerThreadContext::GetSimdTempAreaAddr(uint8 tempIndex) const
{
Assert(tempIndex < SIMD_TEMP_SIZE);
return m_threadContextData.simdTempAreaBaseAddr + tempIndex * sizeof(_x86_SIMDValue);
}
#endif
intptr_t
ServerThreadContext::GetThreadStackLimitAddr() const
{
return static_cast<intptr_t>(m_threadContextData.threadStackLimitAddr);
}
size_t
ServerThreadContext::GetScriptStackLimit() const
{
return static_cast<size_t>(m_threadContextData.scriptStackLimit);
}
bool
ServerThreadContext::IsThreadBound() const
{
return m_threadContextData.isThreadBound != FALSE;
}
HANDLE
ServerThreadContext::GetProcessHandle() const
{
return reinterpret_cast<HANDLE>(m_threadContextData.processHandle);
}
CustomHeap::OOPCodePageAllocators *
ServerThreadContext::GetThunkPageAllocators()
{
return &m_thunkPageAllocators;
}
CustomHeap::OOPCodePageAllocators *
ServerThreadContext::GetCodePageAllocators()
{
return &m_codePageAllocators;
}
SectionAllocWrapper *
ServerThreadContext::GetSectionAllocator()
{
return &m_sectionAllocator;
}
OOPCodeGenAllocators *
ServerThreadContext::GetCodeGenAllocators()
{
return &m_codeGenAlloc;
}
#if defined(_CONTROL_FLOW_GUARD) && (_M_IX86 || _M_X64)
OOPJITThunkEmitter *
ServerThreadContext::GetJITThunkEmitter()
{
return &m_jitThunkEmitter;
}
#endif
intptr_t
ServerThreadContext::GetRuntimeChakraBaseAddress() const
{
return static_cast<intptr_t>(m_threadContextData.chakraBaseAddress);
}
intptr_t
ServerThreadContext::GetRuntimeCRTBaseAddress() const
{
return static_cast<intptr_t>(m_threadContextData.crtBaseAddress);
}
intptr_t
ServerThreadContext::GetJITCRTBaseAddress() const
{
return (intptr_t)ucrtC99MathApis.GetHandle();
}
PageAllocator *
ServerThreadContext::GetForegroundPageAllocator()
{
return &m_pageAlloc;
}
bool
ServerThreadContext::IsNumericProperty(Js::PropertyId propertyId)
{
if (propertyId >= 0 && Js::IsInternalPropertyId(propertyId))
{
return Js::InternalPropertyRecords::GetInternalPropertyName(propertyId)->IsNumeric();
}
bool found = false;
{
AutoCriticalSection lock(&m_cs);
found = m_numericPropertyBV->Test(propertyId) != FALSE;
}
return found;
}
void
ServerThreadContext::UpdateNumericPropertyBV(BVSparseNode * newProps)
{
AutoCriticalSection lock(&m_cs);
m_numericPropertyBV->CopyFromNode(newProps);
}
void ServerThreadContext::AddRef()
{
InterlockedExchangeAdd(&m_refCount, (uint)1);
}
void ServerThreadContext::Release()
{
InterlockedExchangeSubtract(&m_refCount, (uint)1);
if (m_isClosed && m_refCount == 0)
{
HeapDelete(this);
}
}
void ServerThreadContext::Close()
{
this->m_isClosed = true;
#ifdef STACK_BACK_TRACE
ServerContextManager::RecordCloseContext(this);
#endif
}
#endif