| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "JITClientPch.h"
- _Must_inspect_result_
- _Ret_maybenull_ _Post_writable_byte_size_(size)
- void * __RPC_USER midl_user_allocate(
- #if defined(NTBUILD) || defined(_M_ARM)
- _In_ // starting win8, _In_ is in the signature
- #endif
- size_t size)
- {
- return (HeapAlloc(GetProcessHeap(), 0, size));
- }
- void __RPC_USER midl_user_free(_Pre_maybenull_ _Post_invalid_ void * ptr)
- {
- if (ptr != NULL)
- {
- HeapFree(GetProcessHeap(), NULL, ptr);
- }
- }
- JITManager JITManager::s_jitManager = JITManager();
- JITManager::JITManager() :
- m_rpcBindingHandle(nullptr),
- m_oopJitEnabled(false),
- m_isJITServer(false),
- m_serverHandle(nullptr),
- m_jitConnectionId()
- {
- }
- JITManager::~JITManager()
- {
- if (m_rpcBindingHandle)
- {
- RpcBindingFree(&m_rpcBindingHandle);
- }
- if (m_serverHandle)
- {
- CloseHandle(m_serverHandle);
- }
- }
- /* static */
- JITManager *
- JITManager::GetJITManager()
- {
- return &s_jitManager;
- }
- // This routine creates a binding with the server.
- HRESULT
- JITManager::CreateBinding(
- __in HANDLE serverProcessHandle,
- __in_opt void * serverSecurityDescriptor,
- __in UUID * connectionUuid,
- __out RPC_BINDING_HANDLE * bindingHandle)
- {
- Assert(IsOOPJITEnabled());
- RPC_STATUS status;
- DWORD attemptCount = 0;
- DWORD sleepInterval = 100; // in milliseconds
- RPC_BINDING_HANDLE localBindingHandle;
- RPC_BINDING_HANDLE_TEMPLATE_V1 bindingTemplate;
- RPC_BINDING_HANDLE_SECURITY_V1_W bindingSecurity;
- #ifndef NTBUILD
- RPC_SECURITY_QOS_V4 securityQOS;
- ZeroMemory(&securityQOS, sizeof(RPC_SECURITY_QOS_V4));
- securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
- securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
- securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
- securityQOS.Version = 4;
- #else
- RPC_SECURITY_QOS_V5 securityQOS;
- ZeroMemory(&securityQOS, sizeof(RPC_SECURITY_QOS_V5));
- securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
- securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
- securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
- securityQOS.Version = 5;
- securityQOS.ServerSecurityDescriptor = serverSecurityDescriptor;
- #endif // NTBUILD
- ZeroMemory(&bindingTemplate, sizeof(bindingTemplate));
- bindingTemplate.Version = 1;
- bindingTemplate.ProtocolSequence = RPC_PROTSEQ_LRPC;
- bindingTemplate.StringEndpoint = NULL;
- memcpy_s(&bindingTemplate.ObjectUuid, sizeof(UUID), connectionUuid, sizeof(UUID));
- bindingTemplate.Flags |= RPC_BHT_OBJECT_UUID_VALID;
- ZeroMemory(&bindingSecurity, sizeof(bindingSecurity));
- bindingSecurity.Version = 1;
- bindingSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
- bindingSecurity.AuthnSvc = RPC_C_AUTHN_KERNEL;
- bindingSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQOS;
- status = RpcBindingCreate(&bindingTemplate, &bindingSecurity, NULL, &localBindingHandle);
- if (status != RPC_S_OK)
- {
- return HRESULT_FROM_WIN32(status);
- }
- // We keep attempting to connect to the server with increasing wait intervals in between.
- // This will wait close to 5 minutes before it finally gives up.
- do
- {
- DWORD waitStatus;
- status = RpcBindingBind(NULL, localBindingHandle, ClientIChakraJIT_v0_0_c_ifspec);
- if (status == RPC_S_OK)
- {
- break;
- }
- else if (status == EPT_S_NOT_REGISTERED)
- {
- // The Server side has not finished registering the RPC Server yet.
- // We should only breakout if we have reached the max attempt count.
- if (attemptCount > 600)
- {
- break;
- }
- }
- else
- {
- // Some unknown error occurred. We are not going to retry for arbitrary errors.
- break;
- }
- // When we come to this point, it means the server has not finished registration yet.
- // We should wait for a while and then reattempt to bind.
- waitStatus = WaitForSingleObject(serverProcessHandle, sleepInterval);
- if (waitStatus == WAIT_OBJECT_0)
- {
- DWORD exitCode = (DWORD)-1;
- // The server process died for some reason. No need to reattempt.
- // We use -1 as the exit code if GetExitCodeProcess fails.
- Assert(GetExitCodeProcess(serverProcessHandle, &exitCode));
- status = RPC_S_SERVER_UNAVAILABLE;
- break;
- }
- else if (waitStatus == WAIT_TIMEOUT)
- {
- // Not an error. the server is still alive and we should reattempt.
- }
- else
- {
- // wait operation failed for an unknown reason.
- Assert(false);
- status = HRESULT_FROM_WIN32(waitStatus);
- break;
- }
- attemptCount++;
- if (sleepInterval < 500)
- {
- sleepInterval += 100;
- }
- } while (status != RPC_S_OK); // redundant check, but compiler would not allow true here.
- *bindingHandle = localBindingHandle;
- return HRESULT_FROM_WIN32(status);
- }
- bool
- JITManager::IsJITServer() const
- {
- return m_isJITServer;
- }
- void
- JITManager::SetIsJITServer()
- {
- m_isJITServer = true;
- m_oopJitEnabled = true;
- }
- bool
- JITManager::IsConnected() const
- {
- Assert(IsOOPJITEnabled());
- return m_rpcBindingHandle != nullptr;
- }
- HANDLE
- JITManager::GetServerHandle() const
- {
- return m_serverHandle;
- }
- void
- JITManager::EnableOOPJIT()
- {
- m_oopJitEnabled = true;
- }
- bool
- JITManager::IsOOPJITEnabled() const
- {
- return m_oopJitEnabled;
- }
- HRESULT
- JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* serverSecurityDescriptor, __in UUID connectionUuid)
- {
- Assert(IsOOPJITEnabled());
- Assert(m_rpcBindingHandle == nullptr);
- Assert(m_serverHandle == nullptr);
- HRESULT hr = E_FAIL;
- if (IsConnected())
- {
- Assert(UNREACHED);
- return E_FAIL;
- }
- if (!DuplicateHandle(GetCurrentProcess(), jitProcessHandle, GetCurrentProcess(), &m_serverHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto FailureCleanup;
- }
- hr = CreateBinding(jitProcessHandle, serverSecurityDescriptor, &connectionUuid, &m_rpcBindingHandle);
- if (FAILED(hr))
- {
- goto FailureCleanup;
- }
- m_jitConnectionId = connectionUuid;
- return hr;
- FailureCleanup:
- if (m_serverHandle)
- {
- CloseHandle(m_serverHandle);
- m_serverHandle = nullptr;
- }
- if (m_rpcBindingHandle)
- {
- RpcBindingFree(&m_rpcBindingHandle);
- m_rpcBindingHandle = nullptr;
- }
- return hr;
- }
- HRESULT
- JITManager::Shutdown()
- {
- // this is special case of shutdown called when runtime process is a parent of the server process
- // used for console host type scenarios
- HRESULT hr = S_OK;
- Assert(IsOOPJITEnabled());
- Assert(m_rpcBindingHandle != nullptr);
- RpcTryExcept
- {
- ClientShutdown(m_rpcBindingHandle);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- m_rpcBindingHandle = nullptr;
- return hr;
- }
- HRESULT
- JITManager::InitializeThreadContext(
- __in ThreadContextDataIDL * data,
- __out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __out intptr_t * prereservedRegionAddr)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientInitializeThreadContext(m_rpcBindingHandle, data, threadContextInfoAddress, prereservedRegionAddr);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CleanupThreadContext(
- __inout PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCleanupThreadContext(m_rpcBindingHandle, threadContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::AddDOMFastPathHelper(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in intptr_t funcInfoAddr,
- __in int helper)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientAddDOMFastPathHelper(m_rpcBindingHandle, scriptContextInfoAddress, funcInfoAddr, helper);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::SetIsPRNGSeeded(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in boolean value)
- {
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientSetIsPRNGSeeded(m_rpcBindingHandle, scriptContextInfoAddress, value);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::DecommitInterpreterBufferManager(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in boolean asmJsThunk)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientDecommitInterpreterBufferManager(m_rpcBindingHandle, scriptContextInfoAddress, asmJsThunk);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::NewInterpreterThunkBlock(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in InterpreterThunkInputIDL * thunkInput,
- __out InterpreterThunkOutputIDL * thunkOutput)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientNewInterpreterThunkBlock(m_rpcBindingHandle, scriptContextInfoAddress, thunkInput, thunkOutput);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::AddModuleRecordInfo(
- /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- /* [in] */ unsigned int moduleId,
- /* [in] */ intptr_t localExportSlotsAddr)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientAddModuleRecordInfo(m_rpcBindingHandle, scriptContextInfoAddress, moduleId, localExportSlotsAddr);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::SetWellKnownHostTypeId(
- __in PTHREADCONTEXT_HANDLE threadContextRoot,
- __in int typeId)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientSetWellKnownHostTypeId(m_rpcBindingHandle, threadContextRoot, typeId);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::UpdatePropertyRecordMap(
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __in_opt BVSparseNodeIDL * updatedPropsBVHead)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientUpdatePropertyRecordMap(m_rpcBindingHandle, threadContextInfoAddress, updatedPropsBVHead);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::InitializeScriptContext(
- __in ScriptContextDataIDL * data,
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __out PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientInitializeScriptContext(m_rpcBindingHandle, data, threadContextInfoAddress, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CleanupScriptContext(
- __inout PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCleanupScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::CloseScriptContext(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientCloseScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::FreeAllocation(
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __in intptr_t address)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientFreeAllocation(m_rpcBindingHandle, threadContextInfoAddress, address);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::IsNativeAddr(
- __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
- __in intptr_t address,
- __out boolean * result)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientIsNativeAddr(m_rpcBindingHandle, threadContextInfoAddress, address, result);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- HRESULT
- JITManager::RemoteCodeGenCall(
- __in CodeGenWorkItemIDL *workItemData,
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __out JITOutputIDL *jitData)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientRemoteCodeGen(m_rpcBindingHandle, scriptContextInfoAddress, workItemData, jitData);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- #if DBG
- HRESULT
- JITManager::IsInterpreterThunkAddr(
- __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
- __in intptr_t address,
- __in boolean asmjsThunk,
- __out boolean * result)
- {
- Assert(IsOOPJITEnabled());
- HRESULT hr = E_FAIL;
- RpcTryExcept
- {
- hr = ClientIsInterpreterThunkAddr(m_rpcBindingHandle, scriptContextInfoAddress, address, asmjsThunk, result);
- }
- RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
- {
- hr = HRESULT_FROM_WIN32(RpcExceptionCode());
- }
- RpcEndExcept;
- return hr;
- }
- #endif
|