blob: 1839a8c942629792444935af39e1c9618abc5eb2 [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"
ServerScriptContext::ThreadContextHolder::ThreadContextHolder(ServerThreadContext* threadContextInfo) : threadContextInfo(threadContextInfo)
{
threadContextInfo->AddRef();
}
ServerScriptContext::ThreadContextHolder::~ThreadContextHolder()
{
threadContextInfo->Release();
}
ServerScriptContext::ServerScriptContext(ScriptContextDataIDL * contextData, ServerThreadContext* threadContextInfo) :
m_contextData(*contextData),
threadContextHolder(threadContextInfo),
m_isPRNGSeeded(false),
m_sourceCodeArena(_u("JITSourceCodeArena"), threadContextInfo->GetForegroundPageAllocator(), Js::Throw::OutOfMemory, nullptr),
m_interpreterThunkBufferManager(&m_sourceCodeArena, threadContextInfo->GetThunkPageAllocators(), nullptr, _u("Interpreter thunk buffer"), GetThreadContext()->GetProcessHandle()),
m_asmJsInterpreterThunkBufferManager(&m_sourceCodeArena, threadContextInfo->GetThunkPageAllocators(), nullptr, _u("Asm.js interpreter thunk buffer"), GetThreadContext()->GetProcessHandle()),
m_domFastPathHelperMap(nullptr),
m_moduleRecords(&HeapAllocator::Instance),
m_globalThisAddr(0),
#ifdef PROFILE_EXEC
m_codeGenProfiler(nullptr),
#endif
m_refCount(0),
m_isClosed(false)
{
#ifdef PROFILE_EXEC
if (Js::Configuration::Global.flags.IsEnabled(Js::ProfileFlag))
{
m_codeGenProfiler = HeapNew(Js::ScriptContextProfiler);
}
#endif
m_domFastPathHelperMap = HeapNew(JITDOMFastPathHelperMap, &HeapAllocator::Instance, 17);
}
ServerScriptContext::~ServerScriptContext()
{
HeapDelete(m_domFastPathHelperMap);
m_moduleRecords.Map([](uint, Js::ServerSourceTextModuleRecord* record)
{
HeapDelete(record);
});
#ifdef PROFILE_EXEC
if (m_codeGenProfiler)
{
HeapDelete(m_codeGenProfiler);
}
#endif
}
intptr_t
ServerScriptContext::GetNullAddr() const
{
return m_contextData.nullAddr;
}
intptr_t
ServerScriptContext::GetUndefinedAddr() const
{
return m_contextData.undefinedAddr;
}
intptr_t
ServerScriptContext::GetTrueAddr() const
{
return m_contextData.trueAddr;
}
intptr_t
ServerScriptContext::GetFalseAddr() const
{
return m_contextData.falseAddr;
}
intptr_t
ServerScriptContext::GetUndeclBlockVarAddr() const
{
return m_contextData.undeclBlockVarAddr;
}
intptr_t
ServerScriptContext::GetEmptyStringAddr() const
{
return m_contextData.emptyStringAddr;
}
intptr_t
ServerScriptContext::GetNegativeZeroAddr() const
{
return m_contextData.negativeZeroAddr;
}
intptr_t
ServerScriptContext::GetNumberTypeStaticAddr() const
{
return m_contextData.numberTypeStaticAddr;
}
intptr_t
ServerScriptContext::GetStringTypeStaticAddr() const
{
return m_contextData.stringTypeStaticAddr;
}
intptr_t
ServerScriptContext::GetObjectTypeAddr() const
{
return m_contextData.objectTypeAddr;
}
intptr_t
ServerScriptContext::GetObjectHeaderInlinedTypeAddr() const
{
return m_contextData.objectHeaderInlinedTypeAddr;
}
intptr_t
ServerScriptContext::GetRegexTypeAddr() const
{
return m_contextData.regexTypeAddr;
}
intptr_t
ServerScriptContext::GetArrayTypeAddr() const
{
return m_contextData.arrayTypeAddr;
}
intptr_t
ServerScriptContext::GetNativeIntArrayTypeAddr() const
{
return m_contextData.nativeIntArrayTypeAddr;
}
intptr_t
ServerScriptContext::GetNativeFloatArrayTypeAddr() const
{
return m_contextData.nativeFloatArrayTypeAddr;
}
intptr_t
ServerScriptContext::GetArrayConstructorAddr() const
{
return m_contextData.arrayConstructorAddr;
}
intptr_t
ServerScriptContext::GetCharStringCacheAddr() const
{
return m_contextData.charStringCacheAddr;
}
intptr_t
ServerScriptContext::GetSideEffectsAddr() const
{
return m_contextData.sideEffectsAddr;
}
intptr_t
ServerScriptContext::GetArraySetElementFastPathVtableAddr() const
{
return m_contextData.arraySetElementFastPathVtableAddr;
}
intptr_t
ServerScriptContext::GetIntArraySetElementFastPathVtableAddr() const
{
return m_contextData.intArraySetElementFastPathVtableAddr;
}
intptr_t
ServerScriptContext::GetFloatArraySetElementFastPathVtableAddr() const
{
return m_contextData.floatArraySetElementFastPathVtableAddr;
}
intptr_t
ServerScriptContext::GetLibraryAddr() const
{
return m_contextData.libraryAddr;
}
intptr_t
ServerScriptContext::GetGlobalObjectAddr() const
{
return m_contextData.globalObjectAddr;
}
intptr_t
ServerScriptContext::GetGlobalObjectThisAddr() const
{
return m_globalThisAddr;
}
void
ServerScriptContext::UpdateGlobalObjectThisAddr(intptr_t globalThis)
{
m_globalThisAddr = globalThis;
}
intptr_t
ServerScriptContext::GetNumberAllocatorAddr() const
{
return m_contextData.numberAllocatorAddr;
}
intptr_t
ServerScriptContext::GetRecyclerAddr() const
{
return m_contextData.recyclerAddr;
}
bool
ServerScriptContext::GetRecyclerAllowNativeCodeBumpAllocation() const
{
return m_contextData.recyclerAllowNativeCodeBumpAllocation != 0;
}
bool
ServerScriptContext::IsSIMDEnabled() const
{
return m_contextData.isSIMDEnabled != 0;
}
intptr_t
ServerScriptContext::GetBuiltinFunctionsBaseAddr() const
{
return m_contextData.builtinFunctionsBaseAddr;
}
intptr_t
ServerScriptContext::GetAddr() const
{
return m_contextData.scriptContextAddr;
}
intptr_t
ServerScriptContext::GetVTableAddress(VTableValue vtableType) const
{
Assert(vtableType < VTableValue::Count);
return m_contextData.vtableAddresses[vtableType];
}
bool
ServerScriptContext::IsRecyclerVerifyEnabled() const
{
return m_contextData.isRecyclerVerifyEnabled != FALSE;
}
uint
ServerScriptContext::GetRecyclerVerifyPad() const
{
return m_contextData.recyclerVerifyPad;
}
bool
ServerScriptContext::IsPRNGSeeded() const
{
return m_isPRNGSeeded;
}
intptr_t
ServerScriptContext::GetDebuggingFlagsAddr() const
{
return static_cast<intptr_t>(m_contextData.debuggingFlagsAddr);
}
intptr_t
ServerScriptContext::GetDebugStepTypeAddr() const
{
return static_cast<intptr_t>(m_contextData.debugStepTypeAddr);
}
intptr_t
ServerScriptContext::GetDebugFrameAddressAddr() const
{
return static_cast<intptr_t>(m_contextData.debugFrameAddressAddr);
}
intptr_t
ServerScriptContext::GetDebugScriptIdWhenSetAddr() const
{
return static_cast<intptr_t>(m_contextData.debugScriptIdWhenSetAddr);
}
intptr_t
ServerScriptContext::GetChakraLibAddr() const
{
return m_contextData.chakraLibAddr;
}
bool
ServerScriptContext::IsClosed() const
{
return m_isClosed;
}
void
ServerScriptContext::AddToDOMFastPathHelperMap(intptr_t funcInfoAddr, IR::JnHelperMethod helper)
{
m_domFastPathHelperMap->Add(funcInfoAddr, helper);
}
ArenaAllocator *
ServerScriptContext::GetSourceCodeArena()
{
return &m_sourceCodeArena;
}
void
ServerScriptContext::DecommitEmitBufferManager(bool asmJsManager)
{
GetEmitBufferManager(asmJsManager)->Decommit();
}
OOPEmitBufferManager *
ServerScriptContext::GetEmitBufferManager(bool asmJsManager)
{
if (asmJsManager)
{
return &m_asmJsInterpreterThunkBufferManager;
}
else
{
return &m_interpreterThunkBufferManager;
}
}
IR::JnHelperMethod
ServerScriptContext::GetDOMFastPathHelper(intptr_t funcInfoAddr)
{
IR::JnHelperMethod helper;
m_domFastPathHelperMap->LockResize();
bool found = m_domFastPathHelperMap->TryGetValue(funcInfoAddr, &helper);
m_domFastPathHelperMap->UnlockResize();
Assert(found);
return helper;
}
void
ServerScriptContext::Close()
{
Assert(!IsClosed());
m_isClosed = true;
#ifdef STACK_BACK_TRACE
ServerContextManager::RecordCloseContext(this);
#endif
}
void
ServerScriptContext::AddRef()
{
InterlockedExchangeAdd(&m_refCount, 1u);
}
void
ServerScriptContext::Release()
{
InterlockedExchangeSubtract(&m_refCount, 1u);
if (m_isClosed && m_refCount == 0)
{
// Not freeing here, we'll expect explicit ServerCleanupScriptContext() call to do the free
// otherwise after free, the CodeGen call can still get same scriptContext if there's another
// ServerInitializeScriptContext call
}
}
Field(Js::Var)*
ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex)
{
Assert(m_moduleRecords.ContainsKey(moduleIndex));
auto record = m_moduleRecords.Item(moduleIndex);
return record->localExportSlotsAddr;
}
void
ServerScriptContext::SetIsPRNGSeeded(bool value)
{
m_isPRNGSeeded = value;
}
void
ServerScriptContext::AddModuleRecordInfo(unsigned int moduleId, __int64 localExportSlotsAddr)
{
Js::ServerSourceTextModuleRecord* record = HeapNewStructZ(Js::ServerSourceTextModuleRecord);
record->moduleId = moduleId;
record->localExportSlotsAddr = (Field(Js::Var)*)localExportSlotsAddr;
m_moduleRecords.Add(moduleId, record);
}
Js::ScriptContextProfiler *
ServerScriptContext::GetCodeGenProfiler() const
{
#ifdef PROFILE_EXEC
return m_codeGenProfiler;
#else
return nullptr;
#endif
}
#endif