BGParseManager.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. #pragma once
  6. // This files contains the declarations of BGParseManager and BGParseWorkItem and build upon the Job and
  7. // JobManager classes that do work on background threads. This enables the host to offload parser work
  8. // from the UI and execution that doesn't have strict thread dependencies. Thus, both classes are
  9. // multi-threaded; please see the definition of each function for expectations of which thread executes
  10. // the function.
  11. //
  12. // There are up to 3 threads involved per background parse. Here are the relevant BGParseManager functions
  13. // called from these three threads:
  14. //
  15. // Background/Network JobProcessor UI/Executing
  16. // Thread Thread Thread
  17. // | | |
  18. // QueueBackgroundParse | |
  19. // | | |
  20. // | Process |
  21. // | | |
  22. // | | GetParseResults
  23. // . . .
  24. // Note that the thread queueing the work can also be the UIT thread. Also, note that GetParseResults may
  25. // block the calling thread until the JobProcessor thread finishes processing the BGParseWorkItem that
  26. // contains the results.
  27. // Forward Declarations
  28. class BGParseWorkItem;
  29. namespace Js
  30. {
  31. struct Utf8SourceInfo;
  32. typedef void * Var;
  33. class JavascriptFunction;
  34. }
  35. // BGParseManager is the primary interface for background parsing. It uses a cookie to publicly track the data
  36. // involved per parse request.
  37. class BGParseManager sealed : public JsUtil::WaitableJobManager
  38. {
  39. public:
  40. BGParseManager();
  41. ~BGParseManager();
  42. static BGParseManager* GetBGParseManager();
  43. static void DeleteBGParseManager();
  44. static DWORD GetNextCookie();
  45. static DWORD IncCompleted();
  46. static DWORD IncFailed();
  47. HRESULT QueueBackgroundParse(LPCUTF8 pszSrc, size_t cbLength, char16 *fullPath, DWORD* dwBgParseCookie);
  48. HRESULT GetInputFromCookie(DWORD cookie, LPCUTF8* ppszSrc, size_t* pcbLength);
  49. HRESULT GetParseResults(
  50. Js::ScriptContext* scriptContextUI,
  51. DWORD cookie,
  52. LPCUTF8 pszSrc,
  53. SRCINFO const * pSrcInfo,
  54. Js::ParseableFunctionInfo** ppFunc,
  55. CompileScriptException* pse,
  56. size_t& srcLength,
  57. Js::Utf8SourceInfo* utf8SourceInfo,
  58. uint& sourceIndex
  59. );
  60. bool DiscardParseResults(DWORD cookie, void* buffer);
  61. virtual bool Process(JsUtil::Job *const job, JsUtil::ParallelThreadData *threadData) override;
  62. virtual void JobProcessed(JsUtil::Job *const job, const bool succeeded) override;
  63. virtual void JobProcessing(JsUtil::Job* job) override;
  64. // Defines needed for jobs.inl
  65. BGParseWorkItem* GetJob(BGParseWorkItem* workitem);
  66. bool WasAddedToJobProcessor(JsUtil::Job *const job) const;
  67. private:
  68. BGParseWorkItem * FindJob(DWORD dwCookie, bool waitForResults, bool removeJob);
  69. // BGParseWorkItem job can be in one of 3 states, based on which linked list it is in:
  70. // - queued - JobProcessor::jobs
  71. // - processing - BGParseManager::workitemsProcessing
  72. // - processed - BGParseManager::workitemsProcessed
  73. JsUtil::DoublyLinkedList<BGParseWorkItem> workitemsProcessing;
  74. JsUtil::DoublyLinkedList<BGParseWorkItem> workitemsProcessed;
  75. static DWORD s_lastCookie;
  76. static DWORD s_completed;
  77. static DWORD s_failed;
  78. static BGParseManager* s_BGParseManager;
  79. static CriticalSection s_staticMemberLock;
  80. };
  81. // BGParseWorkItem is a helper class to BGParseManager that caches the input data from the calling thread
  82. // to parse on the background thread and caches serialized bytecode so that bytecode can be deserialized
  83. // on the appropriate thread.
  84. class BGParseWorkItem sealed : public JsUtil::Job
  85. {
  86. public:
  87. BGParseWorkItem(
  88. BGParseManager* manager,
  89. const byte* script,
  90. size_t cb,
  91. char16 *fullPath
  92. );
  93. ~BGParseWorkItem();
  94. void ParseUTF8Core(Js::ScriptContext* scriptContext);
  95. HRESULT DeserializeParseResults(
  96. Js::ScriptContext* scriptContextUI,
  97. LPCUTF8 pszSrc,
  98. SRCINFO const * pSrcInfo,
  99. Js::Utf8SourceInfo* utf8SourceInfo,
  100. Js::FunctionBody** functionBodyReturn,
  101. size_t& srcLength,
  102. uint& sourceIndex
  103. );
  104. void TransferCSE(CompileScriptException* pse);
  105. void CreateCompletionEvent();
  106. void WaitForCompletion();
  107. void JobProcessed(const bool succeeded);
  108. void Discard() { discarded = true; }
  109. bool IsDiscarded() const { return discarded; }
  110. DWORD GetCookie() const { return cookie; }
  111. const byte* GetScriptSrc() const { return script; }
  112. size_t GetScriptLength() const { return cb; }
  113. private:
  114. // This cookie is the public identifier for this parser work
  115. DWORD cookie;
  116. // Input data
  117. const byte* script;
  118. size_t cb;
  119. BSTR path;
  120. // Parse state
  121. CompileScriptException cse;
  122. HRESULT parseHR;
  123. size_t parseSourceLength;
  124. Event* complete;
  125. // True when this workitem was discarded while processing. This instance
  126. // will free itself after it has been processed.
  127. bool discarded;
  128. // Output data
  129. byte * bufferReturn;
  130. DWORD bufferReturnBytes;
  131. };