JsrtHelper.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. #ifdef DYNAMIC_PROFILE_STORAGE
  12. #include "Language/DynamicProfileStorage.h"
  13. #endif
  14. #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
  15. #include "Core/ConfigParser.h"
  16. #include "Base/ThreadBoundThreadContextManager.h"
  17. #ifdef CHAKRA_STATIC_LIBRARY
  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 // CHAKRA_STATIC_LIBRARY
  30. #endif
  31. JsrtCallbackState::JsrtCallbackState(ThreadContext* currentThreadContext)
  32. {
  33. if (currentThreadContext == nullptr)
  34. {
  35. originalThreadContext = ThreadContext::GetContextForCurrentThread();
  36. }
  37. else
  38. {
  39. originalThreadContext = currentThreadContext;
  40. }
  41. originalJsrtContext = JsrtContext::GetCurrent();
  42. Assert(originalJsrtContext == nullptr || originalThreadContext == originalJsrtContext->GetScriptContext()->GetThreadContext());
  43. }
  44. JsrtCallbackState::~JsrtCallbackState()
  45. {
  46. if (originalJsrtContext != nullptr)
  47. {
  48. if (originalJsrtContext != JsrtContext::GetCurrent())
  49. {
  50. // This shouldn't fail as the context was previously set on the current thread.
  51. bool isSet = JsrtContext::TrySetCurrent(originalJsrtContext);
  52. if (!isSet)
  53. {
  54. Js::Throw::FatalInternalError();
  55. }
  56. }
  57. }
  58. else
  59. {
  60. bool isSet = ThreadContextTLSEntry::TrySetThreadContext(originalThreadContext);
  61. if (!isSet)
  62. {
  63. Js::Throw::FatalInternalError();
  64. }
  65. }
  66. }
  67. void JsrtCallbackState::ObjectBeforeCallectCallbackWrapper(JsObjectBeforeCollectCallback callback, void* object, void* callbackState, void* threadContext)
  68. {
  69. JsrtCallbackState scope(reinterpret_cast<ThreadContext*>(threadContext));
  70. callback(object, callbackState);
  71. }
  72. #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
  73. void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
  74. {
  75. autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
  76. autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
  77. }
  78. #ifndef _WIN32
  79. static pthread_key_t s_threadLocalDummy;
  80. #endif
  81. static THREAD_LOCAL bool s_threadWasEntered = false;
  82. _NOINLINE void DISPOSE_CHAKRA_CORE_THREAD(void *_)
  83. {
  84. free(_);
  85. ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
  86. }
  87. _NOINLINE bool InitializeProcess()
  88. {
  89. #if !defined(_WIN32)
  90. pthread_key_create(&s_threadLocalDummy, DISPOSE_CHAKRA_CORE_THREAD);
  91. #endif
  92. // setup the cleanup
  93. // we do not track the main thread. When it exits do the cleanup below
  94. #ifdef CHAKRA_STATIC_LIBRARY
  95. atexit([]() {
  96. ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
  97. JsrtRuntime::Uninitialize();
  98. // thread-bound entrypoint should be able to get cleanup correctly, however tlsentry
  99. // for current thread might be left behind if this thread was initialized.
  100. ThreadContextTLSEntry::CleanupThread();
  101. ThreadContextTLSEntry::CleanupProcess();
  102. });
  103. #endif
  104. #ifndef _WIN32
  105. PAL_InitializeChakraCore(0, NULL);
  106. #endif
  107. HMODULE mod = GetModuleHandleW(NULL);
  108. AutoSystemInfo::SaveModuleFileName(mod);
  109. #if defined(_M_IX86) && !defined(__clang__)
  110. // Enable SSE2 math functions in CRT if SSE2 is available
  111. #pragma prefast(suppress:6031, "We don't require SSE2, but will use it if available")
  112. _set_SSE2_enable(TRUE);
  113. #endif
  114. {
  115. CmdLineArgsParser parser;
  116. ConfigParser::ParseOnModuleLoad(parser, mod);
  117. }
  118. #ifdef ENABLE_JS_ETW
  119. EtwTrace::Register();
  120. #endif
  121. ValueType::Initialize();
  122. ThreadContext::GlobalInitialize();
  123. #ifdef ENABLE_BASIC_TELEMETRY
  124. g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
  125. #endif
  126. #ifdef DYNAMIC_PROFILE_STORAGE
  127. DynamicProfileStorage::Initialize();
  128. #endif
  129. return true;
  130. }
  131. _NOINLINE void VALIDATE_ENTER_CURRENT_THREAD()
  132. {
  133. // We do also initialize the process part here
  134. // This is thread safe by the standard
  135. // Let's hope compiler doesn't fail
  136. static bool _has_init = InitializeProcess();
  137. if (!_has_init) // do not assert this.
  138. {
  139. abort();
  140. }
  141. if (s_threadWasEntered) return;
  142. s_threadWasEntered = true;
  143. #ifdef HEAP_TRACK_ALLOC
  144. HeapAllocator::InitializeThread();
  145. #endif
  146. #ifndef _WIN32
  147. // put something into key to make sure destructor is going to be called
  148. pthread_setspecific(s_threadLocalDummy, malloc(1));
  149. #endif
  150. }
  151. #endif