JsrtHelper.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. #if !defined(_WIN32) && !defined(__ANDROID__)
  7. #include <pthread.h>
  8. #endif
  9. #include "jsrtHelper.h"
  10. #include "Base/ThreadContextTlsEntry.h"
  11. #include "Base/VTuneChakraProfile.h"
  12. #ifdef DYNAMIC_PROFILE_STORAGE
  13. #include "Language/DynamicProfileStorage.h"
  14. #endif
  15. #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
  16. #include "Core/ConfigParser.h"
  17. #include "Base/ThreadBoundThreadContextManager.h"
  18. #ifdef CHAKRA_STATIC_LIBRARY
  19. bool ConfigParserAPI::FillConsoleTitle(__ecount(cchBufferSize) LPWSTR buffer, size_t cchBufferSize, __in LPWSTR moduleName)
  20. {
  21. return false;
  22. }
  23. void ConfigParserAPI::DisplayInitialOutput(__in LPWSTR moduleName)
  24. {
  25. }
  26. LPCWSTR JsUtil::ExternalApi::GetFeatureKeyName()
  27. {
  28. return _u("");
  29. }
  30. #endif // CHAKRA_STATIC_LIBRARY
  31. #endif
  32. JsrtCallbackState::JsrtCallbackState(ThreadContext* currentThreadContext)
  33. {
  34. if (currentThreadContext == nullptr)
  35. {
  36. originalThreadContext = ThreadContext::GetContextForCurrentThread();
  37. }
  38. else
  39. {
  40. originalThreadContext = currentThreadContext;
  41. }
  42. originalJsrtContext = JsrtContext::GetCurrent();
  43. Assert(originalJsrtContext == nullptr || originalThreadContext == originalJsrtContext->GetScriptContext()->GetThreadContext());
  44. }
  45. JsrtCallbackState::~JsrtCallbackState()
  46. {
  47. if (originalJsrtContext != nullptr)
  48. {
  49. if (originalJsrtContext != JsrtContext::GetCurrent())
  50. {
  51. // This shouldn't fail as the context was previously set on the current thread.
  52. bool isSet = JsrtContext::TrySetCurrent(originalJsrtContext);
  53. if (!isSet)
  54. {
  55. Js::Throw::FatalInternalError();
  56. }
  57. }
  58. }
  59. else
  60. {
  61. bool isSet = ThreadContextTLSEntry::TrySetThreadContext(originalThreadContext);
  62. if (!isSet)
  63. {
  64. Js::Throw::FatalInternalError();
  65. }
  66. }
  67. }
  68. void JsrtCallbackState::ObjectBeforeCallectCallbackWrapper(JsObjectBeforeCollectCallback callback, void* object, void* callbackState, void* threadContext)
  69. {
  70. JsrtCallbackState scope(reinterpret_cast<ThreadContext*>(threadContext));
  71. callback(object, callbackState);
  72. }
  73. #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
  74. void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
  75. {
  76. autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
  77. autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
  78. }
  79. #ifndef _WIN32
  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. // setup the cleanup
  94. // we do not track the main thread. When it exits do the cleanup below
  95. #ifdef CHAKRA_STATIC_LIBRARY
  96. atexit([]() {
  97. ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
  98. #ifdef DYNAMIC_PROFILE_STORAGE
  99. DynamicProfileStorage::Uninitialize();
  100. #endif
  101. JsrtRuntime::Uninitialize();
  102. // thread-bound entrypoint should be able to get cleanup correctly, however tlsentry
  103. // for current thread might be left behind if this thread was initialized.
  104. ThreadContextTLSEntry::CleanupThread();
  105. ThreadContextTLSEntry::CleanupProcess();
  106. });
  107. #endif
  108. #ifndef _WIN32
  109. PAL_InitializeChakraCore();
  110. #endif
  111. HMODULE mod = GetModuleHandleW(NULL);
  112. AutoSystemInfo::SaveModuleFileName(mod);
  113. #if defined(_M_IX86) && !defined(__clang__)
  114. // Enable SSE2 math functions in CRT if SSE2 is available
  115. #pragma prefast(suppress:6031, "We don't require SSE2, but will use it if available")
  116. _set_SSE2_enable(TRUE);
  117. #endif
  118. {
  119. CmdLineArgsParser parser;
  120. ConfigParser::ParseOnModuleLoad(parser, mod);
  121. }
  122. #if defined(ENABLE_JS_ETW) && !defined(ENABLE_JS_LTTNG)
  123. EtwTrace::Register();
  124. #endif
  125. #ifdef VTUNE_PROFILING
  126. VTuneChakraProfile::Register();
  127. #endif
  128. #if PERFMAP_TRACE_ENABLED
  129. PlatformAgnostic::PerfTrace::Register();
  130. #endif
  131. ValueType::Initialize();
  132. ThreadContext::GlobalInitialize();
  133. #ifdef ENABLE_BASIC_TELEMETRY
  134. g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
  135. #endif
  136. #ifdef DYNAMIC_PROFILE_STORAGE
  137. DynamicProfileStorage::Initialize();
  138. #endif
  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. #ifdef HEAP_TRACK_ALLOC
  154. HeapAllocator::InitializeThread();
  155. #endif
  156. #ifndef _WIN32
  157. // put something into key to make sure destructor is going to be called
  158. pthread_setspecific(s_threadLocalDummy, malloc(1));
  159. #endif
  160. }
  161. #endif