JsrtRuntime.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 "JsrtRuntime.h"
  7. #include "jsrtHelper.h"
  8. #include "Base/ThreadContextTlsEntry.h"
  9. #include "Base/ThreadBoundThreadContextManager.h"
  10. JsrtRuntime::JsrtRuntime(ThreadContext * threadContext, bool useIdle, bool dispatchExceptions)
  11. {
  12. Assert(threadContext != NULL);
  13. this->threadContext = threadContext;
  14. this->contextList = NULL;
  15. this->collectCallback = NULL;
  16. this->beforeCollectCallback = NULL;
  17. this->callbackContext = NULL;
  18. this->allocationPolicyManager = threadContext->GetAllocationPolicyManager();
  19. this->useIdle = useIdle;
  20. this->dispatchExceptions = dispatchExceptions;
  21. if (useIdle)
  22. {
  23. this->threadService.Initialize(threadContext);
  24. }
  25. threadContext->SetJSRTRuntime(this);
  26. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  27. serializeByteCodeForLibrary = false;
  28. #endif
  29. #ifdef ENABLE_SCRIPT_DEBUGGING
  30. this->jsrtDebugManager = nullptr;
  31. #endif
  32. }
  33. JsrtRuntime::~JsrtRuntime()
  34. {
  35. HeapDelete(allocationPolicyManager);
  36. #ifdef ENABLE_SCRIPT_DEBUGGING
  37. if (this->jsrtDebugManager != nullptr)
  38. {
  39. HeapDelete(this->jsrtDebugManager);
  40. this->jsrtDebugManager = nullptr;
  41. }
  42. #endif
  43. }
  44. // This is called at process detach.
  45. // threadcontext created from runtime should not be destroyed in ThreadBoundThreadContext
  46. // we should clean them up at process detach only as runtime can be used in other threads
  47. // even after the current physical thread was destroyed.
  48. // This is called after ThreadBoundThreadContext are cleaned up, so the remaining items
  49. // in the globalthreadContext linklist should be for jsrt only.
  50. void JsrtRuntime::Uninitialize()
  51. {
  52. ThreadContext* currentThreadContext = ThreadContext::GetThreadContextList();
  53. ThreadContext* tmpThreadContext;
  54. while (currentThreadContext)
  55. {
  56. Assert(!currentThreadContext->IsScriptActive());
  57. JsrtRuntime* currentRuntime = static_cast<JsrtRuntime*>(currentThreadContext->GetJSRTRuntime());
  58. tmpThreadContext = currentThreadContext;
  59. currentThreadContext = currentThreadContext->Next();
  60. #ifdef CHAKRA_STATIC_LIBRARY
  61. // xplat-todo: Cleanup staticlib shutdown. This only shuts down threads.
  62. // Other closing contexts / finalizers having trouble with current
  63. // runtime/context.
  64. RentalThreadContextManager::DestroyThreadContext(tmpThreadContext);
  65. #else
  66. currentRuntime->CloseContexts();
  67. RentalThreadContextManager::DestroyThreadContext(tmpThreadContext);
  68. HeapDelete(currentRuntime);
  69. #endif
  70. }
  71. }
  72. void JsrtRuntime::CloseContexts()
  73. {
  74. while (this->contextList != NULL)
  75. {
  76. this->contextList->Dispose(false);
  77. // This will remove it from the list
  78. }
  79. }
  80. void JsrtRuntime::SetBeforeCollectCallback(JsBeforeCollectCallback beforeCollectCallback, void * callbackContext)
  81. {
  82. if (beforeCollectCallback != NULL)
  83. {
  84. if (this->collectCallback == NULL)
  85. {
  86. this->collectCallback = this->threadContext->AddRecyclerCollectCallBack(RecyclerCollectCallbackStatic, this);
  87. }
  88. this->beforeCollectCallback = beforeCollectCallback;
  89. this->callbackContext = callbackContext;
  90. }
  91. else
  92. {
  93. if (this->collectCallback != NULL)
  94. {
  95. this->threadContext->RemoveRecyclerCollectCallBack(this->collectCallback);
  96. this->collectCallback = NULL;
  97. }
  98. this->beforeCollectCallback = NULL;
  99. this->callbackContext = NULL;
  100. }
  101. }
  102. void JsrtRuntime::RecyclerCollectCallbackStatic(void * context, RecyclerCollectCallBackFlags flags)
  103. {
  104. if (flags & Collect_Begin)
  105. {
  106. JsrtRuntime * _this = reinterpret_cast<JsrtRuntime *>(context);
  107. try
  108. {
  109. JsrtCallbackState scope(reinterpret_cast<ThreadContext*>(_this->GetThreadContext()));
  110. _this->beforeCollectCallback(_this->callbackContext);
  111. }
  112. catch (...)
  113. {
  114. AssertMsg(false, "Unexpected non-engine exception.");
  115. }
  116. }
  117. }
  118. unsigned int JsrtRuntime::Idle()
  119. {
  120. return this->threadService.Idle();
  121. }
  122. #ifdef ENABLE_SCRIPT_DEBUGGING
  123. void JsrtRuntime::EnsureJsrtDebugManager()
  124. {
  125. if (this->jsrtDebugManager == nullptr)
  126. {
  127. this->jsrtDebugManager = HeapNew(JsrtDebugManager, this->threadContext);
  128. }
  129. Assert(this->jsrtDebugManager != nullptr);
  130. }
  131. void JsrtRuntime::DeleteJsrtDebugManager()
  132. {
  133. if (this->jsrtDebugManager != nullptr)
  134. {
  135. HeapDelete(this->jsrtDebugManager);
  136. this->jsrtDebugManager = nullptr;
  137. }
  138. }
  139. JsrtDebugManager * JsrtRuntime::GetJsrtDebugManager()
  140. {
  141. return this->jsrtDebugManager;
  142. }
  143. #if ENABLE_TTD
  144. uint32 JsrtRuntime::BPRegister_TTD(int64 bpID, Js::ScriptContext* scriptContext, Js::Utf8SourceInfo* utf8SourceInfo, uint32 line, uint32 column, BOOL* isNewBP)
  145. {
  146. TTDAssert(this->jsrtDebugManager != nullptr, "This needs to be setup before registering any breakpoints.");
  147. Js::BreakpointProbe* probe = this->jsrtDebugManager->SetBreakpointHelper_TTD(bpID, scriptContext, utf8SourceInfo, line, column, isNewBP);
  148. return probe->GetId();
  149. }
  150. void JsrtRuntime::BPDelete_TTD(uint32 bpID)
  151. {
  152. TTDAssert(this->jsrtDebugManager != nullptr, "This needs to be setup before deleting any breakpoints.");
  153. this->jsrtDebugManager->GetDebugDocumentManager()->RemoveBreakpoint(bpID);
  154. }
  155. void JsrtRuntime::BPClearDocument_TTD()
  156. {
  157. TTDAssert(this->jsrtDebugManager != nullptr, "This needs to be setup before deleting any breakpoints.");
  158. this->jsrtDebugManager->ClearBreakpointDebugDocumentDictionary();
  159. }
  160. #endif
  161. #endif