Skip to content

Commit 1fda884

Browse files
committed
have jit server close more gracefully
1 parent 1a74bca commit 1fda884

File tree

9 files changed

+105
-112
lines changed

9 files changed

+105
-112
lines changed

bin/ChakraCore/ChakraCore.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ JsModuleEvaluation
4949
JsSetModuleHostInfo
5050
JsGetModuleHostInfo
5151
JsInitializeJITServer
52+
JsShutdownJITServer

bin/ch/HostConfigFlagsList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ FLAG(BSTR, GenerateLibraryByteCodeHeader, "Generate bytecode header file from
1010
FLAG(int, InspectMaxStringLength, "Max string length to dump in locals inspection", 16)
1111
FLAG(BSTR, Serialized, "If source is UTF8, deserializes from bytecode file", NULL)
1212
FLAG(bool, EnableOutOfProcJIT, "Run JIT in a separate process", false)
13+
FLAG(bool, EnsureCloseJITServer, "JIT process will be force closed when ch is terminated", false)
1314
#undef FLAG
1415
#endif

bin/ch/JITProcessManager.cpp

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ HRESULT JITProcessManager::StartRpcServer(int argc, __in_ecount(argc) LPWSTR arg
1414
HRESULT hr = S_OK;
1515

1616
JITProcessManager::RemoveArg(_u("-dynamicprofilecache:"), &argc, &argv);
17+
JITProcessManager::RemoveArg(_u("-dpc:"), &argc, &argv);
1718
JITProcessManager::RemoveArg(_u("-dynamicprofileinput:"), &argc, &argv);
1819

1920
if (IsEqualGUID(s_connectionId, GUID_NULL))
@@ -126,37 +127,57 @@ HRESULT JITProcessManager::CreateServerProcess(int argc, __in_ecount(argc) LPWST
126127
CloseHandle(processInfo.hThread);
127128
s_rpcServerProcessHandle = processInfo.hProcess;
128129

129-
// create job object so if parent jshost gets killed, server is killed as well
130-
HANDLE jobObject = CreateJobObject(nullptr, nullptr);
131-
if (jobObject == nullptr)
130+
if (HostConfigFlags::flags.EnsureCloseJITServer)
132131
{
133-
return HRESULT_FROM_WIN32(GetLastError());
134-
}
135-
if (!AssignProcessToJobObject(jobObject, s_rpcServerProcessHandle))
136-
{
137-
return HRESULT_FROM_WIN32(GetLastError());
138-
}
132+
// create job object so if parent ch gets killed, server is killed as well
133+
// under a flag because it's preferable to let server close naturally
134+
// only useful in scenarios where ch is expected to be force terminated
135+
HANDLE jobObject = CreateJobObject(nullptr, nullptr);
136+
if (jobObject == nullptr)
137+
{
138+
return HRESULT_FROM_WIN32(GetLastError());
139+
}
140+
if (!AssignProcessToJobObject(jobObject, s_rpcServerProcessHandle))
141+
{
142+
return HRESULT_FROM_WIN32(GetLastError());
143+
}
139144

140-
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { 0 };
141-
jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
145+
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = { 0 };
146+
jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
142147

143-
if (!SetInformationJobObject(jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo)))
144-
{
145-
return HRESULT_FROM_WIN32(GetLastError());
148+
if (!SetInformationJobObject(jobObject, JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo)))
149+
{
150+
return HRESULT_FROM_WIN32(GetLastError());
151+
}
146152
}
147153

148154
return NOERROR;
149155
}
150156

151-
void JITProcessManager::StopRpcServer()
152-
{
153-
// For now we just kill the process
154-
TerminateProcess(s_rpcServerProcessHandle, 1);
157+
typedef HRESULT(WINAPI *JsShutdownJITServerPtr)();
155158

156-
CloseHandle(s_rpcServerProcessHandle);
159+
void JITProcessManager::StopRpcServer(HINSTANCE chakraLibrary)
160+
{
161+
if (s_rpcServerProcessHandle)
162+
{
163+
JsShutdownJITServerPtr shutdownJITServer = (JsShutdownJITServerPtr)GetProcAddress(chakraLibrary, "JsShutdownJITServer");
164+
shutdownJITServer();
165+
}
157166
s_rpcServerProcessHandle = NULL;
158167
}
159168

169+
void
170+
JITProcessManager::TerminateJITServer()
171+
{
172+
if (s_rpcServerProcessHandle)
173+
{
174+
TerminateProcess(s_rpcServerProcessHandle, 1);
175+
176+
CloseHandle(s_rpcServerProcessHandle);
177+
s_rpcServerProcessHandle = NULL;
178+
}
179+
}
180+
160181
HANDLE JITProcessManager::GetRpcProccessHandle()
161182
{
162183
return s_rpcServerProcessHandle;

bin/ch/JITProcessManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ class JITProcessManager
99
{
1010
public:
1111
static HRESULT StartRpcServer(int argc, __in_ecount(argc) LPWSTR argv[]);
12-
static void StopRpcServer();
12+
static void StopRpcServer(HINSTANCE chakraLibrary);
13+
static void TerminateJITServer();
1314

1415
static HANDLE GetRpcProccessHandle();
1516
static UUID GetRpcConnectionId();

bin/ch/ch.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int HostExceptionFilter(int exceptionCode, _EXCEPTION_POINTERS *ep)
3838
ChakraRTInterface::NotifyUnhandledException(ep);
3939

4040
#if ENABLE_NATIVE_CODEGEN
41-
JITProcessManager::StopRpcServer();
41+
JITProcessManager::TerminateJITServer();
4242
#endif
4343
bool crashOnException = false;
4444
ChakraRTInterface::GetCrashOnExceptionFlag(&crashOnException);
@@ -853,8 +853,18 @@ int _cdecl wmain(int argc, __in_ecount(argc) LPWSTR argv[])
853853
// On linux, execute on the same thread
854854
ExecuteTestWithMemoryCheck(argInfo.filename);
855855
#endif
856+
857+
#if ENABLE_NATIVE_CODEGEN && defined(_WIN32)
858+
JITProcessManager::StopRpcServer(chakraLibrary);
859+
#endif
856860
ChakraRTInterface::UnloadChakraDll(chakraLibrary);
857861
}
862+
#if ENABLE_NATIVE_CODEGEN && defined(_WIN32)
863+
else
864+
{
865+
JITProcessManager::TerminateJITServer();
866+
}
867+
#endif
858868

859869
PAL_Shutdown();
860870
return 0;

lib/JITClient/JITManager.cpp

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ JITManager::JITManager() :
3535

3636
JITManager::~JITManager()
3737
{
38-
// TODO: OOP JIT, what to do in case we fail to disconnect?
39-
DisconnectRpcServer();
38+
if (m_rpcBindingHandle)
39+
{
40+
RpcBindingFree(&m_rpcBindingHandle);
41+
}
4042
}
4143

4244
/* static */
@@ -54,7 +56,7 @@ JITManager::CreateBinding(
5456
__in UUID * connectionUuid,
5557
__out RPC_BINDING_HANDLE * bindingHandle)
5658
{
57-
Assert(JITManager::IsOOPJITEnabled());
59+
Assert(IsOOPJITEnabled());
5860

5961
RPC_STATUS status;
6062
DWORD attemptCount = 0;
@@ -170,7 +172,7 @@ JITManager::CreateBinding(
170172
bool
171173
JITManager::IsConnected() const
172174
{
173-
Assert(JITManager::IsOOPJITEnabled());
175+
Assert(IsOOPJITEnabled());
174176
return m_rpcBindingHandle != nullptr && m_targetHandle != nullptr;
175177
}
176178

@@ -200,7 +202,7 @@ JITManager::GetJITTargetHandle() const
200202
HRESULT
201203
JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* serverSecurityDescriptor, __in UUID connectionUuid)
202204
{
203-
Assert(JITManager::IsOOPJITEnabled());
205+
Assert(IsOOPJITEnabled());
204206

205207
HRESULT hr;
206208
RPC_BINDING_HANDLE localBindingHandle;
@@ -231,22 +233,12 @@ JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* server
231233
}
232234

233235
HRESULT
234-
JITManager::DisconnectRpcServer()
236+
JITManager::Shutdown()
235237
{
236238
HRESULT hr = S_OK;
237239

238-
if (m_rpcBindingHandle == nullptr)
239-
{
240-
Assert(m_rpcBindingHandle == nullptr);
241-
Assert(m_targetHandle == nullptr);
242-
return hr;
243-
}
244-
245-
Assert(JITManager::IsOOPJITEnabled());
246-
247-
CleanupProcess((intptr_t)m_targetHandle);
240+
Assert(IsOOPJITEnabled());
248241

249-
// TODO: OOP JIT, host should do this
250242
RpcTryExcept
251243
{
252244
ClientShutdown(m_rpcBindingHandle);
@@ -257,21 +249,6 @@ JITManager::DisconnectRpcServer()
257249
}
258250
RpcEndExcept;
259251

260-
if (FAILED(hr))
261-
{
262-
return hr;
263-
}
264-
265-
hr = HRESULT_FROM_WIN32(RpcBindingFree(&m_rpcBindingHandle));
266-
if (FAILED(hr))
267-
{
268-
return hr;
269-
}
270-
271-
m_targetHandle = nullptr;
272-
m_rpcBindingHandle = nullptr;
273-
m_jitConnectionId = {0};
274-
275252
return hr;
276253
}
277254

@@ -281,7 +258,7 @@ JITManager::InitializeThreadContext(
281258
__out intptr_t * threadContextInfoAddress,
282259
__out intptr_t * prereservedRegionAddr)
283260
{
284-
Assert(JITManager::IsOOPJITEnabled());
261+
Assert(IsOOPJITEnabled());
285262

286263
HRESULT hr = E_FAIL;
287264
RpcTryExcept
@@ -297,31 +274,11 @@ JITManager::InitializeThreadContext(
297274
return hr;
298275
}
299276

300-
HRESULT
301-
JITManager::CleanupProcess(
302-
__in intptr_t processHandle)
303-
{
304-
Assert(JITManager::IsOOPJITEnabled());
305-
306-
HRESULT hr = E_FAIL;
307-
RpcTryExcept
308-
{
309-
hr = ClientCleanupProcess(m_rpcBindingHandle, processHandle);
310-
}
311-
RpcExcept(1)
312-
{
313-
hr = HRESULT_FROM_WIN32(RpcExceptionCode());
314-
}
315-
RpcEndExcept;
316-
317-
return hr;
318-
}
319-
320277
HRESULT
321278
JITManager::CleanupThreadContext(
322279
__in intptr_t threadContextInfoAddress)
323280
{
324-
Assert(JITManager::IsOOPJITEnabled());
281+
Assert(IsOOPJITEnabled());
325282

326283
HRESULT hr = E_FAIL;
327284
RpcTryExcept
@@ -343,7 +300,7 @@ JITManager::AddDOMFastPathHelper(
343300
__in intptr_t funcInfoAddr,
344301
__in int helper)
345302
{
346-
Assert(JITManager::IsOOPJITEnabled());
303+
Assert(IsOOPJITEnabled());
347304

348305
HRESULT hr = E_FAIL;
349306
RpcTryExcept
@@ -385,7 +342,7 @@ JITManager::AddModuleRecordInfo(
385342
/* [in] */ unsigned int moduleId,
386343
/* [in] */ intptr_t localExportSlotsAddr)
387344
{
388-
Assert(JITManager::IsOOPJITEnabled());
345+
Assert(IsOOPJITEnabled());
389346

390347
HRESULT hr = E_FAIL;
391348
RpcTryExcept
@@ -408,7 +365,7 @@ JITManager::SetWellKnownHostTypeId(
408365
__in int typeId)
409366
{
410367

411-
Assert(JITManager::IsOOPJITEnabled());
368+
Assert(IsOOPJITEnabled());
412369

413370
HRESULT hr = E_FAIL;
414371
RpcTryExcept
@@ -431,7 +388,7 @@ JITManager::AddPropertyRecordArray(
431388
__in uint count,
432389
__in PropertyRecordIDL ** propertyRecordArray)
433390
{
434-
Assert(JITManager::IsOOPJITEnabled());
391+
Assert(IsOOPJITEnabled());
435392

436393
HRESULT hr = E_FAIL;
437394
RpcTryExcept
@@ -452,7 +409,7 @@ JITManager::InitializeScriptContext(
452409
__in ScriptContextDataIDL * data,
453410
__out intptr_t * scriptContextInfoAddress)
454411
{
455-
Assert(JITManager::IsOOPJITEnabled());
412+
Assert(IsOOPJITEnabled());
456413

457414
HRESULT hr = E_FAIL;
458415
RpcTryExcept
@@ -472,7 +429,7 @@ HRESULT
472429
JITManager::CleanupScriptContext(
473430
__in intptr_t scriptContextInfoAddress)
474431
{
475-
Assert(JITManager::IsOOPJITEnabled());
432+
Assert(IsOOPJITEnabled());
476433

477434
HRESULT hr = E_FAIL;
478435
RpcTryExcept
@@ -492,7 +449,7 @@ HRESULT
492449
JITManager::CloseScriptContext(
493450
__in intptr_t scriptContextInfoAddress)
494451
{
495-
Assert(JITManager::IsOOPJITEnabled());
452+
Assert(IsOOPJITEnabled());
496453

497454
HRESULT hr = E_FAIL;
498455
RpcTryExcept
@@ -513,7 +470,7 @@ JITManager::FreeAllocation(
513470
__in intptr_t threadContextInfoAddress,
514471
__in intptr_t address)
515472
{
516-
Assert(JITManager::IsOOPJITEnabled());
473+
Assert(IsOOPJITEnabled());
517474

518475
HRESULT hr = E_FAIL;
519476
RpcTryExcept
@@ -535,7 +492,7 @@ JITManager::IsNativeAddr(
535492
__in intptr_t address,
536493
__out boolean * result)
537494
{
538-
Assert(JITManager::IsOOPJITEnabled());
495+
Assert(IsOOPJITEnabled());
539496

540497
HRESULT hr = E_FAIL;
541498
RpcTryExcept
@@ -558,7 +515,7 @@ JITManager::RemoteCodeGenCall(
558515
__in intptr_t scriptContextInfoAddress,
559516
__out JITOutputIDL *jitData)
560517
{
561-
Assert(JITManager::IsOOPJITEnabled());
518+
Assert(IsOOPJITEnabled());
562519

563520
HRESULT hr = E_FAIL;
564521
RpcTryExcept

lib/JITClient/JITManager.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,13 @@ class JITManager
1414
bool IsOOPJITEnabled() const;
1515
void EnableOOPJIT();
1616

17-
~JITManager();
18-
1917
HANDLE GetJITTargetHandle() const;
2018

2119
HRESULT InitializeThreadContext(
2220
__in ThreadContextDataIDL * data,
2321
__out intptr_t *threadContextInfoAddress,
2422
__out intptr_t *prereservedRegionAddr);
2523

26-
HRESULT CleanupProcess(
27-
__in intptr_t processHandle);
28-
2924
HRESULT CleanupThreadContext(
3025
__in intptr_t threadContextInfoAddress);
3126

@@ -77,10 +72,12 @@ class JITManager
7772
__in intptr_t scriptContextInfoAddress,
7873
__out JITOutputIDL *jitData);
7974

75+
HRESULT Shutdown();
76+
8077
static JITManager * GetJITManager();
8178
private:
8279
JITManager();
83-
HRESULT DisconnectRpcServer();
80+
~JITManager();
8481

8582
HRESULT JITManager::CreateBinding(
8683
__in HANDLE serverProcessHandle,

lib/JITIDL/ChakraJIT.idl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ interface IChakraJIT
1919
[out] CHAKRA_PTR * threadContextInfoAddress,
2020
[out] CHAKRA_PTR * prereservedRegionAddr);
2121

22-
HRESULT CleanupProcess(
23-
[in] handle_t binding,
24-
[in] CHAKRA_PTR processHandle);
25-
2622
HRESULT CleanupThreadContext(
2723
[in] handle_t binding,
2824
[in] CHAKRA_PTR threadContextInfoAddress);

0 commit comments

Comments
 (0)