JsrtHelper.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 "JsrtPch.h"
  6. #include "jsrtHelper.h"
  7. #include "Base/ThreadContextTlsEntry.h"
  8. #ifdef DYNAMIC_PROFILE_STORAGE
  9. #include "Language/DynamicProfileStorage.h"
  10. #endif
  11. #ifdef CHAKRA_STATIC_LIBRARY
  12. #include "Core/ConfigParser.h"
  13. void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
  14. {
  15. autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
  16. autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
  17. }
  18. bool ConfigParserAPI::FillConsoleTitle(__ecount(cchBufferSize) LPWSTR buffer, size_t cchBufferSize, __in LPWSTR moduleName)
  19. {
  20. return false;
  21. }
  22. void ConfigParserAPI::DisplayInitialOutput(__in LPWSTR moduleName)
  23. {
  24. }
  25. LPCWSTR JsUtil::ExternalApi::GetFeatureKeyName()
  26. {
  27. return _u("");
  28. }
  29. #endif
  30. JsrtCallbackState::JsrtCallbackState(ThreadContext* currentThreadContext)
  31. {
  32. if (currentThreadContext == nullptr)
  33. {
  34. originalThreadContext = ThreadContext::GetContextForCurrentThread();
  35. }
  36. else
  37. {
  38. originalThreadContext = currentThreadContext;
  39. }
  40. originalJsrtContext = JsrtContext::GetCurrent();
  41. Assert(originalJsrtContext == nullptr || originalThreadContext == originalJsrtContext->GetScriptContext()->GetThreadContext());
  42. }
  43. JsrtCallbackState::~JsrtCallbackState()
  44. {
  45. if (originalJsrtContext != nullptr)
  46. {
  47. if (originalJsrtContext != JsrtContext::GetCurrent())
  48. {
  49. // This shouldn't fail as the context was previously set on the current thread.
  50. bool isSet = JsrtContext::TrySetCurrent(originalJsrtContext);
  51. if (!isSet)
  52. {
  53. Js::Throw::FatalInternalError();
  54. }
  55. }
  56. }
  57. else
  58. {
  59. bool isSet = ThreadContextTLSEntry::TrySetThreadContext(originalThreadContext);
  60. if (!isSet)
  61. {
  62. Js::Throw::FatalInternalError();
  63. }
  64. }
  65. }
  66. void JsrtCallbackState::ObjectBeforeCallectCallbackWrapper(JsObjectBeforeCollectCallback callback, void* object, void* callbackState, void* threadContext)
  67. {
  68. JsrtCallbackState scope(reinterpret_cast<ThreadContext*>(threadContext));
  69. callback(object, callbackState);
  70. }
  71. // todo: We need an interface for thread/process exit.
  72. // At the moment we do handle thread exit for non main threads on xplat
  73. // However, it could be nice/necessary to provide an interface to make sure
  74. // we cover additional edge cases.
  75. #if defined(CHAKRA_STATIC_LIBRARY) || !defined(_WIN32)
  76. #include "Core/ConfigParser.h"
  77. #include "Base/ThreadBoundThreadContextManager.h"
  78. #ifndef _WIN32
  79. #include <pthread.h>
  80. static pthread_key_t s_threadLocalDummy;
  81. #endif
  82. static THREAD_LOCAL bool s_threadWasEntered = false;
  83. _NOINLINE void DISPOSE_CHAKRA_CORE_THREAD(void *_)
  84. {
  85. free(_);
  86. ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
  87. }
  88. _NOINLINE bool InitializeProcess()
  89. {
  90. #if !defined(_WIN32)
  91. pthread_key_create(&s_threadLocalDummy, DISPOSE_CHAKRA_CORE_THREAD);
  92. #endif
  93. #if defined(CHAKRA_STATIC_LIBRARY)
  94. // Attention: shared library is handled under (see ChakraCore/ChakraCoreDllFunc.cpp)
  95. // todo: consolidate similar parts from shared and static library initialization
  96. #ifndef _WIN32
  97. PAL_InitializeChakraCore(0, NULL);
  98. #endif
  99. HMODULE mod = GetModuleHandleW(NULL);
  100. if (!ThreadContextTLSEntry::InitializeProcess() || !JsrtContext::Initialize())
  101. {
  102. return FALSE;
  103. }
  104. AutoSystemInfo::SaveModuleFileName(mod);
  105. #if defined(_M_IX86) && !defined(__clang__)
  106. // Enable SSE2 math functions in CRT if SSE2 is available
  107. #pragma prefast(suppress:6031, "We don't require SSE2, but will use it if available")
  108. _set_SSE2_enable(TRUE);
  109. #endif
  110. {
  111. CmdLineArgsParser parser;
  112. ConfigParser::ParseOnModuleLoad(parser, mod);
  113. }
  114. #ifdef ENABLE_JS_ETW
  115. EtwTrace::Register();
  116. #endif
  117. ValueType::Initialize();
  118. ThreadContext::GlobalInitialize();
  119. // Needed to make sure that only ChakraCore is loaded into the process
  120. // This is unnecessary on Linux since there aren't other flavors of
  121. // Chakra binaries that can be loaded into the process
  122. #ifdef _WIN32
  123. char16 *engine = szChakraCoreLock;
  124. if (::FindAtom(szChakraLock) != 0)
  125. {
  126. AssertMsg(FALSE, "Expecting to load chakracore.dll but process already loaded chakra.dll");
  127. Binary_Inconsistency_fatal_error();
  128. }
  129. lockedDll = ::AddAtom(engine);
  130. AssertMsg(lockedDll, "Failed to lock chakracore.dll");
  131. #endif // _WIN32
  132. #ifdef ENABLE_BASIC_TELEMETRY
  133. g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
  134. #endif
  135. #ifdef DYNAMIC_PROFILE_STORAGE
  136. DynamicProfileStorage::Initialize();
  137. #endif
  138. #endif // STATIC_LIBRARY
  139. return true;
  140. }
  141. _NOINLINE void VALIDATE_ENTER_CURRENT_THREAD()
  142. {
  143. // We do also initialize the process part here
  144. // This is thread safe by the standard
  145. // Let's hope compiler doesn't fail
  146. static bool _has_init = InitializeProcess();
  147. if (!_has_init) // do not assert this.
  148. {
  149. abort();
  150. }
  151. if (s_threadWasEntered) return;
  152. s_threadWasEntered = true;
  153. ThreadContextTLSEntry::InitializeThread();
  154. #ifdef HEAP_TRACK_ALLOC
  155. HeapAllocator::InitializeThread();
  156. #endif
  157. #ifndef _WIN32
  158. // put something into key to make sure destructor is going to be called
  159. pthread_setspecific(s_threadLocalDummy, malloc(1));
  160. #endif
  161. }
  162. #endif