forked from chakra-core/ChakraCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChakraCoreDllFunc.cpp
More file actions
167 lines (142 loc) · 5.26 KB
/
ChakraCoreDllFunc.cpp
File metadata and controls
167 lines (142 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "Runtime.h"
#include "core\AtomLockGuids.h"
#include "core\ConfigParser.h"
#include "Base\ThreadContextTLSEntry.h"
#include "Base\ThreadBoundThreadContextManager.h"
#ifdef DYNAMIC_PROFILE_STORAGE
#include "Language\DynamicProfileStorage.h"
#endif
#include "jsrtcontext.h"
#include "TestHooks.h"
extern HANDLE g_hInstance;
static ATOM lockedDll = 0;
static BOOL AttachProcess(HANDLE hmod)
{
if (!ThreadContextTLSEntry::InitializeProcess() || !JsrtContext::Initialize())
{
return FALSE;
}
g_hInstance = hmod;
AutoSystemInfo::SaveModuleFileName(hmod);
#if defined(_M_IX86)
// Enable SSE2 math functions in CRT if SSE2 is available
#pragma prefast(suppress:6031, "We don't require SSE2, but will use it if available")
_set_SSE2_enable(TRUE);
#endif
#ifdef ENABLE_TEST_HOOKS
if (FAILED(OnChakraCoreLoaded()))
{
return FALSE;
}
#endif
{
CmdLineArgsParser parser;
ConfigParser::ParseOnModuleLoad(parser, hmod);
}
#ifdef ENABLE_JS_ETW
EtwTrace::Register();
#endif
ValueType::Initialize();
ThreadContext::GlobalInitialize();
wchar_t *engine = szChakraCoreLock;
if (::FindAtom(szJScript9Lock) != 0)
{
AssertMsg(FALSE, "Expecting to load chakracore.dll but process already loaded jscript9.dll");
Binary_Inconsistency_fatal_error();
}
if (::FindAtom(szChakraLock) != 0)
{
AssertMsg(FALSE, "Expecting to load chakracore.dll but process already loaded chakra.dll");
Binary_Inconsistency_fatal_error();
}
lockedDll = ::AddAtom(engine);
AssertMsg(lockedDll, "Failed to lock chakracore.dll");
#ifdef ENABLE_BASIC_TELEMETRY
g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
#endif
#ifdef DYNAMIC_PROFILE_STORAGE
return DynamicProfileStorage::Initialize();
#else
return TRUE;
#endif
}
static void DetachProcess()
{
ThreadBoundThreadContextManager::DestroyAllContextsAndEntries();
// In JScript, we never unload except for when the app shuts down
// because DllCanUnloadNow always returns S_FALSE. As a result
// it's okay that we never try to cleanup. Attempting to cleanup on
// shutdown is bad because we shouldn't free objects built into
// other dlls.
JsrtRuntime::Uninitialize();
JsrtContext::Uninitialize();
// thread-bound entrypoint should be able to get cleanup correctly, however tlsentry
// for current thread might be left behind if this thread was initialized.
ThreadContextTLSEntry::CleanupThread();
ThreadContextTLSEntry::CleanupProcess();
#if PROFILE_DICTIONARY
DictionaryStats::OutputStats();
#endif
g_hInstance = NULL;
}
/****************************** Public Functions *****************************/
#if _WIN32 || _WIN64
EXTERN_C BOOL WINAPI DllMain(HINSTANCE hmod, DWORD dwReason, PVOID pvReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
return AttachProcess(hmod);
}
case DLL_THREAD_ATTACH:
ThreadContextTLSEntry::InitializeThread();
#ifdef HEAP_TRACK_ALLOC
HeapAllocator::InitializeThread();
#endif
return TRUE;
case DLL_THREAD_DETACH:
// If we are not doing DllCanUnloadNow, so we should clean up. Otherwise, DllCanUnloadNow is already running,
// so the ThreadContext global lock is already taken. If we try to clean up, we will block on the ThreadContext
// global lock while holding the loader lock, which DllCanUnloadNow may block on waiting for thread termination
// which requires the loader lock. DllCanUnloadNow will clean up for us anyway, so we can just skip the whole thing.
ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
return TRUE;
case DLL_PROCESS_DETACH:
lockedDll = ::DeleteAtom(lockedDll);
AssertMsg(lockedDll == 0, "Failed to release the lock for chakracore.dll");
#ifdef DYNAMIC_PROFILE_STORAGE
DynamicProfileStorage::Uninitialize();
#endif
#ifdef ENABLE_JS_ETW
// Do this before DetachProcess() so that we won't have ETW rundown callbacks while destroying threadContexts.
EtwTrace::UnRegister();
#endif
// don't do anything if we are in forceful shutdown
// try to clean up handles in graceful shutdown
if (pvReserved == NULL)
{
DetachProcess();
}
#if defined(CHECK_MEMORY_LEAK) || defined(LEAK_REPORT)
else
{
ThreadContext::ReportAndCheckLeaksOnProcessDetach();
}
#endif
return TRUE;
default:
AssertMsg(FALSE, "DllMain() called with unrecognized dwReason.");
return FALSE;
}
}
#endif // _WIN32 || _WIN64
void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
{
autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
}