blob: be1827b63a8453fe42fd4d9a1de4661f9a7511d1 [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, ProcessContext* processContext) :
m_threadContextData(*data),
m_refCount(0),
m_numericPropertyBV(nullptr),
m_preReservedSectionAllocator(processContext->processHandle),
m_sectionAllocator(processContext->processHandle),
m_codePageAllocators(nullptr, ALLOC_XDATA, &m_sectionAllocator, &m_preReservedSectionAllocator, processContext->processHandle),
m_thunkPageAllocators(nullptr, /* allocXData */ false, &m_sectionAllocator, nullptr, processContext->processHandle),
#if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
m_jitThunkEmitter(this, &m_sectionAllocator, processContext->processHandle),
#endif
m_pageAlloc(nullptr, Js::Configuration::Global.flags, PageAllocatorType_BGJIT,
AutoSystemInfo::Data.IsLowMemoryProcess() ?
PageAllocator::DefaultLowMaxFreePageCount :
PageAllocator::DefaultMaxFreePageCount
),
processContext(processContext),
m_canCreatePreReservedSegment(data->allowPrereserveAlloc != FALSE)
{
m_pid = GetProcessId(processContext->processHandle);
m_numericPropertyBV = HeapNew(BVSparse<HeapAllocator>, &HeapAllocator::Instance);
}
ServerThreadContext::~ServerThreadContext()
{
processContext->Release();
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);
}
#ifdef ENABLE_WASM_SIMD
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 this->processContext->processHandle;
}
CustomHeap::OOPCodePageAllocators *
ServerThreadContext::GetThunkPageAllocators()
{
return &m_thunkPageAllocators;
}
SectionAllocWrapper *
ServerThreadContext::GetSectionAllocator()
{
return &m_sectionAllocator;
}
CustomHeap::OOPCodePageAllocators *
ServerThreadContext::GetCodePageAllocators()
{
return &m_codePageAllocators;
}
#if defined(_CONTROL_FLOW_GUARD) && !defined(_M_ARM)
OOPJITThunkEmitter *
ServerThreadContext::GetJITThunkEmitter()
{
return &m_jitThunkEmitter;
}
#endif
intptr_t
ServerThreadContext::GetRuntimeChakraBaseAddress() const
{
return this->processContext->chakraBaseAddress;
}
intptr_t
ServerThreadContext::GetRuntimeCRTBaseAddress() const
{
return this->processContext->crtBaseAddress;
}
/* static */
intptr_t
ServerThreadContext::GetJITCRTBaseAddress()
{
return (intptr_t)AutoSystemInfo::Data.GetCRTHandle();
}
PageAllocator *
ServerThreadContext::GetForegroundPageAllocator()
{
return &m_pageAlloc;
}
bool
ServerThreadContext::CanCreatePreReservedSegment() const
{
return m_canCreatePreReservedSegment;
}
void
ServerThreadContext::SetCanCreatePreReservedSegment(bool value)
{
m_canCreatePreReservedSegment = value;
}
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
}
ProcessContext::ProcessContext(HANDLE processHandle, intptr_t chakraBaseAddress, intptr_t crtBaseAddress) :
processHandle(processHandle),
chakraBaseAddress(chakraBaseAddress),
crtBaseAddress(crtBaseAddress),
refCount(0)
{
}
ProcessContext::~ProcessContext()
{
CloseHandle(processHandle);
}
void ProcessContext::AddRef()
{
InterlockedExchangeAdd(&this->refCount, 1);
}
void ProcessContext::Release()
{
InterlockedExchangeSubtract(&this->refCount, 1);
}
bool ProcessContext::HasRef()
{
return this->refCount != 0;
}
#endif