JsrtRuntime.cpp 5.7 KB

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