| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #if !defined(_WIN32)
- #include <pthread.h>
- #endif
- #include "JsrtPch.h"
- #include "jsrtHelper.h"
- #include "Base/ThreadContextTlsEntry.h"
- #ifdef DYNAMIC_PROFILE_STORAGE
- #include "Language/DynamicProfileStorage.h"
- #endif
- #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
- #include "Core/ConfigParser.h"
- #include "Base/ThreadBoundThreadContextManager.h"
- #ifdef CHAKRA_STATIC_LIBRARY
- bool ConfigParserAPI::FillConsoleTitle(__ecount(cchBufferSize) LPWSTR buffer, size_t cchBufferSize, __in LPWSTR moduleName)
- {
- return false;
- }
- void ConfigParserAPI::DisplayInitialOutput(__in LPWSTR moduleName)
- {
- }
- LPCWSTR JsUtil::ExternalApi::GetFeatureKeyName()
- {
- return _u("");
- }
- #endif // CHAKRA_STATIC_LIBRARY
- #endif
- JsrtCallbackState::JsrtCallbackState(ThreadContext* currentThreadContext)
- {
- if (currentThreadContext == nullptr)
- {
- originalThreadContext = ThreadContext::GetContextForCurrentThread();
- }
- else
- {
- originalThreadContext = currentThreadContext;
- }
- originalJsrtContext = JsrtContext::GetCurrent();
- Assert(originalJsrtContext == nullptr || originalThreadContext == originalJsrtContext->GetScriptContext()->GetThreadContext());
- }
- JsrtCallbackState::~JsrtCallbackState()
- {
- if (originalJsrtContext != nullptr)
- {
- if (originalJsrtContext != JsrtContext::GetCurrent())
- {
- // This shouldn't fail as the context was previously set on the current thread.
- bool isSet = JsrtContext::TrySetCurrent(originalJsrtContext);
- if (!isSet)
- {
- Js::Throw::FatalInternalError();
- }
- }
- }
- else
- {
- bool isSet = ThreadContextTLSEntry::TrySetThreadContext(originalThreadContext);
- if (!isSet)
- {
- Js::Throw::FatalInternalError();
- }
- }
- }
- void JsrtCallbackState::ObjectBeforeCallectCallbackWrapper(JsObjectBeforeCollectCallback callback, void* object, void* callbackState, void* threadContext)
- {
- JsrtCallbackState scope(reinterpret_cast<ThreadContext*>(threadContext));
- callback(object, callbackState);
- }
- #if !defined(_WIN32) || defined(CHAKRA_STATIC_LIBRARY)
- void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
- {
- autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
- autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
- }
- #ifndef _WIN32
- static pthread_key_t s_threadLocalDummy;
- #endif
- static THREAD_LOCAL bool s_threadWasEntered = false;
- _NOINLINE void DISPOSE_CHAKRA_CORE_THREAD(void *_)
- {
- free(_);
- ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
- }
- _NOINLINE bool InitializeProcess()
- {
- #if !defined(_WIN32)
- pthread_key_create(&s_threadLocalDummy, DISPOSE_CHAKRA_CORE_THREAD);
- #endif
- // setup the cleanup
- // we do not track the main thread. When it exits do the cleanup below
- #ifdef CHAKRA_STATIC_LIBRARY
- atexit([]() {
- ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
- JsrtRuntime::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();
- });
- #endif
- #ifndef _WIN32
- PAL_InitializeChakraCore(0, NULL);
- #endif
- HMODULE mod = GetModuleHandleW(NULL);
- AutoSystemInfo::SaveModuleFileName(mod);
- #if defined(_M_IX86) && !defined(__clang__)
- // 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
- {
- CmdLineArgsParser parser;
- ConfigParser::ParseOnModuleLoad(parser, mod);
- }
- #ifdef ENABLE_JS_ETW
- EtwTrace::Register();
- #endif
- ValueType::Initialize();
- ThreadContext::GlobalInitialize();
- #ifdef ENABLE_BASIC_TELEMETRY
- g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
- #endif
- #ifdef DYNAMIC_PROFILE_STORAGE
- DynamicProfileStorage::Initialize();
- #endif
- return true;
- }
- _NOINLINE void VALIDATE_ENTER_CURRENT_THREAD()
- {
- // We do also initialize the process part here
- // This is thread safe by the standard
- // Let's hope compiler doesn't fail
- static bool _has_init = InitializeProcess();
- if (!_has_init) // do not assert this.
- {
- abort();
- }
- if (s_threadWasEntered) return;
- s_threadWasEntered = true;
- #ifdef HEAP_TRACK_ALLOC
- HeapAllocator::InitializeThread();
- #endif
- #ifndef _WIN32
- // put something into key to make sure destructor is going to be called
- pthread_setspecific(s_threadLocalDummy, malloc(1));
- #endif
- }
- #endif
|