JITManager.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "JITClientPch.h"
  6. _Must_inspect_result_
  7. _Ret_maybenull_ _Post_writable_byte_size_(size)
  8. void * __RPC_USER midl_user_allocate(
  9. #if defined(_WIN32_WINNT_WIN10)
  10. _In_ // starting win10, _In_ is in the signature
  11. #endif
  12. size_t size)
  13. {
  14. return (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
  15. }
  16. void __RPC_USER midl_user_free(_Pre_maybenull_ _Post_invalid_ void * ptr)
  17. {
  18. if (ptr != NULL)
  19. {
  20. HeapFree(GetProcessHeap(), NULL, ptr);
  21. }
  22. }
  23. JITManager JITManager::s_jitManager = JITManager();
  24. JITManager::JITManager() :
  25. m_rpcBindingHandle(nullptr),
  26. m_oopJitEnabled(false),
  27. m_isJITServer(false),
  28. m_failingHRESULT(S_OK),
  29. m_jitConnectionId()
  30. {
  31. }
  32. JITManager::~JITManager()
  33. {
  34. if (m_rpcBindingHandle)
  35. {
  36. RpcBindingFree(&m_rpcBindingHandle);
  37. }
  38. }
  39. /* static */
  40. JITManager *
  41. JITManager::GetJITManager()
  42. {
  43. return &s_jitManager;
  44. }
  45. typedef struct _CHAKRA_RPC_SECURITY_QOS_V5 {
  46. unsigned long Version;
  47. unsigned long Capabilities;
  48. unsigned long IdentityTracking;
  49. unsigned long ImpersonationType;
  50. unsigned long AdditionalSecurityInfoType;
  51. union
  52. {
  53. RPC_HTTP_TRANSPORT_CREDENTIALS_W* HttpCredentials;
  54. } u;
  55. void* Sid;
  56. unsigned int EffectiveOnly;
  57. void* ServerSecurityDescriptor;
  58. } CHAKRA_RPC_SECURITY_QOS_V5;
  59. // This routine creates a binding with the server.
  60. HRESULT
  61. JITManager::CreateBinding(
  62. __in HANDLE serverProcessHandle,
  63. __in_opt void * serverSecurityDescriptor,
  64. __in UUID * connectionUuid,
  65. __out RPC_BINDING_HANDLE * bindingHandle)
  66. {
  67. Assert(IsOOPJITEnabled());
  68. RPC_STATUS status;
  69. DWORD attemptCount = 0;
  70. DWORD sleepInterval = 100; // in milliseconds
  71. RPC_BINDING_HANDLE localBindingHandle;
  72. RPC_BINDING_HANDLE_TEMPLATE_V1 bindingTemplate;
  73. RPC_BINDING_HANDLE_SECURITY_V1_W bindingSecurity;
  74. CHAKRA_RPC_SECURITY_QOS_V5 securityQOS;
  75. ZeroMemory(&securityQOS, sizeof(CHAKRA_RPC_SECURITY_QOS_V5));
  76. securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
  77. securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
  78. securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
  79. securityQOS.Version = AutoSystemInfo::Data.IsWin8OrLater() ? 5 : 4;
  80. securityQOS.ServerSecurityDescriptor = serverSecurityDescriptor;
  81. ZeroMemory(&bindingTemplate, sizeof(bindingTemplate));
  82. bindingTemplate.Version = 1;
  83. bindingTemplate.ProtocolSequence = RPC_PROTSEQ_LRPC;
  84. bindingTemplate.StringEndpoint = NULL;
  85. memcpy_s(&bindingTemplate.ObjectUuid, sizeof(UUID), connectionUuid, sizeof(UUID));
  86. bindingTemplate.Flags |= RPC_BHT_OBJECT_UUID_VALID;
  87. ZeroMemory(&bindingSecurity, sizeof(bindingSecurity));
  88. bindingSecurity.Version = 1;
  89. bindingSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
  90. bindingSecurity.AuthnSvc = RPC_C_AUTHN_KERNEL;
  91. bindingSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQOS;
  92. status = RpcBindingCreate(&bindingTemplate, &bindingSecurity, NULL, &localBindingHandle);
  93. if (status != RPC_S_OK)
  94. {
  95. return HRESULT_FROM_WIN32(status);
  96. }
  97. // We keep attempting to connect to the server with increasing wait intervals in between.
  98. // This will wait close to 5 minutes before it finally gives up.
  99. do
  100. {
  101. DWORD waitStatus;
  102. status = RpcBindingBind(NULL, localBindingHandle, ClientIChakraJIT_v0_0_c_ifspec);
  103. if (status == RPC_S_OK)
  104. {
  105. break;
  106. }
  107. else if (status == EPT_S_NOT_REGISTERED)
  108. {
  109. // The Server side has not finished registering the RPC Server yet.
  110. // We should only breakout if we have reached the max attempt count.
  111. if (attemptCount > 600)
  112. {
  113. break;
  114. }
  115. }
  116. else
  117. {
  118. // Some unknown error occurred. We are not going to retry for arbitrary errors.
  119. break;
  120. }
  121. // When we come to this point, it means the server has not finished registration yet.
  122. // We should wait for a while and then reattempt to bind.
  123. waitStatus = WaitForSingleObject(serverProcessHandle, sleepInterval);
  124. if (waitStatus == WAIT_OBJECT_0)
  125. {
  126. // The server process died for some reason. No need to reattempt.
  127. status = RPC_S_SERVER_UNAVAILABLE;
  128. break;
  129. }
  130. else if (waitStatus == WAIT_TIMEOUT)
  131. {
  132. // Not an error. the server is still alive and we should reattempt.
  133. }
  134. else
  135. {
  136. Assert(waitStatus == WAIT_FAILED);
  137. #ifdef DBG
  138. LPWSTR messageBuffer = nullptr;
  139. DWORD errorNumber = GetLastError();
  140. FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  141. NULL, errorNumber, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
  142. Output::Print(_u("Last error was 0x%x (%s)"), errorNumber, messageBuffer);
  143. LocalFree(messageBuffer);
  144. #endif
  145. // wait operation failed for an unknown reason.
  146. Assert(false);
  147. status = HRESULT_FROM_WIN32(waitStatus);
  148. break;
  149. }
  150. attemptCount++;
  151. if (sleepInterval < 500)
  152. {
  153. sleepInterval += 100;
  154. }
  155. } while (status != RPC_S_OK); // redundant check, but compiler would not allow true here.
  156. *bindingHandle = localBindingHandle;
  157. return HRESULT_FROM_WIN32(status);
  158. }
  159. bool
  160. JITManager::IsJITServer() const
  161. {
  162. return m_isJITServer;
  163. }
  164. void
  165. JITManager::SetIsJITServer()
  166. {
  167. m_isJITServer = true;
  168. m_oopJitEnabled = true;
  169. }
  170. bool
  171. JITManager::IsConnected() const
  172. {
  173. Assert(IsOOPJITEnabled());
  174. return m_rpcBindingHandle != nullptr && !HasJITFailed();
  175. }
  176. void
  177. JITManager::EnableOOPJIT()
  178. {
  179. m_oopJitEnabled = true;
  180. if (CONFIG_FLAG(OOPCFGRegistration))
  181. {
  182. // Since this client has enabled OOPJIT, perform the one-way policy update
  183. // that will disable SetProcessValidCallTargets from being invoked.
  184. GlobalSecurityPolicy::DisableSetProcessValidCallTargets();
  185. }
  186. }
  187. void
  188. JITManager::SetJITFailed(HRESULT hr)
  189. {
  190. Assert(hr != S_OK);
  191. m_failingHRESULT = hr;
  192. }
  193. bool
  194. JITManager::HasJITFailed() const
  195. {
  196. return m_failingHRESULT != S_OK;
  197. }
  198. bool
  199. JITManager::IsOOPJITEnabled() const
  200. {
  201. return m_oopJitEnabled;
  202. }
  203. #pragma prefast(push)
  204. #pragma prefast(disable:__WARNING_RELEASING_UNHELD_LOCK_MEDIUM_CONFIDENCE, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
  205. #pragma prefast(disable:__WARNING_CALLER_FAILING_TO_HOLD, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
  206. HRESULT
  207. JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* serverSecurityDescriptor, __in UUID connectionUuid)
  208. {
  209. // We might be trying to connect from multiple threads simultaneously
  210. AutoCriticalSection cs(&m_cs);
  211. Assert(IsOOPJITEnabled());
  212. if (m_rpcBindingHandle != nullptr)
  213. {
  214. return S_OK;
  215. }
  216. HRESULT hr = E_FAIL;
  217. RPC_BINDING_HANDLE bindingHandle;
  218. hr = CreateBinding(jitProcessHandle, serverSecurityDescriptor, &connectionUuid, &bindingHandle);
  219. if (FAILED(hr))
  220. {
  221. goto FailureCleanup;
  222. }
  223. hr = ConnectProcess(bindingHandle);
  224. HandleServerCallResult(hr, RemoteCallType::StateUpdate);
  225. // Only store the binding handle after JIT handshake, so other threads do not prematurely think we are ready to JIT
  226. m_rpcBindingHandle = bindingHandle;
  227. m_jitConnectionId = connectionUuid;
  228. return hr;
  229. FailureCleanup:
  230. if (m_rpcBindingHandle)
  231. {
  232. RpcBindingFree(&m_rpcBindingHandle);
  233. m_rpcBindingHandle = nullptr;
  234. }
  235. return hr;
  236. }
  237. #pragma prefast(pop)
  238. HRESULT
  239. JITManager::Shutdown()
  240. {
  241. // this is special case of shutdown called when runtime process is a parent of the server process
  242. // used for console host type scenarios
  243. HRESULT hr = S_OK;
  244. Assert(IsOOPJITEnabled());
  245. Assert(m_rpcBindingHandle != nullptr);
  246. RpcTryExcept
  247. {
  248. ClientShutdown(m_rpcBindingHandle);
  249. }
  250. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  251. {
  252. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  253. }
  254. RpcEndExcept;
  255. m_rpcBindingHandle = nullptr;
  256. return hr;
  257. }
  258. HRESULT
  259. JITManager::ConnectProcess(RPC_BINDING_HANDLE rpcBindingHandle)
  260. {
  261. Assert(IsOOPJITEnabled());
  262. HRESULT hr = E_FAIL;
  263. if (AutoSystemInfo::Data.IsWin8Point1OrLater())
  264. {
  265. HANDLE processHandle = nullptr;
  266. // RPC handle marshalling is only available on 8.1+
  267. if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &processHandle, 0, false, DUPLICATE_SAME_ACCESS))
  268. {
  269. return HRESULT_FROM_WIN32(GetLastError());
  270. }
  271. RpcTryExcept
  272. {
  273. hr = ClientConnectProcessWithProcessHandle(
  274. rpcBindingHandle,
  275. processHandle,
  276. (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
  277. (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
  278. }
  279. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  280. {
  281. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  282. }
  283. RpcEndExcept;
  284. if (processHandle)
  285. {
  286. CloseHandle(processHandle);
  287. }
  288. }
  289. else
  290. {
  291. #if (WINVER >= _WIN32_WINNT_WINBLUE)
  292. AssertOrFailFast(UNREACHED);
  293. #else
  294. RpcTryExcept
  295. {
  296. hr = ClientConnectProcess(
  297. rpcBindingHandle,
  298. (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
  299. (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
  300. }
  301. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  302. {
  303. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  304. }
  305. RpcEndExcept;
  306. #endif
  307. }
  308. return hr;
  309. }
  310. HRESULT
  311. JITManager::InitializeThreadContext(
  312. __in ThreadContextDataIDL * data,
  313. __out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
  314. __out intptr_t * prereservedRegionAddr,
  315. __out intptr_t * jitThunkAddr)
  316. {
  317. Assert(IsOOPJITEnabled());
  318. HRESULT hr = E_FAIL;
  319. RpcTryExcept
  320. {
  321. hr = ClientInitializeThreadContext(
  322. m_rpcBindingHandle,
  323. data,
  324. threadContextInfoAddress,
  325. prereservedRegionAddr,
  326. jitThunkAddr);
  327. }
  328. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  329. {
  330. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  331. }
  332. RpcEndExcept;
  333. return hr;
  334. }
  335. HRESULT
  336. JITManager::CleanupThreadContext(
  337. __inout PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
  338. {
  339. Assert(IsOOPJITEnabled());
  340. HRESULT hr = E_FAIL;
  341. RpcTryExcept
  342. {
  343. hr = ClientCleanupThreadContext(m_rpcBindingHandle, threadContextInfoAddress);
  344. }
  345. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  346. {
  347. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  348. }
  349. RpcEndExcept;
  350. return hr;
  351. }
  352. HRESULT
  353. JITManager::AddDOMFastPathHelper(
  354. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  355. __in intptr_t funcInfoAddr,
  356. __in int helper)
  357. {
  358. Assert(IsOOPJITEnabled());
  359. HRESULT hr = E_FAIL;
  360. RpcTryExcept
  361. {
  362. hr = ClientAddDOMFastPathHelper(m_rpcBindingHandle, scriptContextInfoAddress, funcInfoAddr, helper);
  363. }
  364. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  365. {
  366. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  367. }
  368. RpcEndExcept;
  369. return hr;
  370. }
  371. HRESULT
  372. JITManager::SetIsPRNGSeeded(
  373. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  374. __in boolean value)
  375. {
  376. HRESULT hr = E_FAIL;
  377. RpcTryExcept
  378. {
  379. hr = ClientSetIsPRNGSeeded(m_rpcBindingHandle, scriptContextInfoAddress, value);
  380. }
  381. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  382. {
  383. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  384. }
  385. RpcEndExcept;
  386. return hr;
  387. }
  388. HRESULT
  389. JITManager::DecommitInterpreterBufferManager(
  390. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  391. __in boolean asmJsThunk)
  392. {
  393. Assert(IsOOPJITEnabled());
  394. HRESULT hr = E_FAIL;
  395. RpcTryExcept
  396. {
  397. hr = ClientDecommitInterpreterBufferManager(m_rpcBindingHandle, scriptContextInfoAddress, asmJsThunk);
  398. }
  399. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  400. {
  401. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  402. }
  403. RpcEndExcept;
  404. return hr;
  405. }
  406. HRESULT
  407. JITManager::NewInterpreterThunkBlock(
  408. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  409. __in InterpreterThunkInputIDL * thunkInput,
  410. __out InterpreterThunkOutputIDL * thunkOutput)
  411. {
  412. Assert(IsOOPJITEnabled());
  413. HRESULT hr = E_FAIL;
  414. RpcTryExcept
  415. {
  416. hr = ClientNewInterpreterThunkBlock(m_rpcBindingHandle, scriptContextInfoAddress, thunkInput, thunkOutput);
  417. }
  418. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  419. {
  420. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  421. }
  422. RpcEndExcept;
  423. return hr;
  424. }
  425. HRESULT
  426. JITManager::AddModuleRecordInfo(
  427. /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  428. /* [in] */ unsigned int moduleId,
  429. /* [in] */ intptr_t localExportSlotsAddr)
  430. {
  431. Assert(IsOOPJITEnabled());
  432. HRESULT hr = E_FAIL;
  433. RpcTryExcept
  434. {
  435. hr = ClientAddModuleRecordInfo(m_rpcBindingHandle, scriptContextInfoAddress, moduleId, localExportSlotsAddr);
  436. }
  437. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  438. {
  439. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  440. }
  441. RpcEndExcept;
  442. return hr;
  443. }
  444. HRESULT
  445. JITManager::SetWellKnownHostTypeId(
  446. __in PTHREADCONTEXT_HANDLE threadContextRoot,
  447. __in int typeId)
  448. {
  449. Assert(IsOOPJITEnabled());
  450. HRESULT hr = E_FAIL;
  451. RpcTryExcept
  452. {
  453. hr = ClientSetWellKnownHostTypeId(m_rpcBindingHandle, threadContextRoot, typeId);
  454. }
  455. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  456. {
  457. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  458. }
  459. RpcEndExcept;
  460. return hr;
  461. }
  462. HRESULT
  463. JITManager::UpdatePropertyRecordMap(
  464. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  465. __in_opt BVSparseNodeIDL * updatedPropsBVHead)
  466. {
  467. Assert(IsOOPJITEnabled());
  468. HRESULT hr = E_FAIL;
  469. RpcTryExcept
  470. {
  471. hr = ClientUpdatePropertyRecordMap(m_rpcBindingHandle, threadContextInfoAddress, updatedPropsBVHead);
  472. }
  473. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  474. {
  475. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  476. }
  477. RpcEndExcept;
  478. return hr;
  479. }
  480. HRESULT
  481. JITManager::InitializeScriptContext(
  482. __in ScriptContextDataIDL * data,
  483. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  484. __out PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  485. {
  486. Assert(IsOOPJITEnabled());
  487. HRESULT hr = E_FAIL;
  488. RpcTryExcept
  489. {
  490. hr = ClientInitializeScriptContext(m_rpcBindingHandle, data, threadContextInfoAddress, scriptContextInfoAddress);
  491. }
  492. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  493. {
  494. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  495. }
  496. RpcEndExcept;
  497. return hr;
  498. }
  499. HRESULT
  500. JITManager::CleanupScriptContext(
  501. __inout PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  502. {
  503. Assert(IsOOPJITEnabled());
  504. HRESULT hr = E_FAIL;
  505. RpcTryExcept
  506. {
  507. hr = ClientCleanupScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  508. }
  509. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  510. {
  511. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  512. }
  513. RpcEndExcept;
  514. return hr;
  515. }
  516. HRESULT
  517. JITManager::CloseScriptContext(
  518. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  519. {
  520. Assert(IsOOPJITEnabled());
  521. HRESULT hr = E_FAIL;
  522. RpcTryExcept
  523. {
  524. hr = ClientCloseScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  525. }
  526. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  527. {
  528. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  529. }
  530. RpcEndExcept;
  531. return hr;
  532. }
  533. HRESULT
  534. JITManager::FreeAllocation(
  535. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  536. __in intptr_t codeAddress)
  537. {
  538. Assert(IsOOPJITEnabled());
  539. HRESULT hr = E_FAIL;
  540. RpcTryExcept
  541. {
  542. hr = ClientFreeAllocation(m_rpcBindingHandle, scriptContextInfoAddress, codeAddress);
  543. }
  544. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  545. {
  546. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  547. }
  548. RpcEndExcept;
  549. return hr;
  550. }
  551. HRESULT
  552. JITManager::IsNativeAddr(
  553. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  554. __in intptr_t address,
  555. __out boolean * result)
  556. {
  557. Assert(IsOOPJITEnabled());
  558. HRESULT hr = E_FAIL;
  559. RpcTryExcept
  560. {
  561. hr = ClientIsNativeAddr(m_rpcBindingHandle, threadContextInfoAddress, address, result);
  562. }
  563. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  564. {
  565. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  566. }
  567. RpcEndExcept;
  568. return hr;
  569. }
  570. HRESULT
  571. JITManager::RemoteCodeGenCall(
  572. __in CodeGenWorkItemIDL *workItemData,
  573. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  574. __out JITOutputIDL *jitData)
  575. {
  576. Assert(IsOOPJITEnabled());
  577. HRESULT hr = E_FAIL;
  578. RpcTryExcept
  579. {
  580. hr = ClientRemoteCodeGen(m_rpcBindingHandle, scriptContextInfoAddress, workItemData, jitData);
  581. }
  582. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  583. {
  584. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  585. }
  586. RpcEndExcept;
  587. return hr;
  588. }
  589. #if DBG
  590. HRESULT
  591. JITManager::IsInterpreterThunkAddr(
  592. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  593. __in intptr_t address,
  594. __in boolean asmjsThunk,
  595. __out boolean * result)
  596. {
  597. Assert(IsOOPJITEnabled());
  598. HRESULT hr = E_FAIL;
  599. RpcTryExcept
  600. {
  601. hr = ClientIsInterpreterThunkAddr(m_rpcBindingHandle, scriptContextInfoAddress, address, asmjsThunk, result);
  602. }
  603. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  604. {
  605. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  606. }
  607. RpcEndExcept;
  608. return hr;
  609. }
  610. #endif
  611. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  612. HRESULT
  613. JITManager::DeserializeRPCData(
  614. _In_reads_(bufferSize) const byte* buffer,
  615. _In_ uint bufferSize,
  616. _Out_ CodeGenWorkItemIDL **workItemData
  617. )
  618. {
  619. RPC_STATUS status = RPC_S_OK;
  620. handle_t marshalHandle = nullptr;
  621. *workItemData = nullptr;
  622. __try
  623. {
  624. RpcTryExcept
  625. {
  626. status = MesDecodeBufferHandleCreate((char*)buffer, bufferSize, &marshalHandle);
  627. if (status != RPC_S_OK)
  628. {
  629. return HRESULT_FROM_WIN32(status);
  630. }
  631. pCodeGenWorkItemIDL_Decode(
  632. marshalHandle,
  633. workItemData);
  634. }
  635. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  636. {
  637. status = RpcExceptionCode();
  638. }
  639. RpcEndExcept;
  640. }
  641. __finally
  642. {
  643. MesHandleFree(marshalHandle);
  644. }
  645. return HRESULT_FROM_WIN32(status);
  646. }
  647. HRESULT
  648. JITManager::SerializeRPCData(_In_ CodeGenWorkItemIDL *workItemData, _Out_ size_t* bufferSize, _Outptr_result_buffer_(*bufferSize) const byte** outBuffer)
  649. {
  650. handle_t marshalHandle = nullptr;
  651. *bufferSize = 0;
  652. *outBuffer = nullptr;
  653. RPC_STATUS status = RPC_S_OK;
  654. __try
  655. {
  656. RpcTryExcept
  657. {
  658. char* data = nullptr;
  659. unsigned long encodedSize;
  660. status = MesEncodeDynBufferHandleCreate(
  661. &data,
  662. &encodedSize,
  663. &marshalHandle);
  664. if (status != RPC_S_OK)
  665. {
  666. return HRESULT_FROM_WIN32(status);
  667. }
  668. MIDL_ES_CODE encodeType = MES_ENCODE;
  669. #if TARGET_64
  670. encodeType = MES_ENCODE_NDR64;
  671. // We only support encode syntax NDR64, however MesEncodeDynBufferHandleCreate doesn't allow to specify it
  672. status = MesBufferHandleReset(
  673. marshalHandle,
  674. MES_DYNAMIC_BUFFER_HANDLE,
  675. encodeType,
  676. &data,
  677. 0,
  678. &encodedSize
  679. );
  680. if (status != RPC_S_OK)
  681. {
  682. return HRESULT_FROM_WIN32(status);
  683. }
  684. #endif
  685. // Calculate how big we need to create the buffer
  686. size_t tmpBufSize = pCodeGenWorkItemIDL_AlignSize(marshalHandle, &workItemData);
  687. size_t alignedBufSize = Math::Align<size_t>(tmpBufSize, 16);
  688. data = HeapNewNoThrowArray(char, alignedBufSize);
  689. if (!data)
  690. {
  691. // Ran out of memory
  692. return E_OUTOFMEMORY;
  693. }
  694. // Reset the buffer handle to a fixed buffer
  695. status = MesBufferHandleReset(
  696. marshalHandle,
  697. MES_FIXED_BUFFER_HANDLE,
  698. encodeType,
  699. &data,
  700. (unsigned long)alignedBufSize,
  701. &encodedSize
  702. );
  703. if (status != RPC_S_OK)
  704. {
  705. return HRESULT_FROM_WIN32(status);
  706. }
  707. pCodeGenWorkItemIDL_Encode(
  708. marshalHandle,
  709. &workItemData);
  710. *bufferSize = alignedBufSize;
  711. *outBuffer = (byte*)data;
  712. }
  713. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  714. {
  715. status = RpcExceptionCode();
  716. }
  717. RpcEndExcept;
  718. }
  719. __finally
  720. {
  721. MesHandleFree(marshalHandle);
  722. }
  723. return HRESULT_FROM_WIN32(status);
  724. }
  725. #endif