| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- // This files contains the declarations of BGParseManager and BGParseWorkItem and build upon the Job and
- // JobManager classes that do work on background threads. This enables the host to offload parser work
- // from the UI and execution that doesn't have strict thread dependencies. Thus, both classes are
- // multi-threaded; please see the definition of each function for expectations of which thread executes
- // the function.
- //
- // There are up to 3 threads involved per background parse. Here are the relevant BGParseManager functions
- // called from these three threads:
- //
- // Background/Network JobProcessor UI/Executing
- // Thread Thread Thread
- // | | |
- // QueueBackgroundParse | |
- // | | |
- // | Process |
- // | | |
- // | | GetParseResults
- // . . .
- // Note that the thread queueing the work can also be the UIT thread. Also, note that GetParseResults may
- // block the calling thread until the JobProcessor thread finishes processing the BGParseWorkItem that
- // contains the results.
- // Forward Declarations
- class BGParseWorkItem;
- namespace Js
- {
- struct Utf8SourceInfo;
- typedef void * Var;
- class JavascriptFunction;
- }
- // BGParseManager is the primary interface for background parsing. It uses a cookie to publicly track the data
- // involved per parse request.
- class BGParseManager sealed : public JsUtil::WaitableJobManager
- {
- public:
- BGParseManager();
- ~BGParseManager();
- static BGParseManager* GetBGParseManager();
- static void DeleteBGParseManager();
- static DWORD GetNextCookie();
- static DWORD IncCompleted();
- static DWORD IncFailed();
- HRESULT QueueBackgroundParse(LPCUTF8 pszSrc, size_t cbLength, char16 *fullPath, DWORD* dwBgParseCookie);
- HRESULT GetInputFromCookie(DWORD cookie, LPCUTF8* ppszSrc, size_t* pcbLength, WCHAR** sourceUrl);
- HRESULT GetParseResults(
- Js::ScriptContext* scriptContextUI,
- DWORD cookie,
- LPCUTF8 pszSrc,
- SRCINFO const * pSrcInfo,
- Js::FunctionBody** ppFunc,
- CompileScriptException* pse,
- size_t& srcLength,
- Js::Utf8SourceInfo* utf8SourceInfo,
- uint& sourceIndex
- );
- bool DiscardParseResults(DWORD cookie, void* buffer);
- virtual bool Process(JsUtil::Job *const job, JsUtil::ParallelThreadData *threadData) override;
- virtual void JobProcessed(JsUtil::Job *const job, const bool succeeded) override;
- virtual void JobProcessing(JsUtil::Job* job) override;
- // Defines needed for jobs.inl
- BGParseWorkItem* GetJob(BGParseWorkItem* workitem);
- bool WasAddedToJobProcessor(JsUtil::Job *const job) const;
- private:
- BGParseWorkItem * FindJob(DWORD dwCookie, bool waitForResults, bool removeJob);
- // BGParseWorkItem job can be in one of 3 states, based on which linked list it is in:
- // - queued - JobProcessor::jobs
- // - processing - BGParseManager::workitemsProcessing
- // - processed - BGParseManager::workitemsProcessed
- JsUtil::DoublyLinkedList<BGParseWorkItem> workitemsProcessing;
- JsUtil::DoublyLinkedList<BGParseWorkItem> workitemsProcessed;
- static DWORD s_lastCookie;
- static DWORD s_completed;
- static DWORD s_failed;
- static BGParseManager* s_BGParseManager;
- static CriticalSection s_staticMemberLock;
- };
- // BGParseWorkItem is a helper class to BGParseManager that caches the input data from the calling thread
- // to parse on the background thread and caches serialized bytecode so that bytecode can be deserialized
- // on the appropriate thread.
- class BGParseWorkItem sealed : public JsUtil::Job
- {
- public:
- BGParseWorkItem(
- BGParseManager* manager,
- const byte* script,
- size_t cb,
- char16 *fullPath
- );
- ~BGParseWorkItem();
- void ParseUTF8Core(Js::ScriptContext* scriptContext);
- HRESULT DeserializeParseResults(
- Js::ScriptContext* scriptContextUI,
- LPCUTF8 pszSrc,
- SRCINFO const * pSrcInfo,
- Js::Utf8SourceInfo* utf8SourceInfo,
- Js::FunctionBody** functionBodyReturn,
- size_t& srcLength,
- uint& sourceIndex
- );
- void TransferCSE(CompileScriptException* pse);
- void CreateCompletionEvent();
- void WaitForCompletion();
- void JobProcessed(const bool succeeded);
- void Discard() { discarded = true; }
- bool IsDiscarded() const { return discarded; }
- DWORD GetCookie() const { return cookie; }
- const byte* GetScriptSrc() const { return script; }
- size_t GetScriptLength() const { return cb; }
- WCHAR* GetScriptPath() const { return path; }
- private:
- // This cookie is the public identifier for this parser work
- DWORD cookie;
- // Input data
- const byte* script;
- size_t cb;
- BSTR path;
- // Parse state
- CompileScriptException cse;
- HRESULT parseHR;
- size_t parseSourceLength;
- Event* complete;
-
- // True when this workitem was discarded while processing. This instance
- // will free itself after it has been processed.
- bool discarded;
- // Output data
- byte * bufferReturn;
- DWORD bufferReturnBytes;
- };
|