| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "JITServerPch.h"
- __declspec(dllexport)
- HRESULT JsInitializeJITServer(
- __in UUID* connectionUuid,
- __in_opt void* securityDescriptor,
- __in_opt void* alpcSecurityDescriptor)
- {
- RPC_STATUS status;
- RPC_BINDING_VECTOR* bindingVector = NULL;
- UUID_VECTOR uuidVector;
- uuidVector.Count = 1;
- uuidVector.Uuid[0] = connectionUuid;
- status = RpcServerUseProtseqW(
- (RPC_WSTR)L"ncalrpc",
- RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
- alpcSecurityDescriptor);
- if (status != RPC_S_OK)
- {
- return status;
- }
- #ifndef NTBUILD
- status = RpcServerRegisterIf2(
- ServerIChakraJIT_v0_0_s_ifspec,
- NULL,
- NULL,
- RPC_IF_AUTOLISTEN,
- RPC_C_LISTEN_MAX_CALLS_DEFAULT,
- (ULONG)-1,
- NULL);
- #else
- status = RpcServerRegisterIf3(
- ServerIChakraJIT_v0_0_s_ifspec,
- NULL,
- NULL,
- RPC_IF_AUTOLISTEN,
- RPC_C_LISTEN_MAX_CALLS_DEFAULT,
- (ULONG)-1,
- NULL,
- securityDescriptor);
- #endif
- if (status != RPC_S_OK)
- {
- return status;
- }
- status = RpcServerInqBindings(&bindingVector);
- if (status != RPC_S_OK)
- {
- return status;
- }
- JITManager::GetJITManager()->SetIsJITServer();
- PageAllocatorPool::Initialize();
- status = RpcEpRegister(
- ServerIChakraJIT_v0_0_s_ifspec,
- bindingVector,
- &uuidVector,
- NULL);
- if (status != RPC_S_OK)
- {
- return status;
- }
- status = RpcBindingVectorFree(&bindingVector);
- if (status != RPC_S_OK)
- {
- return status;
- }
- status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
- return status;
- }
- HRESULT
- ShutdownCommon()
- {
- HRESULT status = RpcMgmtStopServerListening(NULL);
- if (status != RPC_S_OK)
- {
- return status;
- }
- status = RpcServerUnregisterIf(ServerIChakraJIT_v0_0_s_ifspec, NULL, FALSE);
- ServerContextManager::Shutdown();
- PageAllocatorPool::Shutdown();
- return status;
- }
- HRESULT
- ServerShutdown(
- /* [in] */ handle_t binding)
- {
- return ShutdownCommon();
- }
- void
- __RPC_USER PTHREADCONTEXT_HANDLE_rundown(__RPC__in PTHREADCONTEXT_HANDLE phContext)
- {
- ServerCleanupThreadContext(nullptr, &phContext);
- }
- void
- __RPC_USER PSCRIPTCONTEXT_HANDLE_rundown(__RPC__in PSCRIPTCONTEXT_HANDLE phContext)
- {
- ServerCloseScriptContext(nullptr, phContext);
- ServerCleanupScriptContext(nullptr, &phContext);
- }
- HRESULT CheckModuleAddress(HANDLE process, LPCVOID remoteImageBase, LPCVOID localImageBase)
- {
- byte remoteImageHeader[0x1000];
- MEMORY_BASIC_INFORMATION remoteImageInfo;
- SIZE_T resultBytes = VirtualQueryEx(process, (LPCVOID)remoteImageBase, &remoteImageInfo, sizeof(remoteImageInfo));
- if (resultBytes != sizeof(remoteImageInfo))
- {
- return E_ACCESSDENIED;
- }
- if (remoteImageInfo.BaseAddress != (PVOID)remoteImageBase)
- {
- return E_ACCESSDENIED;
- }
- if (remoteImageInfo.Type != MEM_IMAGE)
- {
- return E_ACCESSDENIED;
- }
- if (remoteImageInfo.State != MEM_COMMIT)
- {
- return E_ACCESSDENIED;
- }
- if (remoteImageInfo.RegionSize < sizeof(remoteImageHeader))
- {
- return E_ACCESSDENIED;
- }
- if (!ReadProcessMemory(process, remoteImageBase, remoteImageHeader, sizeof(remoteImageHeader), &resultBytes))
- {
- return HRESULT_FROM_WIN32(GetLastError());
- }
- if (resultBytes < sizeof(remoteImageHeader))
- {
- return E_ACCESSDENIED;
- }
- PIMAGE_DOS_HEADER localDosHeader = (PIMAGE_DOS_HEADER)localImageBase;
- PIMAGE_NT_HEADERS localNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)localDosHeader + localDosHeader->e_lfanew);
- PIMAGE_DOS_HEADER remoteDosHeader = (PIMAGE_DOS_HEADER)remoteImageHeader;
- PIMAGE_NT_HEADERS remoteNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)remoteDosHeader + remoteDosHeader->e_lfanew);
- uintptr_t remoteHeaderMax = (uintptr_t)remoteImageHeader + sizeof(remoteImageHeader);
- uintptr_t remoteMaxRead = (uintptr_t)remoteNtHeader + sizeof(IMAGE_NT_HEADERS);
- if (remoteMaxRead >= remoteHeaderMax || remoteMaxRead < (uintptr_t)remoteImageHeader)
- {
- return E_ACCESSDENIED;
- }
- if (localNtHeader->FileHeader.NumberOfSections != remoteNtHeader->FileHeader.NumberOfSections)
- {
- return E_ACCESSDENIED;
- }
- if (localNtHeader->FileHeader.NumberOfSymbols != remoteNtHeader->FileHeader.NumberOfSymbols)
- {
- return E_ACCESSDENIED;
- }
- if (localNtHeader->OptionalHeader.CheckSum != remoteNtHeader->OptionalHeader.CheckSum)
- {
- return E_ACCESSDENIED;
- }
- if (localNtHeader->OptionalHeader.SizeOfImage != remoteNtHeader->OptionalHeader.SizeOfImage)
- {
- return E_ACCESSDENIED;
- }
- return S_OK;
- }
- #pragma warning(push)
- #pragma warning(disable:6387 28196) // PREFast does not understand the out context can be null here
- HRESULT
- ServerInitializeThreadContext(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in ThreadContextDataIDL * threadContextData,
- /* [out] */ __RPC__deref_out_opt PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
- /* [out] */ __RPC__out intptr_t *prereservedRegionAddr)
- {
- if (threadContextInfoAddress == nullptr || prereservedRegionAddr == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- *threadContextInfoAddress = nullptr;
- *prereservedRegionAddr = 0;
- ServerThreadContext * contextInfo = nullptr;
- try
- {
- AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory));
- contextInfo = HeapNew(ServerThreadContext, threadContextData);
- ServerContextManager::RegisterThreadContext(contextInfo);
- }
- catch (Js::OutOfMemoryException)
- {
- CloseHandle((HANDLE)threadContextData->processHandle);
- return E_OUTOFMEMORY;
- }
- return ServerCallWrapper(contextInfo, [&]()->HRESULT
- {
- RPC_CALL_ATTRIBUTES CallAttributes = {0};
- CallAttributes.Version = RPC_CALL_ATTRIBUTES_VERSION;
- CallAttributes.Flags = RPC_QUERY_CLIENT_PID;
- HRESULT hr = HRESULT_FROM_WIN32(RpcServerInqCallAttributes(binding, &CallAttributes));
- if (FAILED(hr))
- {
- return hr;
- }
- if (CallAttributes.ClientPID != (HANDLE)contextInfo->GetRuntimePid())
- {
- return E_ACCESSDENIED;
- }
- hr = CheckModuleAddress(contextInfo->GetProcessHandle(), (LPCVOID)contextInfo->GetRuntimeChakraBaseAddress(), (LPCVOID)AutoSystemInfo::Data.dllLoadAddress);
- if (FAILED(hr))
- {
- return hr;
- }
- if (contextInfo->GetUCrtC99MathApis()->IsAvailable())
- {
- hr = CheckModuleAddress(contextInfo->GetProcessHandle(), (LPCVOID)contextInfo->GetRuntimeCRTBaseAddress(), (LPCVOID)contextInfo->GetJITCRTBaseAddress());
- if (FAILED(hr))
- {
- return hr;
- }
- }
- *threadContextInfoAddress = (PTHREADCONTEXT_HANDLE)EncodePointer(contextInfo);
- *prereservedRegionAddr = (intptr_t)contextInfo->GetPreReservedSectionAllocator()->EnsurePreReservedRegion();
- return hr;
- });
- }
- HRESULT
- ServerInitializeScriptContext(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in ScriptContextDataIDL * scriptContextData,
- /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- /* [out] */ __RPC__deref_out_opt PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- if (scriptContextInfoAddress == nullptr || threadContextInfoAddress == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- *scriptContextInfoAddress = nullptr;
- ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer(threadContextInfoAddress);
- return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
- {
- ServerScriptContext * contextInfo = HeapNew(ServerScriptContext, scriptContextData, threadContextInfo);
- ServerContextManager::RegisterScriptContext(contextInfo);
- *scriptContextInfoAddress = (PSCRIPTCONTEXT_HANDLE)EncodePointer(contextInfo);
- #if !FLOATVAR
- // TODO: should move this to ServerInitializeThreadContext, also for the fields in IDL
- XProcNumberPageSegmentImpl::Initialize(contextInfo->IsRecyclerVerifyEnabled(), contextInfo->GetRecyclerVerifyPad());
- #endif
- return S_OK;
- });
- }
- #pragma warning(pop)
- HRESULT
- ServerCleanupThreadContext(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__deref_inout_opt PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
- {
- if (threadContextInfoAddress == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer(*threadContextInfoAddress);
- if (threadContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- // This tells the run-time, when it is marshalling the out
- // parameters, that the context handle has been closed normally.
- *threadContextInfoAddress = nullptr;
- return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
- {
- threadContextInfo->Close();
- ServerContextManager::UnRegisterThreadContext(threadContextInfo);
- return S_OK;
- });
- }
- HRESULT
- ServerUpdatePropertyRecordMap(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- /* [in] */ __RPC__in_opt BVSparseNodeIDL * updatedPropsBVHead)
- {
- ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer(threadContextInfoAddress);
- if (threadContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
- {
- typedef ServerThreadContext::BVSparseNode BVSparseNode;
- CompileAssert(sizeof(BVSparseNode) == sizeof(BVSparseNodeIDL));
- threadContextInfo->UpdateNumericPropertyBV((BVSparseNode*)updatedPropsBVHead);
- return S_OK;
- });
- }
- HRESULT
- ServerAddDOMFastPathHelper(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ intptr_t funcInfoAddr,
- /* [in] */ int helper)
- {
- ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer(scriptContextInfoAddress);
- if (scriptContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContextInfo, [&]()->HRESULT
- {
- scriptContextInfo->AddToDOMFastPathHelperMap(funcInfoAddr, (IR::JnHelperMethod)helper);
- return S_OK;
- });
- }
- HRESULT
- ServerAddModuleRecordInfo(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ unsigned int moduleId,
- /* [in] */ intptr_t localExportSlotsAddr)
- {
- ServerScriptContext * serverScriptContext = (ServerScriptContext*)DecodePointer(scriptContextInfoAddress);
- if (serverScriptContext == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(serverScriptContext, [&]()->HRESULT
- {
- serverScriptContext->AddModuleRecordInfo(moduleId, localExportSlotsAddr);
- return S_OK;
- });
- }
- HRESULT
- ServerSetWellKnownHostTypeId(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- /* [in] */ int typeId)
- {
- ServerThreadContext * threadContextInfo = (ServerThreadContext*)DecodePointer(threadContextInfoAddress);
- if (threadContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(threadContextInfo, [&]()->HRESULT
- {
- threadContextInfo->SetWellKnownHostTypeId((Js::TypeId)typeId);
- return S_OK;
- });
- }
- HRESULT
- ServerCleanupScriptContext(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__deref_inout_opt PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- if (scriptContextInfoAddress == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer(*scriptContextInfoAddress);
- if (scriptContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- // This tells the run-time, when it is marshalling the out
- // parameters, that the context handle has been closed normally.
- *scriptContextInfoAddress = nullptr;
- Assert(scriptContextInfo->IsClosed());
- HeapDelete(scriptContextInfo);
- return S_OK;
- }
- HRESULT
- ServerCloseScriptContext(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer(scriptContextInfoAddress);
- if (scriptContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContextInfo, [&]()->HRESULT
- {
- #ifdef PROFILE_EXEC
- auto profiler = scriptContextInfo->GetCodeGenProfiler();
- if (profiler && profiler->IsInitialized())
- {
- profiler->ProfilePrint(Js::Configuration::Global.flags.Profile.GetFirstPhase());
- }
- #endif
- scriptContextInfo->Close();
- ServerContextManager::UnRegisterScriptContext(scriptContextInfo);
- return S_OK;
- });
- }
- HRESULT
- ServerDecommitInterpreterBufferManager(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ boolean asmJsManager)
- {
- ServerScriptContext * scriptContext = (ServerScriptContext *)DecodePointer((void*)scriptContextInfoAddress);
- if (scriptContext == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContext, [&]()->HRESULT
- {
- scriptContext->DecommitEmitBufferManager(asmJsManager != FALSE);
- return S_OK;
- });
- }
- HRESULT
- ServerNewInterpreterThunkBlock(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfo,
- /* [in] */ __RPC__in InterpreterThunkInputIDL * thunkInput,
- /* [out] */ __RPC__out InterpreterThunkOutputIDL * thunkOutput)
- {
- memset(thunkOutput, 0, sizeof(InterpreterThunkOutputIDL));
- ServerScriptContext * scriptContext = (ServerScriptContext *)DecodePointer(scriptContextInfo);
- if (scriptContext == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContext, [&]()->HRESULT
- {
- ServerThreadContext * threadContext = scriptContext->GetThreadContext();
- class AutoLocalAlloc
- {
- public:
- AutoLocalAlloc(ServerThreadContext * threadContext) : localAddress(nullptr), threadContext(threadContext) { }
- ~AutoLocalAlloc()
- {
- if (localAddress)
- {
- threadContext->GetCodePageAllocators()->FreeLocal(this->localAddress, this->segment);
- }
- }
- char * localAddress;
- void * segment;
- ServerThreadContext * threadContext;
- } localAlloc(threadContext);
- OOPEmitBufferManager * emitBufferManager = scriptContext->GetEmitBufferManager(thunkInput->asmJsThunk != FALSE);
- BYTE* runtimeAddress;
- EmitBufferAllocation<SectionAllocWrapper, PreReservedSectionAllocWrapper> * alloc = emitBufferManager->AllocateBuffer(InterpreterThunkEmitter::BlockSize, &runtimeAddress);
- CompileAssert(InterpreterThunkEmitter::BlockSize <= CustomHeap::Page::MaxAllocationSize);
- localAlloc.segment = alloc->allocation->page->segment;
- localAlloc.localAddress = threadContext->GetCodePageAllocators()->AllocLocal((char*)runtimeAddress, InterpreterThunkEmitter::BlockSize, localAlloc.segment);
- if (!localAlloc.localAddress)
- {
- Js::Throw::OutOfMemory();
- }
- #if PDATA_ENABLED
- PRUNTIME_FUNCTION pdataStart = {0};
- intptr_t epilogEnd = 0;
- #endif
- DWORD thunkCount = 0;
- InterpreterThunkEmitter::FillBuffer(
- threadContext,
- thunkInput->asmJsThunk != FALSE,
- (intptr_t)runtimeAddress,
- InterpreterThunkEmitter::BlockSize,
- (BYTE*)localAlloc.localAddress,
- #if PDATA_ENABLED
- &pdataStart,
- &epilogEnd,
- #endif
- &thunkCount
- );
- emitBufferManager->CommitBufferForInterpreter(alloc, runtimeAddress, InterpreterThunkEmitter::BlockSize);
- // Call to set VALID flag for CFG check
- if (CONFIG_FLAG(OOPCFGRegistration))
- {
- threadContext->SetValidCallTargetForCFG(runtimeAddress);
- }
- thunkOutput->thunkCount = thunkCount;
- thunkOutput->mappedBaseAddr = (intptr_t)runtimeAddress;
- #if PDATA_ENABLED
- thunkOutput->pdataTableStart = (intptr_t)pdataStart;
- thunkOutput->epilogEndAddr = epilogEnd;
- #endif
- return S_OK;
- });
- }
- #if DBG
- HRESULT
- ServerIsInterpreterThunkAddr(
- /* [in] */ handle_t binding,
- /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ intptr_t address,
- /* [in] */ boolean asmjsThunk,
- /* [out] */ __RPC__out boolean * result)
- {
- ServerScriptContext * context = (ServerScriptContext*)DecodePointer((void*)scriptContextInfoAddress);
- if (context == nullptr)
- {
- *result = false;
- return RPC_S_INVALID_ARG;
- }
- OOPEmitBufferManager * manager = context->GetEmitBufferManager(asmjsThunk != FALSE);
- if (manager == nullptr)
- {
- *result = false;
- return S_OK;
- }
- *result = manager->IsInHeap((void*)address);
- return S_OK;
- }
- #endif
- HRESULT
- ServerFreeAllocation(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfo,
- /* [in] */ intptr_t address)
- {
- ServerThreadContext * context = (ServerThreadContext*)DecodePointer(threadContextInfo);
- if (context == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(context, [&]()->HRESULT
- {
- if (CONFIG_FLAG(OOPCFGRegistration))
- {
- context->SetValidCallTargetForCFG((PVOID)address, false);
- }
- context->GetCodeGenAllocators()->emitBufferManager.FreeAllocation((void*)address);
- return S_OK;
- });
- }
- HRESULT
- ServerIsNativeAddr(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PTHREADCONTEXT_HANDLE threadContextInfo,
- /* [in] */ intptr_t address,
- /* [out] */ __RPC__out boolean * result)
- {
- if (result == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- *result = false;
- ServerThreadContext * context = (ServerThreadContext*)DecodePointer(threadContextInfo);
- if (context == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(context, [&]()->HRESULT
- {
- PreReservedSectionAllocWrapper *preReservedAllocWrapper = context->GetPreReservedSectionAllocator();
- if (preReservedAllocWrapper->IsInRange((void*)address))
- {
- *result = true;
- }
- else if (!context->IsAllJITCodeInPreReservedRegion())
- {
- AutoCriticalSection autoLock(&context->GetCodePageAllocators()->cs);
- *result = context->GetCodePageAllocators()->IsInNonPreReservedPageAllocator((void*)address);
- }
- else
- {
- *result = false;
- }
- return S_OK;
- });
- }
- HRESULT
- ServerSetIsPRNGSeeded(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ boolean value)
- {
- ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer(scriptContextInfoAddress);
- if (scriptContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContextInfo, [&]()->HRESULT
- {
- scriptContextInfo->SetIsPRNGSeeded(value != FALSE);
- return S_OK;
- });
- }
- HRESULT
- ServerRemoteCodeGen(
- /* [in] */ handle_t binding,
- /* [in] */ __RPC__in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ __RPC__in CodeGenWorkItemIDL *workItemData,
- /* [out] */ __RPC__out JITOutputIDL *jitData)
- {
- memset(jitData, 0, sizeof(JITOutputIDL));
- ServerScriptContext * scriptContextInfo = (ServerScriptContext*)DecodePointer(scriptContextInfoAddress);
- if (scriptContextInfo == nullptr)
- {
- Assert(false);
- return RPC_S_INVALID_ARG;
- }
- return ServerCallWrapper(scriptContextInfo, [&]() ->HRESULT
- {
- LARGE_INTEGER start_time = { 0 };
- if (PHASE_TRACE1(Js::BackEndPhase))
- {
- QueryPerformanceCounter(&start_time);
- }
- scriptContextInfo->UpdateGlobalObjectThisAddr(workItemData->globalThisAddr);
- ServerThreadContext * threadContextInfo = scriptContextInfo->GetThreadContext();
- AutoReturnPageAllocator autoReturnPageAllocator;
- PageAllocator* pageAllocator = autoReturnPageAllocator.GetPageAllocator();
- NoRecoverMemoryJitArenaAllocator jitArena(L"JITArena", pageAllocator, Js::Throw::OutOfMemory);
- #if DBG
- jitArena.SetNeedsDelayFreeList();
- #endif
- JITTimeWorkItem * jitWorkItem = Anew(&jitArena, JITTimeWorkItem, workItemData);
- if (PHASE_VERBOSE_TRACE_RAW(Js::BackEndPhase, jitWorkItem->GetJITTimeInfo()->GetSourceContextId(), jitWorkItem->GetJITTimeInfo()->GetLocalFunctionId()))
- {
- LARGE_INTEGER freq;
- LARGE_INTEGER end_time;
- QueryPerformanceCounter(&end_time);
- QueryPerformanceFrequency(&freq);
- Output::Print(
- L"BackendMarshalIn - function: %s time:%8.6f mSec\r\n",
- jitWorkItem->GetJITFunctionBody()->GetDisplayName(),
- (((double)((end_time.QuadPart - workItemData->startTime)* (double)1000.0 / (double)freq.QuadPart))) / (1));
- Output::Flush();
- }
- auto profiler = scriptContextInfo->GetCodeGenProfiler();
- #ifdef PROFILE_EXEC
- if (profiler && !profiler->IsInitialized())
- {
- profiler->Initialize(pageAllocator, nullptr);
- }
- #endif
- if (jitWorkItem->GetWorkItemData()->xProcNumberPageSegment)
- {
- jitData->numberPageSegments = (XProcNumberPageSegment*)midl_user_allocate(sizeof(XProcNumberPageSegment));
- if (!jitData->numberPageSegments)
- {
- return E_OUTOFMEMORY;
- }
- __analysis_assume(jitData->numberPageSegments);
- memcpy_s(jitData->numberPageSegments, sizeof(XProcNumberPageSegment), jitWorkItem->GetWorkItemData()->xProcNumberPageSegment, sizeof(XProcNumberPageSegment));
- }
- Func::Codegen(
- &jitArena,
- jitWorkItem,
- threadContextInfo,
- scriptContextInfo,
- jitData,
- nullptr,
- nullptr,
- jitWorkItem->GetPolymorphicInlineCacheInfo(),
- threadContextInfo->GetCodeGenAllocators(),
- #if !FLOATVAR
- nullptr, // number allocator
- #endif
- profiler,
- true);
- #ifdef PROFILE_EXEC
- if (profiler && profiler->IsInitialized())
- {
- profiler->ProfilePrint(Js::Configuration::Global.flags.Profile.GetFirstPhase());
- }
- #endif
- if (PHASE_VERBOSE_TRACE_RAW(Js::BackEndPhase, jitWorkItem->GetJITTimeInfo()->GetSourceContextId(), jitWorkItem->GetJITTimeInfo()->GetLocalFunctionId()))
- {
- LARGE_INTEGER freq;
- LARGE_INTEGER end_time;
- QueryPerformanceCounter(&end_time);
- QueryPerformanceFrequency(&freq);
- Output::Print(
- L"EndBackEndInner - function: %s time:%8.6f mSec\r\n",
- jitWorkItem->GetJITFunctionBody()->GetDisplayName(),
- (((double)((end_time.QuadPart - start_time.QuadPart)* (double)1000.0 / (double)freq.QuadPart))) / (1));
- Output::Flush();
- }
- LARGE_INTEGER out_time = { 0 };
- if (PHASE_TRACE1(Js::BackEndPhase))
- {
- QueryPerformanceCounter(&out_time);
- jitData->startTime = out_time.QuadPart;
- }
- return S_OK;
- });
- }
- JsUtil::BaseHashSet<ServerThreadContext*, HeapAllocator> ServerContextManager::threadContexts(&HeapAllocator::Instance);
- JsUtil::BaseHashSet<ServerScriptContext*, HeapAllocator> ServerContextManager::scriptContexts(&HeapAllocator::Instance);
- CriticalSection ServerContextManager::cs;
- #ifdef STACK_BACK_TRACE
- SList<ServerContextManager::ClosedContextEntry<ServerThreadContext>*, NoThrowHeapAllocator> ServerContextManager::ClosedThreadContextList(&NoThrowHeapAllocator::Instance);
- SList<ServerContextManager::ClosedContextEntry<ServerScriptContext>*, NoThrowHeapAllocator> ServerContextManager::ClosedScriptContextList(&NoThrowHeapAllocator::Instance);
- #endif
- void ServerContextManager::RegisterThreadContext(ServerThreadContext* threadContext)
- {
- AutoCriticalSection autoCS(&cs);
- threadContexts.Add(threadContext);
- }
- void ServerContextManager::UnRegisterThreadContext(ServerThreadContext* threadContext)
- {
- AutoCriticalSection autoCS(&cs);
- threadContexts.Remove(threadContext);
- auto iter = scriptContexts.GetIteratorWithRemovalSupport();
- while (iter.IsValid())
- {
- ServerScriptContext* scriptContext = iter.Current().Key();
- if (scriptContext->GetThreadContext() == threadContext)
- {
- if (!scriptContext->IsClosed())
- {
- scriptContext->Close();
- }
- iter.RemoveCurrent();
- }
- iter.MoveNext();
- }
- }
- void ServerContextManager::RegisterScriptContext(ServerScriptContext* scriptContext)
- {
- AutoCriticalSection autoCS(&cs);
- scriptContexts.Add(scriptContext);
- }
- void ServerContextManager::UnRegisterScriptContext(ServerScriptContext* scriptContext)
- {
- AutoCriticalSection autoCS(&cs);
- scriptContexts.Remove(scriptContext);
- }
- bool ServerContextManager::CheckLivenessAndAddref(ServerScriptContext* context)
- {
- AutoCriticalSection autoCS(&cs);
- if (scriptContexts.LookupWithKey(context))
- {
- if (!context->IsClosed() && !context->GetThreadContext()->IsClosed())
- {
- context->AddRef();
- context->GetThreadContext()->AddRef();
- return true;
- }
- }
- return false;
- }
- bool ServerContextManager::CheckLivenessAndAddref(ServerThreadContext* context)
- {
- AutoCriticalSection autoCS(&cs);
- if (threadContexts.LookupWithKey(context))
- {
- if (!context->IsClosed())
- {
- context->AddRef();
- return true;
- }
- }
- return false;
- }
- template<typename Fn>
- HRESULT ServerCallWrapper(ServerThreadContext* threadContextInfo, Fn fn)
- {
- MemoryOperationLastError::ClearLastError();
- HRESULT hr = S_OK;
- try
- {
- AUTO_NESTED_HANDLED_EXCEPTION_TYPE(static_cast<ExceptionType>(ExceptionType_OutOfMemory | ExceptionType_StackOverflow));
- AutoReleaseThreadContext autoThreadContext(threadContextInfo);
- hr = fn();
- }
- catch (ContextClosedException&)
- {
- hr = E_ACCESSDENIED;
- }
- catch (Js::OutOfMemoryException)
- {
- hr = E_OUTOFMEMORY;
- }
- catch (Js::StackOverflowException)
- {
- hr = VBSERR_OutOfStack;
- }
- catch (Js::OperationAbortedException)
- {
- hr = E_ABORT;
- }
- catch (...)
- {
- AssertOrFailFastMsg(false, "Unknown exception caught in JIT server call.");
- }
- return MemoryOperationLastError::GetLastError();
- }
- template<typename Fn>
- HRESULT ServerCallWrapper(ServerScriptContext* scriptContextInfo, Fn fn)
- {
- try
- {
- AutoReleaseScriptContext autoScriptContext(scriptContextInfo);
- ServerThreadContext* threadContextInfo = scriptContextInfo->GetThreadContext();
- return ServerCallWrapper(threadContextInfo, fn);
- }
- catch (ContextClosedException&)
- {
- return E_ACCESSDENIED;
- }
- }
|