| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994 |
- //-------------------------------------------------------------------------------------------------------
- // 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
- #if defined(_WIN32) && defined(ENABLE_SCRIPT_PROFILING)
- #include "activprof.h"
- #endif
- #if DBG || ENABLE_REGEX_CONFIG_OPTIONS || defined(PROFILE_STRINGS)
- #define NEED_MISC_ALLOCATOR
- #endif
- #define BuiltInFunctionsScriptId 0
- using namespace PlatformAgnostic;
- class NativeCodeGenerator;
- class BackgroundParser;
- class BGParseManager;
- struct IActiveScriptDirect;
- namespace Js
- {
- #ifdef ENABLE_BASIC_TELEMETRY
- class ScriptContextTelemetry;
- #endif
- class ScriptContext;
- class ScriptEditQuery;
- class MutationBreakpoint;
- class StringProfiler;
- class DebugContext;
- struct HaltCallback;
- struct DebuggerOptionsCallback;
- class ModuleRecordBase;
- class SimpleDataCacheWrapper;
- }
- // Created for every source buffer passed by host.
- // This structure has all the details.
- class SRCINFO
- {
- // We currently don't free SRCINFO object so we don't want to add extra variables here.
- // In future, when we do make it freeable and will be able to allocate more than one per Module,
- // we can move variables m_isGlobalFunc and m_isEval from FunctionBody.cpp here.
- public:
- Field(SourceContextInfo *) sourceContextInfo;
- Field(ULONG) dlnHost; // Line number passed to ParseScriptText
- Field(ULONG) ulColumnHost; // Column number on the line where the parse script text started
- Field(ULONG) lnMinHost; // Line offset of first host-supplied line
- Field(ULONG) ichMinHost; // Range of host supplied characters
- Field(ULONG) ichLimHost;
- Field(ULONG) ulCharOffset; // Char offset of the source text relative to the document. (Populated using IActiveScriptContext)
- Field(Js::ModuleID) moduleID;
- Field(ULONG) grfsi;
- static SRCINFO* Copy(Recycler* recycler, const SRCINFO* srcInfo)
- {
- SRCINFO* copySrcInfo = RecyclerNew(recycler, SRCINFO, *srcInfo);
- return copySrcInfo;
- }
- SRCINFO()
- {
- }
- SRCINFO(const SRCINFO& other)
- :sourceContextInfo(other.sourceContextInfo),
- dlnHost(other.dlnHost),
- ulColumnHost(other.ulColumnHost),
- lnMinHost(other.lnMinHost),
- ichMinHost(other.ichMinHost),
- ichLimHost(other.ichLimHost),
- ulCharOffset(other.ulCharOffset),
- moduleID(other.moduleID),
- grfsi(other.grfsi)
- {
- }
- SRCINFO(
- SourceContextInfo*sourceContextInfo,
- ULONG dlnHost,
- ULONG ulColumnHost,
- ULONG lnMinHost,
- ULONG ichMinHost,
- ULONG ichLimHost,
- ULONG ulCharOffset,
- Js::ModuleID moduleID,
- ULONG grfsi
- ):sourceContextInfo(sourceContextInfo),
- dlnHost(dlnHost),
- ulColumnHost(ulColumnHost),
- lnMinHost(lnMinHost),
- ichMinHost(ichMinHost),
- ichLimHost(ichLimHost),
- ulCharOffset(ulCharOffset),
- moduleID(moduleID),
- grfsi(grfsi)
- {
- }
- };
- struct CustomExternalObjectOperations
- {
- size_t offsetOfOperationsUsage;
- DWORD operationFlagEquals;
- DWORD operationFlagStrictEquals;
- };
- enum ExternalJitData
- {
- ExternalJitData_CustomExternalObjectOperations
- };
- enum LoadScriptFlag
- {
- LoadScriptFlag_None = 0x0,
- LoadScriptFlag_Expression = 0x1, // the script returns a value.
- LoadScriptFlag_disableDeferredParse = 0x2, // do not defer-parse the code.
- LoadScriptFlag_isByteCodeBufferForLibrary = 0x4, // for bytecode buffer
- LoadScriptFlag_disableAsmJs = 0x8, // disable parse as asmjs. The code is not conform to asmjs requirement.
- LoadScriptFlag_Module = 0x10, // input script is module code.
- LoadScriptFlag_isFunction = 0x20, // input script is in a function scope, not global code.
- LoadScriptFlag_Utf8Source = 0x40, // input buffer is utf8 encoded.
- LoadScriptFlag_LibraryCode = 0x80, // for debugger, indicating 'not my code'
- LoadScriptFlag_ExternalArrayBuffer = 0x100, // for ExternalArrayBuffer
- LoadScriptFlag_CreateParserState = 0x200, // create the parser state cache while parsing.
- LoadScriptFlag_StrictMode = 0x400 // parse using strict mode semantics
- };
- enum class ScriptContextPrivilegeLevel
- {
- Low,
- Medium,
- High
- };
- #ifdef INLINE_CACHE_STATS
- // Used to store inline cache stats
- struct InlineCacheData
- {
- uint hits;
- uint misses;
- uint collisions;
- bool isGetCache;
- Js::PropertyId propertyId;
- InlineCacheData() : hits(0), misses(0), collisions(0), isGetCache(false), propertyId(Js::PropertyIds::_none) { }
- };
- #endif
- class HostScriptContext
- {
- public:
- HostScriptContext(Js::ScriptContext* inScriptContext) { this->scriptContext = inScriptContext; }
- virtual void Delete() = 0;
- virtual HRESULT GetPreviousHostScriptContext(__deref_out HostScriptContext** ppUnkCaller) = 0;
- virtual HRESULT PushHostScriptContext() = 0;
- virtual void PopHostScriptContext() = 0;
- virtual HRESULT SetCaller(IUnknown *punkNew, IUnknown **ppunkPrev) = 0;
- virtual HRESULT GetDispatchExCaller(__deref_out void** dispatchExCaller) = 0;
- virtual void ReleaseDispatchExCaller(__in void* dispatchExCaler) = 0;
- virtual Js::ModuleRoot * GetModuleRoot(int moduleID) = 0;
- virtual HRESULT CheckCrossDomainScriptContext(__in Js::ScriptContext* scriptContext) = 0;
- virtual HRESULT GetHostContextUrl(__in DWORD_PTR hostSourceContext, __out BSTR& pUrl) = 0;
- virtual BOOL HasCaller() = 0;
- virtual void CleanDynamicCodeCache() = 0;
- virtual HRESULT VerifyDOMSecurity(Js::ScriptContext* targetContext, Js::Var obj) = 0;
- virtual HRESULT CheckEvalRestriction() = 0;
- virtual HRESULT HostExceptionFromHRESULT(HRESULT hr, Js::Var* outError) = 0;
- virtual HRESULT GetExternalJitData(ExternalJitData id, void *data) = 0;
- virtual HRESULT SetDispatchInvoke(Js::JavascriptMethod dispatchInvoke) = 0;
- virtual HRESULT EnqueuePromiseTask(Js::Var varTask) = 0;
- virtual HRESULT FetchImportedModule(Js::ModuleRecordBase* referencingModule, LPCOLESTR specifier, Js::ModuleRecordBase** dependentModuleRecord) = 0;
- virtual HRESULT FetchImportedModuleFromScript(DWORD_PTR dwReferencingSourceContext, LPCOLESTR specifier, Js::ModuleRecordBase** dependentModuleRecord) = 0;
- virtual HRESULT NotifyHostAboutModuleReady(Js::ModuleRecordBase* referencingModule, Js::Var exceptionVar) = 0;
- virtual HRESULT InitializeImportMeta(Js::ModuleRecordBase* referencingModule, Js::Var importMetaObject) = 0;
- virtual bool ReportModuleCompletion(Js::ModuleRecordBase* module, Js::Var exception) = 0;
- virtual HRESULT ThrowIfFailed(HRESULT hr) = 0;
- Js::ScriptContext* GetScriptContext() { return scriptContext; }
- virtual bool SetCrossSiteForFunctionType(Js::JavascriptFunction * function) = 0;
- #if DBG_DUMP || defined(PROFILE_EXEC) || defined(PROFILE_MEM)
- virtual void EnsureParentInfo(Js::ScriptContext* scriptContext = NULL) = 0;
- #endif
- #if DBG
- virtual bool IsHostCrossSiteThunk(Js::JavascriptMethod address) = 0;
- #endif
- private:
- Js::ScriptContext* scriptContext;
- };
- class HostStream
- {
- public:
- virtual byte * ExtendBuffer(byte *oldBuffer, size_t newSize, size_t *allocatedSize) = 0;
- virtual bool WriteHostObject(void* data) = 0;
- };
- class HostReadStream
- {
- public:
- virtual Js::Var ReadHostObject() = 0;
- };
- #if ENABLE_TTD
- typedef void (CALLBACK *JsTTDOnScriptLoadCallback)(FinalizableObject* hostContext, Js::FunctionBody* body, Js::Utf8SourceInfo* utf8SourceInfo, CompileScriptException* compileException, bool notify);
- typedef uint32 (CALLBACK *JsTTDOnBPRegisterCallback)(void* hostRuntime, int64 bpID, Js::ScriptContext* scriptContext, Js::Utf8SourceInfo* utf8SourceInfo, uint32 line, uint32 column, BOOL* isNewBP);
- typedef void (CALLBACK *JsTTDOnBPDeleteCallback)(void* hostRuntime, uint32 bpID);
- typedef void (CALLBACK *JsTTDOnBPClearDocumentCallback)(void* hostRuntime);
- //A class that we use to pass in a functor from the host when we need to inform it about something we are doing
- class HostScriptContextCallbackFunctor
- {
- public:
- FinalizableObject* HostContext;
- void* HostRuntime;
- JsTTDOnScriptLoadCallback pfOnScriptLoadCallback;
- JsTTDOnBPRegisterCallback pfOnBPRegisterCallback;
- JsTTDOnBPDeleteCallback pfOnBPDeleteCallback;
- JsTTDOnBPClearDocumentCallback pfOnBPClearDocumentCallback;
- HostScriptContextCallbackFunctor()
- : HostContext(nullptr), HostRuntime(nullptr), pfOnScriptLoadCallback(nullptr), pfOnBPRegisterCallback(nullptr), pfOnBPDeleteCallback(nullptr), pfOnBPClearDocumentCallback(nullptr)
- {
- ;
- }
- HostScriptContextCallbackFunctor(FinalizableObject* hostContext, void* hostRuntime, JsTTDOnScriptLoadCallback callbackOnScriptLoad, JsTTDOnBPRegisterCallback callbackOnBPRegister, JsTTDOnBPDeleteCallback callbackOnBPDelete, JsTTDOnBPClearDocumentCallback callbackOnBPClearDocument)
- : HostContext(hostContext), HostRuntime(hostRuntime), pfOnScriptLoadCallback(callbackOnScriptLoad), pfOnBPRegisterCallback(callbackOnBPRegister), pfOnBPDeleteCallback(callbackOnBPDelete), pfOnBPClearDocumentCallback(callbackOnBPClearDocument)
- {
- ;
- }
- };
- #endif
- namespace Js
- {
- #pragma pack(push, 1)
- struct StackFrameInfo
- {
- StackFrameInfo() { }
- StackFrameInfo(DWORD_PTR _scriptContextID
- , UINT32 _sourceLocationLineNumber
- , UINT32 _sourceLocationColumnNumber
- , UINT32 _methodIDOrNameIndex
- , UINT8 _isFrameIndex)
- : scriptContextID(_scriptContextID)
- , sourceLocationLineNumber(_sourceLocationLineNumber)
- , sourceLocationColumnNumber(_sourceLocationColumnNumber)
- , methodIDOrNameIndex(_methodIDOrNameIndex)
- , isFrameIndex(_isFrameIndex)
- { }
- DWORD_PTR scriptContextID;
- UINT32 sourceLocationLineNumber;
- UINT32 sourceLocationColumnNumber;
- UINT32 methodIDOrNameIndex;
- UINT8 isFrameIndex;
- };
- #pragma pack(pop)
- class ScriptConfiguration
- {
- public:
- ScriptConfiguration(const ThreadConfiguration * const threadConfig, const bool isOptimizedForManyInstances) :
- NoNative(Configuration::Global.flags.NoNative),
- NoDynamicThunks(false),
- isOptimizedForManyInstances(isOptimizedForManyInstances),
- threadConfig(threadConfig)
- {
- }
- #define FORWARD_THREAD_CONFIG(flag) inline bool flag() const { return threadConfig->flag(); }
- #define FLAG(threadFlag, globalFlag) FORWARD_THREAD_CONFIG(threadFlag)
- #define FLAG_RELEASE(threadFlag, globalFlag) FORWARD_THREAD_CONFIG(threadFlag)
- #include "../Base/ThreadConfigFlagsList.h"
- #undef FLAG_RELEASE
- #undef FLAG
- #undef FORWARD_THREAD_CONFIG
- void ForceNoDynamicThunks() { this->NoDynamicThunks = true; }
- bool IsNoDynamicThunks() const { return this->NoDynamicThunks; }
- void ForceNoNative() { this->NoNative = true; }
- void ForceNative() { this->NoNative = false; }
- bool IsNoNative() const { return this->NoNative; }
- void SetCanOptimizeGlobalLookupFlag(BOOL f){ this->fCanOptimizeGlobalLookup = f;}
- BOOL CanOptimizeGlobalLookup() const { return this->fCanOptimizeGlobalLookup;}
- bool IsOptimizedForManyInstances() const { return isOptimizedForManyInstances; }
- void CopyFrom(ScriptConfiguration& other)
- {
- this->NoNative = other.NoNative;
- this->fCanOptimizeGlobalLookup = other.fCanOptimizeGlobalLookup;
- }
- private:
- // Per script configurations
- bool NoNative;
- bool NoDynamicThunks;
- BOOL fCanOptimizeGlobalLookup;
- const bool isOptimizedForManyInstances;
- const ThreadConfiguration * const threadConfig;
- };
- struct ScriptEntryExitRecord
- {
- bool hasCaller : 1;
- bool hasReentered : 1;
- #if DBG_DUMP
- bool isCallRoot : 1;
- #endif
- #if DBG || defined(PROFILE_EXEC)
- bool leaveForHost : 1;
- #endif
- #if DBG
- bool leaveForAsyncHostOperation : 1;
- #endif
- #ifdef CHECK_STACKWALK_EXCEPTION
- bool ignoreStackWalkException: 1;
- #endif
- Js::ImplicitCallFlags savedImplicitCallFlags;
- void * returnAddrOfScriptEntryFunction;
- void * addrOfReturnAddrOfScriptEntryFunction;
- void * frameIdOfScriptExitFunction; // the frameAddres in x86, the return address in amd64/arm_soc
- ScriptContext * scriptContext;
- struct ScriptEntryExitRecord * next;
- #if defined(_M_IX86) && defined(DBG)
- void * scriptEntryFS0;
- #endif
- #ifdef EXCEPTION_CHECK
- ExceptionType handledExceptionType;
- #endif
- };
- #if ENABLE_NATIVE_CODEGEN
- /*
- * This class caches jitted func address ranges.
- * This is to facilitate WER scenarios to use this cache for checking native addresses.
- */
- class JITPageAddrToFuncRangeCache
- {
- public:
- typedef JsUtil::BaseDictionary<void *, uint, HeapAllocator> RangeMap;
- typedef JsUtil::BaseDictionary<void *, RangeMap*, HeapAllocator, PrimeSizePolicy> JITPageAddrToFuncRangeMap;
- typedef JsUtil::BaseDictionary<void *, uint, HeapAllocator, PrimeSizePolicy> LargeJITFuncAddrToSizeMap;
- private:
- JITPageAddrToFuncRangeMap * jitPageAddrToFuncRangeMap;
- LargeJITFuncAddrToSizeMap * largeJitFuncToSizeMap;
- static CriticalSection cs;
- public:
- JITPageAddrToFuncRangeCache() :jitPageAddrToFuncRangeMap(nullptr), largeJitFuncToSizeMap(nullptr) {}
- ~JITPageAddrToFuncRangeCache()
- {
- ClearCache();
- }
- void ClearCache();
- void AddFuncRange(void * address, uint bytes);
- void RemoveFuncRange(void * address);
- void * GetPageAddr(void * address);
- bool IsNativeAddr(void * address);
- JITPageAddrToFuncRangeMap * GetJITPageAddrToFuncRangeMap();
- LargeJITFuncAddrToSizeMap * GetLargeJITFuncAddrToSizeMap();
- static CriticalSection * GetCriticalSection() { return &cs; }
- };
- #endif
- class ScriptContext : public ScriptContextBase, public ScriptContextInfo
- {
- friend class LowererMD;
- friend class RemoteScriptContext;
- friend class GlobalObject; // InitializeCache
- friend class SourceTextModuleRecord; // for module bytecode gen.
- #if ENABLE_NATIVE_CODEGEN
- public:
- static DWORD GetThreadContextOffset() { return offsetof(ScriptContext, threadContext); }
- static DWORD GetOptimizationOverridesOffset() { return offsetof(ScriptContext, optimizationOverrides); }
- static DWORD GetRecyclerOffset() { return offsetof(ScriptContext, recycler); }
- static DWORD GetNumberAllocatorOffset() { return offsetof(ScriptContext, numberAllocator); }
- JITPageAddrToFuncRangeCache * GetJitFuncRangeCache();
- private:
- JITPageAddrToFuncRangeCache * jitFuncRangeCache;
- #endif
- public:
- ScriptContext *next;
- ScriptContext *prev;
- bool IsRegistered() { return next != nullptr || prev != nullptr || threadContext->GetScriptContextList() == this; }
- ScriptContextOptimizationOverrideInfo optimizationOverrides;
- Js::JavascriptMethod CurrentThunk;
- Js::JavascriptMethod CurrentCrossSiteThunk;
- Js::JavascriptMethod DeferredParsingThunk;
- Js::JavascriptMethod DeferredDeserializationThunk;
- Js::JavascriptMethod DispatchDefaultInvoke;
- Js::JavascriptMethod DispatchProfileInvoke;
- #ifdef ENABLE_SCRIPT_DEBUGGING
- typedef HRESULT (*GetDocumentContextFunction)(
- Js::FunctionBody *pFunctionBody,
- IDebugDocumentContext **ppDebugDocumentContext);
- GetDocumentContextFunction GetDocumentContext;
- #endif // ENABLE_SCRIPT_DEBUGGING
- #ifdef ENABLE_SCRIPT_PROFILING
- typedef HRESULT (*CleanupDocumentContextFunction)(ScriptContext *pContext);
- CleanupDocumentContextFunction CleanupDocumentContext;
- #endif
- const ScriptContextBase* GetScriptContextBase() const { return static_cast<const ScriptContextBase*>(this); }
- void RedeferFunctionBodies(ActiveFunctionSet *pActive, uint inactiveThreshold);
- bool DoUndeferGlobalFunctions() const;
- bool IsUndeclBlockVar(Var var) const { return this->javascriptLibrary->IsUndeclBlockVar(var); }
- void TrackPid(const PropertyRecord* propertyRecord);
- void TrackPid(PropertyId propertyId);
- bool IsTrackedPropertyId(Js::PropertyId propertyId);
- void InvalidateHostObjects()
- {
- AssertMsg(!isClosed, "Host Object invalidation should occur before the engine is fully closed. Figure our how isClosed got set beforehand.");
- isInvalidatedForHostObjects = true;
- }
- bool IsInvalidatedForHostObjects()
- {
- return isInvalidatedForHostObjects;
- }
- #if ENABLE_NATIVE_CODEGEN
- void InitializeRemoteScriptContext();
- #endif
- #ifdef ENABLE_JS_ETW
- void EmitStackTraceEvent(__in UINT64 operationID, __in USHORT maxFrameCount, bool emitV2AsyncStackEvent);
- static ushort ProcessNameAndGetLength(Js::StringBuilder<ArenaAllocator>* nameBuffer, const WCHAR* name);
- #endif
- void SetPrivilegeLevel(ScriptContextPrivilegeLevel level) { this->scriptContextPrivilegeLevel = level; }
- ScriptContextPrivilegeLevel GetPrivilegeLevel() { return this->scriptContextPrivilegeLevel; }
- void SetIsDiagnosticsScriptContext(bool);
- bool IsDiagnosticsScriptContext() const { return this->isDiagnosticsScriptContext; }
- bool IsScriptContextInNonDebugMode() const;
- bool IsScriptContextInDebugMode() const;
- bool IsScriptContextInSourceRundownOrDebugMode() const;
- #ifdef ENABLE_SCRIPT_DEBUGGING
- bool IsDebuggerRecording() const;
- void SetIsDebuggerRecording(bool isDebuggerRecording);
- #endif
- bool IsRunningScript() const { return this->threadContext->GetScriptEntryExit() != nullptr; }
- typedef JsUtil::List<RecyclerWeakReference<Utf8SourceInfo>*, Recycler, false, Js::WeakRefFreeListedRemovePolicy> CalleeSourceList;
- RecyclerRootPtr<CalleeSourceList> calleeUtf8SourceInfoList;
- void AddCalleeSourceInfoToList(Utf8SourceInfo* sourceInfo);
- bool HaveCalleeSources() { return calleeUtf8SourceInfoList && !calleeUtf8SourceInfoList->Empty(); }
- template<class TMapFunction>
- void MapCalleeSources(TMapFunction map)
- {
- if (this->HaveCalleeSources())
- {
- calleeUtf8SourceInfoList->Map([&](uint i, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfoWeakRef)
- {
- if (calleeUtf8SourceInfoList->IsItemValid(i))
- {
- Js::Utf8SourceInfo* sourceInfo = sourceInfoWeakRef->Get();
- map(sourceInfo);
- }
- });
- }
- if (calleeUtf8SourceInfoList)
- {
- calleeUtf8SourceInfoList.Unroot(this->GetRecycler());
- }
- }
- #ifdef ASMJS_PLAT
- inline AsmJsCodeGenerator* GetAsmJsCodeGenerator() const{return asmJsCodeGenerator;}
- AsmJsCodeGenerator* InitAsmJsCodeGenerator();
- #endif
- bool IsExceptionWrapperForBuiltInsEnabled();
- static bool IsExceptionWrapperForBuiltInsEnabled(ScriptContext* scriptContext);
- static bool IsExceptionWrapperForHelpersEnabled(ScriptContext* scriptContext);
- bool IsEnumerateNonUserFunctionsOnly() const { return m_enumerateNonUserFunctionsOnly; }
- #ifdef ENABLE_SCRIPT_PROFILING
- bool IsTraceDomCall() const { return !!m_fTraceDomCall; }
- #elif defined(ENABLE_SCRIPT_DEBUGGING)
- bool IsTraceDomCall() const { return false; }
- #endif
- InlineCache * GetValueOfInlineCache() const { return valueOfInlineCache;}
- InlineCache * GetToStringInlineCache() const { return toStringInlineCache; }
- NoSpecialPropertyScriptRegistry* GetNoSpecialPropertyRegistry() { return &this->noSpecialPropertyRegistry; }
- OnlyWritablePropertyScriptRegistry* GetOnlyWritablePropertyRegistry() { return &this->onlyWritablePropertyRegistry; }
- private:
- JavascriptFunction* GenerateRootFunction(ParseNodeProg * parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName);
- typedef void (*EventHandler)(ScriptContext *);
- NoSpecialPropertyScriptRegistry noSpecialPropertyRegistry;
- OnlyWritablePropertyScriptRegistry onlyWritablePropertyRegistry;
- ArenaAllocator generalAllocator;
- #ifdef ENABLE_BASIC_TELEMETRY
- ArenaAllocator telemetryAllocator;
- #endif
- ArenaAllocator dynamicProfileInfoAllocator;
- InlineCacheAllocator inlineCacheAllocator;
- CacheAllocator isInstInlineCacheAllocator;
- CacheAllocator enumeratorCacheAllocator;
- ArenaAllocator* interpreterArena;
- #ifdef ENABLE_SCRIPT_DEBUGGING
- ArenaAllocator* diagnosticArena;
- #endif
- #if ENABLE_NATIVE_CODEGEN
- PSCRIPTCONTEXT_HANDLE m_remoteScriptContextAddr;
- #endif
- bool startupComplete; // Indicates if the heuristic startup phase for this script context is complete
- bool isInvalidatedForHostObjects; // Indicates that we've invalidate all objects in the host so stop calling them.
- #ifdef ENABLE_SCRIPT_DEBUGGING
- bool isEnumeratingRecyclerObjects; // Indicates this scriptContext is enumerating recycler objects. Used by recycler enumerating callbacks to filter out other unrelated scriptContexts.
- #endif
- bool m_enumerateNonUserFunctionsOnly; // Indicates that recycler enumeration callback will consider only non-user functions (which are built-ins, external, winrt etc).
- ThreadContext* threadContext;
- TypeId directHostTypeId;
- InlineCache * valueOfInlineCache;
- InlineCache * toStringInlineCache;
- typedef JsUtil::BaseHashSet<Js::PropertyId, ArenaAllocator> PropIdSetForConstProp;
- PropIdSetForConstProp * intConstPropsOnGlobalObject;
- PropIdSetForConstProp * intConstPropsOnGlobalUserObject;
- void * firstInterpreterFrameReturnAddress;
- #ifdef SEPARATE_ARENA
- ArenaAllocator sourceCodeAllocator;
- ArenaAllocator regexAllocator;
- #endif
- #ifdef NEED_MISC_ALLOCATOR
- ArenaAllocator miscAllocator;
- #endif
- #if DBG
- JsUtil::BaseHashSet<void *, ArenaAllocator> bindRef;
- int m_iProfileSession;
- #endif
- #ifdef PROFILE_EXEC
- ScriptContextProfiler * profiler;
- bool isProfilerCreated;
- bool disableProfiler;
- bool ensureParentInfo;
- Profiler * CreateProfiler();
- #endif
- #ifdef PROFILE_MEM
- bool profileMemoryDump;
- #endif
- #ifdef PROFILE_STRINGS
- StringProfiler* stringProfiler;
- #endif
- public:
- #ifdef PROFILE_TYPES
- int convertNullToSimpleCount;
- int convertNullToSimpleDictionaryCount;
- int convertNullToDictionaryCount;
- int convertDeferredToDictionaryCount;
- int convertDeferredToSimpleDictionaryCount;
- int convertSimpleToDictionaryCount;
- int convertSimpleToSimpleDictionaryCount;
- int convertPathToDictionaryExceededLengthCount;
- int convertPathToDictionaryDeletedCount;
- int convertPathToDictionaryAttributesCount;
- int convertPathToDictionaryItemAttributesCount;
- int convertPathToDictionaryAccessorsCount;
- int convertPathToDictionaryItemAccessorsCount;
- int convertPathToDictionaryExtensionsCount;
- int convertPathToDictionaryProtoCount;
- int convertPathToDictionaryNoRootCount;
- int convertPathToDictionaryResetCount;
- int convertPathToSimpleDictionaryCount;
- int convertSimplePathToPathCount;
- int convertSimpleDictionaryToDictionaryCount;
- int convertSimpleSharedDictionaryToNonSharedCount;
- int convertSimpleSharedToNonSharedCount;
- int pathTypeHandlerCount;
- int promoteCount;
- int cacheCount;
- int branchCount;
- int maxPathLength;
- int typeCount[TypeIds_Limit];
- int instanceCount[TypeIds_Limit];
- #endif
- #ifdef PROFILE_BAILOUT_RECORD_MEMORY
- __int64 bailOutRecordBytes;
- __int64 bailOutOffsetBytes;
- __int64 codeSize;
- #endif
- #ifdef PROFILE_OBJECT_LITERALS
- int objectLiteralInstanceCount;
- int objectLiteralPathCount;
- int objectLiteralCount[TypePath::MaxPathTypeHandlerLength];
- int objectLiteralSimpleDictionaryCount;
- uint32 objectLiteralMaxLength;
- int objectLiteralPromoteCount;
- int objectLiteralCacheCount;
- int objectLiteralBranchCount;
- #endif
- #if DBG_DUMP
- uint byteCodeDataSize;
- uint byteCodeAuxiliaryDataSize;
- uint byteCodeAuxiliaryContextDataSize;
- uint byteCodeHistogram[static_cast<uint>(OpCode::ByteCodeLast)];
- uint32 forinCache;
- uint32 forinNoCache;
- #endif
- #ifdef BGJIT_STATS
- uint interpretedCount;
- uint funcJITCount;
- uint loopJITCount;
- uint bytecodeJITCount;
- uint interpretedCallsHighPri;
- uint maxFuncInterpret;
- uint jitCodeUsed;
- uint funcJitCodeUsed;
- uint speculativeJitCount;
- #endif
- #if DBG
- // Count how many Out of Memory and Stack overflow exceptions happened during the execution
- uint oomExceptionCount = 0;
- uint soExceptionCount = 0;
- #endif
- #ifdef REJIT_STATS
- // Used to store bailout stats
- typedef JsUtil::BaseDictionary<uint, uint, ArenaAllocator> BailoutStatsMap;
- struct RejitStats
- {
- uint *m_rejitReasonCounts;
- BailoutStatsMap* m_bailoutReasonCounts;
- uint m_totalRejits;
- uint m_totalBailouts;
- RejitStats(ScriptContext *scriptContext) : m_totalRejits(0), m_totalBailouts(0)
- {
- m_rejitReasonCounts = AnewArrayZ(scriptContext->GeneralAllocator(), uint, NumRejitReasons);
- m_bailoutReasonCounts = Anew(scriptContext->GeneralAllocator(), BailoutStatsMap, scriptContext->GeneralAllocator());
- }
- };
- void LogDataForFunctionBody(Js::FunctionBody *body, uint idx, bool isRejit);
- void LogRejit(Js::FunctionBody *body, RejitReason reason);
- void LogBailout(Js::FunctionBody *body, uint kind);
- // Used to centrally collect stats for all function bodies.
- typedef JsUtil::WeaklyReferencedKeyDictionary<const Js::FunctionBody, RejitStats*> RejitStatsMap;
- RejitStatsMap* rejitStatsMap;
- BailoutStatsMap *bailoutReasonCounts;
- BailoutStatsMap *bailoutReasonCountsCap;
- uint *rejitReasonCounts;
- uint *rejitReasonCountsCap;
- void ClearBailoutReasonCountsMap();
- void ClearRejitReasonCountsArray();
- #endif
- #ifdef ENABLE_BASIC_TELEMETRY
- private:
- Js::ScriptContextTelemetry * telemetry;
- public:
- Js::ScriptContextTelemetry& GetTelemetry();
- bool HasTelemetry();
- #endif
- #ifdef INLINE_CACHE_STATS
- // This is a strongly referenced dictionary, since we want to know hit rates for dead caches.
- typedef JsUtil::BaseDictionary<const Js::PolymorphicInlineCache*, InlineCacheData*, Recycler> CacheDataMap;
- CacheDataMap *cacheDataMap;
- void LogCacheUsage(Js::PolymorphicInlineCache *cache, bool isGet, Js::PropertyId propertyId, bool hit, bool collision);
- #endif
- #ifdef FIELD_ACCESS_STATS
- typedef SList<FieldAccessStatsPtr, Recycler> FieldAccessStatsList;
- struct FieldAccessStatsEntry
- {
- Field(RecyclerWeakReference<FunctionBody>*) functionBodyWeakRef;
- Field(FieldAccessStatsList) stats;
- FieldAccessStatsEntry(RecyclerWeakReference<FunctionBody>* functionBodyWeakRef, Recycler* recycler)
- : functionBodyWeakRef(functionBodyWeakRef), stats(recycler) {}
- };
- typedef JsUtil::BaseDictionary<uint, FieldAccessStatsEntry*, Recycler> FieldAccessStatsByFunctionNumberMap;
- FieldAccessStatsByFunctionNumberMap* fieldAccessStatsByFunctionNumber;
- void RecordFieldAccessStats(FunctionBody* functionBody, FieldAccessStatsPtr fieldAccessStats);
- #endif
- #ifdef MISSING_PROPERTY_STATS
- int missingPropertyMisses;
- int missingPropertyHits;
- int missingPropertyCacheAttempts;
- void RecordMissingPropertyMiss();
- void RecordMissingPropertyHit();
- void RecordMissingPropertyCacheAttempt();
- #endif
- bool IsIntConstPropertyOnGlobalObject(Js::PropertyId propId);
- void TrackIntConstPropertyOnGlobalObject(Js::PropertyId propId);
- bool IsIntConstPropertyOnGlobalUserObject(Js::PropertyId propertyId);
- void TrackIntConstPropertyOnGlobalUserObject(Js::PropertyId propertyId);
- private:
- //
- // Regex globals
- //
- #if ENABLE_REGEX_CONFIG_OPTIONS
- UnifiedRegex::DebugWriter* regexDebugWriter;
- UnifiedRegex::RegexStatsDatabase* regexStatsDatabase;
- #endif
- UnifiedRegex::TrigramAlphabet* trigramAlphabet;
- UnifiedRegex::RegexStacks *regexStacks;
- JsUtil::Stack<Var>* operationStack;
- Recycler* recycler;
- RecyclerJavascriptNumberAllocator numberAllocator;
- ScriptConfiguration config;
- CharClassifier *charClassifier;
- // DisableJIT-TODO: Switch this to Dynamic thunk ifdef instead
- #if ENABLE_NATIVE_CODEGEN
- #if DYNAMIC_INTERPRETER_THUNK
- InterpreterThunkEmitter* interpreterThunkEmitter;
- #endif
- BackgroundParser *backgroundParser;
- #ifdef ASMJS_PLAT
- InterpreterThunkEmitter* asmJsInterpreterThunkEmitter;
- AsmJsCodeGenerator* asmJsCodeGenerator;
- typedef JsUtil::BaseDictionary<void*, SList<AsmJsScriptFunction *>*, ArenaAllocator> AsmFunctionMap;
- AsmFunctionMap* asmJsEnvironmentMap;
- ArenaAllocator* debugTransitionAlloc;
- #endif
- NativeCodeGenerator* nativeCodeGen;
- #endif
- DateTime::DaylightTimeHelper daylightTimeHelper;
- DateTime::Utility dateTimeUtility;
- public:
- inline const WCHAR *GetStandardName(size_t *nameLength, DateTime::YMD *ymd = NULL)
- {
- return dateTimeUtility.GetStandardName(nameLength, ymd);
- }
- inline const WCHAR *GetDaylightName(size_t *nameLength, DateTime::YMD *ymd = NULL)
- {
- return dateTimeUtility.GetDaylightName(nameLength, ymd);
- }
- private:
- HostScriptContext * hostScriptContext;
- HaltCallback* scriptEngineHaltCallback;
- EventHandler scriptStartEventHandler;
- EventHandler scriptEndEventHandler;
- #ifdef FAULT_INJECTION
- EventHandler disposeScriptByFaultInjectionEventHandler;
- #endif
- #ifndef CC_LOW_MEMORY_TARGET
- uint integerStringMapCacheMissCount;
- uint integerStringMapCacheUseCount;
- #endif
- double lastNumberToStringRadix10;
- double lastUtcTimeFromStr;
- #if ENABLE_PROFILE_INFO
- bool referencesSharedDynamicSourceContextInfo;
- #endif
- // We could delay the actual close after callRootLevel is 0.
- // this is to indicate the actual close is called once only.
- bool isScriptContextActuallyClosed;
- bool isFinalized;
- bool isEvalRestricted;
- #if DBG
- bool isInitialized;
- bool isCloningGlobal;
- #endif
- bool fastDOMenabled;
- bool hasUsedInlineCache;
- bool hasProtoOrStoreFieldInlineCache;
- bool hasIsInstInlineCache;
- bool deferredBody;
- bool isPerformingNonreentrantWork;
- bool isDiagnosticsScriptContext; // mentions that current script context belongs to the diagnostics OM.
- // Privilege levels are a way of enforcing a relationship hierarchy between two script contexts
- // A less privileged script context is not allowed to marshal in objects that live in a more privileged context
- ScriptContextPrivilegeLevel scriptContextPrivilegeLevel;
- size_t sourceSize;
- void CleanSourceListInternal(bool calledDuringMark);
- typedef JsUtil::List<RecyclerWeakReference<Utf8SourceInfo>*, Recycler, false, Js::FreeListedRemovePolicy> SourceList;
- RecyclerRootPtr<SourceList> sourceList;
- #ifdef ENABLE_SCRIPT_DEBUGGING
- typedef void(*RaiseMessageToDebuggerFunctionType)(ScriptContext *, DEBUG_EVENT_INFO_TYPE, LPCWSTR, LPCWSTR);
- RaiseMessageToDebuggerFunctionType raiseMessageToDebuggerFunctionType;
- typedef void(*TransitionToDebugModeIfFirstSourceFn)(ScriptContext *, Utf8SourceInfo *);
- TransitionToDebugModeIfFirstSourceFn transitionToDebugModeIfFirstSourceFn;
- DebugContext* debugContext;
- CriticalSection debugContextCloseCS;
- #endif
- #ifdef ENABLE_SCRIPT_PROFILING
- IActiveScriptProfilerHeapEnum* heapEnum;
- // Profiler Probes
- // In future these can be list of callbacks ?
- // Profiler Callback information
- IActiveScriptProfilerCallback *m_pProfileCallback;
- BOOL m_fTraceFunctionCall;
- BOOL m_fTraceNativeFunctionCall;
- DWORD m_dwEventMask;
- IActiveScriptProfilerCallback2 *m_pProfileCallback2;
- BOOL m_fTraceDomCall;
- BOOL m_inProfileCallback;
- #endif // ENABLE_SCRIPT_PROFILING
- // List of weak reference dictionaries. We'll walk through them
- // and clean them up post-collection
- // IWeakReferenceDictionary objects are added to this list by calling
- // RegisterWeakReferenceDictionary. If you use JsUtil::WeakReferenceDictionary,
- // which also exposes the IWeakReferenceDictionary interface, it'll
- // automatically register the dictionary on the script context
- SListBase<JsUtil::IWeakReferenceDictionary*> weakReferenceDictionaryList;
- bool isWeakReferenceDictionaryListCleared;
- ScriptContext(ThreadContext* threadContext);
- void InitializeAllocations();
- void InitializePreGlobal();
- void InitializePostGlobal();
- void InitializeCache();
- bool isDebugContextInitialized;
- // Source Info
- void EnsureSourceContextInfoMap();
- void EnsureDynamicSourceContextInfoMap();
- void AddToEvalMapHelper(FastEvalMapString & key, BOOL isIndirect, ScriptFunction *pFuncScript);
- uint moduleSrcInfoCount;
- #ifdef RUNTIME_DATA_COLLECTION
- time_t createTime;
- #endif
- char16 const * url;
- void PrintStats();
- void InternalClose();
- template <typename TProperty> void InvalidatePropertyCache(PropertyId propertyId, Type* type);
- void InvalidatePropertyRecordUsageCache(PropertyRecordUsageCache* propertyRecordUsageCache, Type *type);
- template <typename TProperty> TProperty* TryGetProperty(PropertyId propertyId);
- template <typename TProperty> TProperty* GetProperty(PropertyId propertyId, const PropertyRecord* propertyRecord);
- template <typename TProperty> TProperty* CreateAndCacheSymbolOrPropertyString(const PropertyRecord* propertyRecord);
- public:
- #ifdef LEAK_REPORT
- LeakReport::UrlRecord * urlRecord;
- bool isRootTrackerScriptContext;
- #endif
- DateTime::DaylightTimeHelper *GetDaylightTimeHelper() { return &daylightTimeHelper; }
- DateTime::Utility *GetDateUtility() { return &dateTimeUtility; }
- virtual bool IsClosed() const override { return isClosed; }
- void SetIsClosed();
- bool IsFinalized() const { return isFinalized; }
- void SetIsFinalized() { isFinalized = true; }
- bool IsActuallyClosed() const { return isScriptContextActuallyClosed; }
- void SetEvalRestriction(bool set) { this->isEvalRestricted = set; }
- bool IsEvalRestriction() const { return this->isEvalRestricted; }
- #if ENABLE_NATIVE_CODEGEN
- bool IsClosedNativeCodeGenerator() const
- {
- return !nativeCodeGen || ::IsClosedNativeCodeGenerator(nativeCodeGen);
- }
- #endif
- void SetHasUsedInlineCache(bool value)
- {
- hasUsedInlineCache = value;
- #if DBG
- if(hasUsedInlineCache)
- {
- inlineCacheAllocator.Unlock();
- }
- #endif
- }
- void SetDirectHostTypeId(TypeId typeId) {directHostTypeId = typeId; }
- TypeId GetDirectHostTypeId() const { return directHostTypeId; }
- #if ENABLE_NATIVE_CODEGEN
- PSCRIPTCONTEXT_HANDLE GetRemoteScriptAddr(bool allowInitialize = true)
- {
- #if ENABLE_OOP_NATIVE_CODEGEN
- if (!m_remoteScriptContextAddr && allowInitialize)
- {
- InitializeRemoteScriptContext();
- }
- #endif
- return m_remoteScriptContextAddr;
- }
- #endif
- char16 const * GetUrl() const { return url; }
- void SetUrl(BSTR bstr);
- #ifdef RUNTIME_DATA_COLLECTION
- time_t GetCreateTime() const { return createTime; }
- uint GetAllocId() const { return allocId; }
- #endif
- #ifdef HEAP_ENUMERATION_VALIDATION
- bool IsInitialized() { return this->isInitialized; }
- #endif
- #ifdef ENABLE_SCRIPT_DEBUGGING
- bool IsDebugContextInitialized() const { return this->isDebugContextInitialized; }
- DebugContext* GetDebugContext() const;
- CriticalSection* GetDebugContextCloseCS() { return &debugContextCloseCS; }
- #endif
- uint callCount;
- // if the current context is for webworker
- DWORD webWorkerId;
- static ScriptContext * New(ThreadContext * threadContext);
- ~ScriptContext();
- #ifdef PROFILE_TYPES
- void ProfileTypes();
- #endif
- #ifdef PROFILE_OBJECT_LITERALS
- void ProfileObjectLiteral();
- #endif
- //
- // Regex helpers
- //
- #if ENABLE_REGEX_CONFIG_OPTIONS
- UnifiedRegex::RegexStatsDatabase* GetRegexStatsDatabase();
- UnifiedRegex::DebugWriter* GetRegexDebugWriter();
- #endif
- RegexPatternMruMap* GetDynamicRegexMap() const;
- UnifiedRegex::TrigramAlphabet* GetTrigramAlphabet() { return trigramAlphabet; }
- void SetTrigramAlphabet(UnifiedRegex::TrigramAlphabet * trigramAlphabet);
- UnifiedRegex::RegexStacks *RegexStacks();
- UnifiedRegex::RegexStacks *AllocRegexStacks();
- UnifiedRegex::RegexStacks *SaveRegexStacks();
- void RestoreRegexStacks(UnifiedRegex::RegexStacks *const contStack);
- void InitializeGlobalObject();
- bool IsIntlEnabled();
- bool IsJsBuiltInEnabled();
- JavascriptLibrary* GetLibrary() const { return javascriptLibrary; }
- Js::Cache* Cache() const{ return &this->javascriptLibrary->cache; }
- const JavascriptLibraryBase* GetLibraryBase() const { return javascriptLibrary->GetLibraryBase(); }
- #if DBG
- BOOL IsCloningGlobal() const { return isCloningGlobal;}
- #endif
- void PushObject(Var object);
- Var PopObject();
- BOOL CheckObject(Var object);
- inline bool IsHeapEnumInProgress() { return GetRecycler()->IsHeapEnumInProgress(); }
- bool IsInterpreted() { return config.IsNoNative(); }
- void ForceNoDynamicThunks() { config.ForceNoDynamicThunks(); }
- void ForceNoNative() { config.ForceNoNative(); }
- void ForceNative() { config.ForceNative(); }
- ScriptConfiguration const * GetConfig(void) const { return &config; }
- CharClassifier const * GetCharClassifier(void) const;
- static bool ExceedsStackNestedFuncCount(uint count);
- ThreadContext * GetThreadContext() const { return threadContext; }
- static const int MaxEvalSourceSize = 400;
- bool IsInEvalMap(FastEvalMapString const& key, BOOL isIndirect, ScriptFunction **ppFuncScript);
- void AddToEvalMap(FastEvalMapString & key, BOOL isIndirect, ScriptFunction *pFuncScript);
- template <typename TCacheType>
- void CleanDynamicFunctionCache(TCacheType* cacheType);
- template <class TDelegate>
- void MapFunction(TDelegate mapper);
- template <class TDelegate>
- FunctionBody* FindFunction(TDelegate predicate);
- inline bool EnableEvalMapCleanup() { return CONFIG_FLAG(EnableEvalMapCleanup); };
- uint GetNextSourceContextId();
- bool IsInNewFunctionMap(EvalMapString const& key, FunctionInfo **ppFuncInfo);
- void AddToNewFunctionMap(EvalMapString const& key, FunctionInfo *pFuncInfo);
- SourceContextInfo * GetSourceContextInfo(DWORD_PTR hostSourceContext, SimpleDataCacheWrapper* dataCacheWrapper);
- SourceContextInfo * GetSourceContextInfo(uint hash);
- SourceContextInfo * CreateSourceContextInfo(uint hash, DWORD_PTR hostSourceContext);
- SourceContextInfo * CreateSourceContextInfo(DWORD_PTR hostSourceContext, char16 const * url, size_t len,
- SimpleDataCacheWrapper* dataCacheWrapper, char16 const * sourceMapUrl = nullptr, size_t sourceMapUrlLen = 0);
- #if defined(LEAK_REPORT) || defined(CHECK_MEMORY_LEAK)
- void ClearSourceContextInfoMaps()
- {
- #if ENABLE_PROFILE_INFO
- this->referencesSharedDynamicSourceContextInfo = false;
- #endif
- }
- #endif
- #if ENABLE_PROFILE_INFO
- #if DBG_DUMP || defined(DYNAMIC_PROFILE_STORAGE) || defined(RUNTIME_DATA_COLLECTION)
- void ClearDynamicProfileList()
- {
- if (this->Cache()->profileInfoList)
- {
- this->Cache()->profileInfoList->Reset();
- this->Cache()->profileInfoList = nullptr;
- }
- }
- DynamicProfileInfoList * GetProfileInfoList() { return this->Cache()->profileInfoList; }
- #endif
- #endif
- SRCINFO const * GetModuleSrcInfo(Js::ModuleID moduleID);
- SourceContextInfoMap* GetSourceContextInfoMap()
- {
- return this->Cache()->sourceContextInfoMap;
- }
- DynamicSourceContextInfoMap* GetDynamicSourceContextInfoMap()
- {
- return this->Cache()->dynamicSourceContextInfoMap;
- }
- #if ENABLE_TTD
- //The host callback functor info
- HostScriptContextCallbackFunctor TTDHostCallbackFunctor;
- //The LogTag for this script context (the same as the tag for the global object but we put it here for fast lookup)
- TTD_LOG_PTR_ID ScriptContextLogTag;
- //Info about the core image for the context
- TTD::RuntimeContextInfo* TTDWellKnownInfo;
- //Additional runtime context that we only care about if TTD is running (or will be running)
- TTD::ScriptContextTTD* TTDContextInfo;
- //A flag indicating a TTDSnapshot is in progress
- bool TTDSnapshotOrInflateInProgress;
- //Check if a snapshot is in progress on this context
- bool IsTTDSnapshotOrInflateInProgress() const { return this->TTDSnapshotOrInflateInProgress; }
- //Memoized results for frequently used Record/Replay action checks
- bool TTDRecordOrReplayModeEnabled;
- bool TTDRecordModeEnabled;
- bool TTDReplayModeEnabled;
- bool TTDShouldPerformRecordOrReplayAction;
- bool TTDShouldPerformRecordAction;
- bool TTDShouldPerformReplayAction;
- bool TTDShouldPerformRecordOrReplayDebuggerAction;
- bool TTDShouldPerformRecordDebuggerAction;
- bool TTDShouldPerformReplayDebuggerAction;
- bool TTDShouldSuppressGetterInvocationForDebuggerEvaluation;
- //Check if the TTD system has been activated (and record/replay may or may not be enabled)
- bool IsTTDRecordOrReplayModeEnabled() const { return this->TTDRecordOrReplayModeEnabled; }
- //Check if the TTD Record system has been activated (and may or may not be enabled)
- bool IsTTDRecordModeEnabled() const { return this->TTDRecordModeEnabled; }
- //Check if the TTD Replay system has been activated (and may or may not be enabled)
- bool IsTTDReplayModeEnabled() const { return this->TTDReplayModeEnabled; }
- //Check if we are in (record OR replay) AND this code is being run on behalf of the user application
- bool ShouldPerformRecordOrReplayAction() const { return this->TTDShouldPerformRecordOrReplayAction; }
- //Use this to check specifically if we are in record AND this code is being run on behalf of the user application
- bool ShouldPerformRecordAction() const { return this->TTDShouldPerformRecordAction; }
- //Use this to check specifically if we are in replay mode AND this code is being run on behalf of the user application
- bool ShouldPerformReplayAction() const { return this->TTDShouldPerformReplayAction; }
- //Use this to check specifically if we are in debugging mode AND this code is being run on behalf of the user application
- bool ShouldPerformRecordOrReplayDebuggerAction() const { return this->TTDShouldPerformRecordOrReplayDebuggerAction; }
- //Use this to check specifically if we are in debugging record mode AND this code is being run on behalf of the user application
- bool ShouldPerformRecordDebuggerAction() const { return this->TTDShouldPerformRecordDebuggerAction; }
- //Use this to check specifically if we are in debugging replay mode AND this code is being run on behalf of the user application
- bool ShouldPerformReplayDebuggerAction() const { return this->TTDShouldPerformReplayDebuggerAction; }
- //A special check to see if we are debugging and want to suppress the execution of getters (which may be triggered by displaying values in the debugger)
- bool ShouldSuppressGetterInvocationForDebuggerEvaluation() const { return this->TTDShouldSuppressGetterInvocationForDebuggerEvaluation; }
- //
- //TODO: this is currently called explicitly -- we need to fix up the core image computation and this will be eliminated then
- //
- //Initialize the core object image for TTD
- void InitializeCoreImage_TTD();
- #endif
- void SetFirstInterpreterFrameReturnAddress(void * returnAddress) { firstInterpreterFrameReturnAddress = returnAddress;}
- void *GetFirstInterpreterFrameReturnAddress() { return firstInterpreterFrameReturnAddress;}
- void CleanupWeakReferenceDictionaries();
- void Initialize();
- bool Close(bool inDestructor);
- void MarkForClose();
- void SetCanOptimizeGlobalLookupFlag(BOOL f){ config.SetCanOptimizeGlobalLookupFlag(f);}
- BOOL CanOptimizeGlobalLookup(){ return config.CanOptimizeGlobalLookup();}
- bool IsFastDOMEnabled() { return fastDOMenabled; }
- void SetFastDOMenabled();
- BOOL VerifyAlive(BOOL isJSFunction = FALSE, ScriptContext* requestScriptContext = nullptr);
- void VerifyAliveWithHostContext(BOOL isJSFunction, HostScriptContext* requestHostScriptContext);
- void BindReference(void* addr);
- void InitPropertyStringMap(int i);
- PropertyString* AddPropertyString2(const Js::PropertyRecord* propertyRecord);
- PropertyString* CachePropertyString2(const Js::PropertyRecord* propertyRecord);
- PropertyString* GetPropertyString2(char16 ch1, char16 ch2);
- void FindPropertyRecord(__in LPCWSTR pszPropertyName, __in int propertyNameLength, PropertyRecord const** propertyRecord);
- JsUtil::List<const RecyclerWeakReference<Js::PropertyRecord const>*>* FindPropertyIdNoCase(__in LPCWSTR pszPropertyName, __in int propertyNameLength);
- void FindPropertyRecord(JavascriptString* pstName, PropertyRecord const** propertyRecord);
- PropertyRecord const * GetPropertyName(PropertyId propertyId);
- PropertyRecord const * GetPropertyNameLocked(PropertyId propertyId);
- void GetOrAddPropertyRecord(JsUtil::CharacterBuffer<WCHAR> const& propName, PropertyRecord const** propertyRecord);
- template <size_t N> void GetOrAddPropertyRecord(const char16(&propertyName)[N], PropertyRecord const** propertyRecord)
- {
- GetOrAddPropertyRecord(propertyName, N - 1, propertyRecord);
- }
- void GetOrAddPropertyRecord(_In_ Js::JavascriptString * propertyString, _Out_ PropertyRecord const** propertyRecord);
- PropertyId GetOrAddPropertyIdTracked(JsUtil::CharacterBuffer<WCHAR> const& propName);
- template <size_t N> PropertyId GetOrAddPropertyIdTracked(const char16(&propertyName)[N])
- {
- return GetOrAddPropertyIdTracked(propertyName, N - 1);
- }
- PropertyId GetOrAddPropertyIdTracked(__in_ecount(propertyNameLength) LPCWSTR pszPropertyName, __in int propertyNameLength);
- void GetOrAddPropertyRecord(__in_ecount(propertyNameLength) LPCWSTR pszPropertyName, _In_ int propertyNameLength, _Out_ PropertyRecord const** propertyRecord);
- BOOL IsNumericPropertyId(PropertyId propertyId, uint32* value);
- void RegisterWeakReferenceDictionary(JsUtil::IWeakReferenceDictionary* weakReferenceDictionary);
- void ResetWeakReferenceDictionaryList() { weakReferenceDictionaryList.Reset(); }
- BOOL ReserveStaticTypeIds(__in int first, __in int last);
- TypeId ReserveTypeIds(int count);
- TypeId CreateTypeId();
- template<WellKnownHostType wellKnownType>
- bool IsWellKnownHostType(Js::TypeId typeId) { return threadContext->IsWellKnownHostType<wellKnownType>(typeId); }
- void SetWellKnownHostTypeId(WellKnownHostType wellKnownType, Js::TypeId typeId) { threadContext->SetWellKnownHostTypeId(wellKnownType, typeId); }
- ParseNodeProg * ParseScript(Parser* parser, const byte* script,
- size_t cb, SRCINFO const * pSrcInfo,
- CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo,
- const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag,
- uint* sourceIndex, Js::Var scriptSource = nullptr);
- JavascriptFunction* LoadScript(const byte* script, size_t cb,
- SRCINFO const * pSrcInfo,
- CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo,
- const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag,
- Js::Var scriptSource = nullptr);
- JavascriptFunction* LoadScriptInternal(Parser* parser,
- const byte* script, size_t cb,
- SRCINFO const * pSrcInfo,
- CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo,
- const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag,
- Js::Var scriptSource = nullptr);
- HRESULT TryDeserializeParserState(
- _In_ ULONG grfscr,
- _In_ uint sourceCRC,
- _In_ charcount_t cchLength,
- _In_ SRCINFO *srcInfo,
- _In_ Js::Utf8SourceInfo* utf8SourceInfo,
- _Inout_ uint& sourceIndex,
- _In_ bool isCesu8,
- _In_opt_ NativeModule* nativeModule,
- _Outptr_ Js::ParseableFunctionInfo ** func,
- _Outptr_result_buffer_(*parserStateCacheByteCount) byte** parserStateCacheBuffer,
- _Out_ DWORD* parserStateCacheByteCount,
- _In_ Js::SimpleDataCacheWrapper* pDataCache);
- HRESULT TrySerializeParserState(
- _In_ uint sourceCRC,
- _In_reads_bytes_(cbLength) LPCUTF8 pszSrc,
- _In_ size_t cbLength,
- _In_ SRCINFO *srcInfo,
- _In_ Js::ParseableFunctionInfo* func,
- _In_reads_bytes_(parserStateCacheByteCount) byte* parserStateCacheBuffer,
- _In_ DWORD parserStateCacheByteCount,
- _In_ Js::SimpleDataCacheWrapper* pDataCache);
- HRESULT CompileUTF8Core(
- __in Parser& ps,
- __in Js::Utf8SourceInfo* utf8SourceInfo,
- __in SRCINFO *srcInfo,
- __in BOOL fOriginalUTF8Code,
- _In_reads_bytes_(cbLength) LPCUTF8 pszSrc,
- __in size_t cbLength,
- __in ULONG grfscr,
- __in CompileScriptException *pse,
- __inout charcount_t& cchLength,
- __out size_t& srcLength,
- __out uint& sourceIndex,
- __deref_out Js::ParseableFunctionInfo ** func,
- __in_opt Js::SimpleDataCacheWrapper* pDataCache);
- HRESULT SerializeParserState(const byte* script, size_t cb,
- SRCINFO const * pSrcInfo,
- CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo,
- const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag,
- byte** buffer, DWORD* bufferSize, ArenaAllocator* alloc,
- JavascriptFunction** function = nullptr,
- Js::Var scriptSource = nullptr);
- void MakeUtf8SourceInfo(const byte* script,
- size_t cb,
- SRCINFO const * pSrcInfo,
- Utf8SourceInfo** ppSourceInfo,
- LoadScriptFlag loadScriptFlag,
- Js::Var scriptSource);
- ULONG GetParseFlags(LoadScriptFlag loadScriptFlag, Utf8SourceInfo* pSourceInfo, SourceContextInfo* sourceContextInfo);
- ArenaAllocator* GeneralAllocator() { return &generalAllocator; }
- #ifdef ENABLE_BASIC_TELEMETRY
- ArenaAllocator* TelemetryAllocator() { return &telemetryAllocator; }
- #endif
- #ifdef SEPARATE_ARENA
- ArenaAllocator* SourceCodeAllocator() { return &sourceCodeAllocator; }
- ArenaAllocator* RegexAllocator() { return ®exAllocator; }
- #else
- ArenaAllocator* SourceCodeAllocator() { return &generalAllocator; }
- ArenaAllocator* RegexAllocator() { return &generalAllocator; }
- #endif
- #ifdef NEED_MISC_ALLOCATOR
- ArenaAllocator* MiscAllocator() { return &miscAllocator; }
- #endif
- InlineCacheAllocator* GetInlineCacheAllocator() { return &inlineCacheAllocator; }
- CacheAllocator* GetIsInstInlineCacheAllocator() { return &isInstInlineCacheAllocator; }
- CacheAllocator * GetEnumeratorAllocator() { return &enumeratorCacheAllocator; }
- ArenaAllocator* DynamicProfileInfoAllocator() { return &dynamicProfileInfoAllocator; }
- #ifdef ENABLE_SCRIPT_DEBUGGING
- ArenaAllocator* AllocatorForDiagnostics();
- #endif
- Js::TempArenaAllocatorObject* GetTemporaryAllocator(LPCWSTR name);
- void ReleaseTemporaryAllocator(Js::TempArenaAllocatorObject* tempAllocator);
- Js::TempGuestArenaAllocatorObject* GetTemporaryGuestAllocator(LPCWSTR name);
- void ReleaseTemporaryGuestAllocator(Js::TempGuestArenaAllocatorObject* tempAllocator);
- bool EnsureInterpreterArena(ArenaAllocator **);
- void ReleaseInterpreterArena();
- Recycler* GetRecycler() const { return recycler; }
- RecyclerJavascriptNumberAllocator * GetNumberAllocator() { return &numberAllocator; }
- #if ENABLE_NATIVE_CODEGEN
- NativeCodeGenerator * GetNativeCodeGenerator() const { return nativeCodeGen; }
- #endif
- #if ENABLE_BACKGROUND_PARSING
- BackgroundParser * GetBackgroundParser() const { return backgroundParser; }
- #endif
- void OnScriptStart(bool isRoot, bool isScript);
- void OnScriptEnd(bool isRoot, bool isForcedEnd);
- template <bool stackProbe, bool leaveForHost>
- bool LeaveScriptStart(void * frameAddress);
- template <bool leaveForHost>
- void LeaveScriptEnd(void * frameAddress);
- HostScriptContext * GetHostScriptContext() const { return hostScriptContext; }
- void SetHostScriptContext(HostScriptContext * hostScriptContext);
- void SetScriptEngineHaltCallback(HaltCallback* scriptEngine);
- void ClearHostScriptContext();
- IActiveScriptProfilerHeapEnum* GetHeapEnum();
- void SetHeapEnum(IActiveScriptProfilerHeapEnum* newHeapEnum);
- void ClearHeapEnum();
- void SetScriptStartEventHandler(EventHandler eventHandler);
- void SetScriptEndEventHandler(EventHandler eventHandler);
- #ifdef FAULT_INJECTION
- void DisposeScriptContextByFaultInjection();
- void SetDisposeDisposeByFaultInjectionEventHandler(EventHandler eventHandler);
- #endif
- EnumeratedObjectCache* GetEnumeratedObjectCache() { return &(this->Cache()->enumObjCache); }
- PropertyString* GetPropertyString(PropertyId propertyId);
- PropertyString* GetPropertyString(const PropertyRecord* propertyRecord);
- JavascriptSymbol* GetSymbol(PropertyId propertyId);
- JavascriptSymbol* GetSymbol(const PropertyRecord* propertyRecord);
- void InvalidatePropertyStringAndSymbolCaches(PropertyId propertyId, Type* type);
- JavascriptString* GetIntegerString(Var aValue);
- JavascriptString* GetIntegerString(int value);
- JavascriptString* GetIntegerString(uint value);
- void CheckEvalRestriction();
- RecyclableObject* GetMissingPropertyResult();
- RecyclableObject* GetMissingItemResult();
- bool HasRecordedException() const { return threadContext->GetRecordedException() != nullptr; }
- Js::JavascriptExceptionObject * GetAndClearRecordedException(bool *considerPassingToDebugger = nullptr);
- void RecordException(Js::JavascriptExceptionObject * exceptionObject, bool propagateToDebugger = false);
- __declspec(noreturn) void RethrowRecordedException(JavascriptExceptionObject::HostWrapperCreateFuncType hostWrapperCreateFunc);
- #if ENABLE_NATIVE_CODEGEN
- BOOL IsNativeAddress(void * codeAddr);
- #endif
- uint SaveSourceNoCopy(Utf8SourceInfo* sourceInfo, int cchLength, bool isCesu8);
- Utf8SourceInfo* GetSource(uint sourceIndex);
- void RemoveSource(uint sourceIndex);
- uint SourceCount() const { return (uint)sourceList->Count(); }
- void CleanSourceList() { CleanSourceListInternal(false); }
- SourceList* GetSourceList() const { return sourceList; }
- bool IsItemValidInSourceList(int index);
- template <typename TFunction>
- void MapScript(TFunction mapper)
- {
- this->sourceList->Map([mapper] (int, RecyclerWeakReference<Utf8SourceInfo>* sourceInfoWeakReference)
- {
- Utf8SourceInfo* strongRef = sourceInfoWeakReference->Get();
- if (strongRef)
- {
- mapper(strongRef);
- }
- });
- }
- #ifdef CHECK_STACKWALK_EXCEPTION
- void SetIgnoreStackWalkException() {threadContext->GetScriptEntryExit()->ignoreStackWalkException = true; }
- #endif
- // For debugging scenarios where execution will go to debugging manager and come back to engine again, enforce the current EER to have
- // 'hasCaller' property set, which will enable the stack walking across frames.
- // Do not call this directly, look for ENFORCE_ENTRYEXITRECORD_HASCALLER macro.
- void EnforceEERHasCaller() { threadContext->GetScriptEntryExit()->hasCaller = true; }
- #ifdef ENABLE_SCRIPT_DEBUGGING
- void SetRaiseMessageToDebuggerFunction(RaiseMessageToDebuggerFunctionType function)
- {
- raiseMessageToDebuggerFunctionType = function;
- }
- void RaiseMessageToDebugger(DEBUG_EVENT_INFO_TYPE messageType, LPCWSTR message, LPCWSTR url)
- {
- if (raiseMessageToDebuggerFunctionType != nullptr)
- {
- raiseMessageToDebuggerFunctionType(this, messageType, message, url);
- }
- }
- void SetTransitionToDebugModeIfFirstSourceFn(TransitionToDebugModeIfFirstSourceFn function)
- {
- transitionToDebugModeIfFirstSourceFn = function;
- }
- void TransitionToDebugModeIfFirstSource(Utf8SourceInfo *sourceInfo)
- {
- if (transitionToDebugModeIfFirstSourceFn != nullptr)
- {
- transitionToDebugModeIfFirstSourceFn(this, sourceInfo);
- }
- }
- #endif
- void AddSourceSize(size_t sourceSize)
- {
- this->sourceSize += sourceSize;
- this->threadContext->AddSourceSize(sourceSize);
- }
- size_t GetSourceSize()
- {
- return this->sourceSize;
- }
- BOOL SetDeferredBody(BOOL set)
- {
- bool old = this->deferredBody;
- this->deferredBody = !!set;
- return old;
- }
- BOOL GetDeferredBody(void) const
- {
- return this->deferredBody;
- }
- private:
- Js::PropertyId emptyStringPropertyId;
- public:
- Js::PropertyId GetEmptyStringPropertyId()
- {
- return threadContext->GetEmptyStringPropertyId();
- }
- void FreeFunctionEntryPoint(Js::JavascriptMethod codeAddress, Js::JavascriptMethod thunkAddress);
- public:
- void RegisterProtoInlineCache(InlineCache *pCache, PropertyId propId);
- void InvalidateProtoCaches(const PropertyId propertyId);
- void InvalidateAllProtoCaches();
- void RegisterStoreFieldInlineCache(InlineCache *pCache, PropertyId propId);
- void InvalidateStoreFieldCaches(const PropertyId propertyId);
- void InvalidateAllStoreFieldCaches();
- void RegisterIsInstInlineCache(Js::IsInstInlineCache * cache, Js::Var function);
- #if DBG
- bool IsIsInstInlineCacheRegistered(Js::IsInstInlineCache * cache, Js::Var function);
- #endif
- void ClearInlineCaches();
- void ClearIsInstInlineCaches();
- void ClearEnumeratorCaches();
- #ifdef PERSISTENT_INLINE_CACHES
- void ClearInlineCachesWithDeadWeakRefs();
- #endif
- void ClearScriptContextCaches();
- #if ENABLE_NATIVE_CODEGEN
- void RegisterConstructorCache(Js::PropertyId propertyId, Js::ConstructorCache* cache);
- #endif
- public:
- JavascriptString * GetLastNumberToStringRadix10(double value);
- void SetLastNumberToStringRadix10(double value, JavascriptString * str);
- bool GetLastUtcTimeFromStr(JavascriptString * str, double& dbl);
- void SetLastUtcTimeFromStr(JavascriptString * str, double value);
- bool IsNoContextSourceContextInfo(SourceContextInfo *sourceContextInfo) const
- {
- return sourceContextInfo == this->Cache()->noContextSourceContextInfo;
- }
- BOOL IsProfiling()
- {
- #ifdef ENABLE_SCRIPT_PROFILING
- return (m_pProfileCallback != nullptr);
- #else
- return FALSE;
- #endif
- }
- BOOL IsInProfileCallback()
- {
- #ifdef ENABLE_SCRIPT_PROFILING
- return m_inProfileCallback;
- #else
- return FALSE;
- #endif
- }
- SRCINFO *AddHostSrcInfo(SRCINFO const *pSrcInfo);
- #if DBG
- SourceContextInfo const * GetNoContextSourceContextInfo() const { return this->Cache()->noContextSourceContextInfo; }
- bool hadProfiled;
- bool HadProfiled() const { return hadProfiled; }
- #ifdef ENABLE_SCRIPT_PROFILING
- int GetProfileSession()
- {
- AssertMsg(m_pProfileCallback != nullptr, "Asking for profile session when we aren't in one.");
- return m_iProfileSession;
- }
- void StartNewProfileSession()
- {
- AssertMsg(m_pProfileCallback != nullptr, "New Session when the profiler isn't set to any callback.");
- m_iProfileSession++;
- }
- void StopProfileSession()
- {
- AssertMsg(m_pProfileCallback == nullptr, "How to stop when there is still the callback out there");
- }
- #endif // ENABLE_SCRIPT_PROFILING
- #endif
- #ifdef ENABLE_SCRIPT_PROFILING
- void CoreSetProfileEventMask(DWORD dwEventMask);
- typedef HRESULT(*RegisterExternalLibraryType)(Js::ScriptContext *pScriptContext);
- HRESULT RegisterProfileProbe(IActiveScriptProfilerCallback *pProfileCallback, DWORD dwEventMask, DWORD dwContext, RegisterExternalLibraryType RegisterExternalLibrary, JavascriptMethod dispatchInvoke);
- HRESULT DeRegisterProfileProbe(HRESULT hrReason, JavascriptMethod dispatchInvoke);
- HRESULT RegisterLibraryFunction(const char16 *pwszObjectName, const char16 *pwszFunctionName, Js::PropertyId functionPropertyId, JavascriptMethod entryPoint);
- HRESULT RegisterBuiltinFunctions(RegisterExternalLibraryType RegisterExternalLibrary);
- HRESULT SetProfileEventMask(DWORD dwEventMask);
- HRESULT RegisterScript(Js::FunctionProxy *pFunctionBody, BOOL fRegisterScript = TRUE);
- // Register static and dynamic scripts
- HRESULT RegisterAllScripts();
- #endif
- #ifdef ENABLE_SCRIPT_DEBUGGING
- // Iterate through utf8sourceinfo and clear debug document if they are there.
- void EnsureClearDebugDocument();
- void UpdateRecyclerFunctionEntryPointsForDebugger();
- static void RecyclerFunctionCallbackForDebugger(void *address, size_t size);
- void SetFunctionInRecyclerToProfileMode(bool enumerateNonUserFunctionsOnly = false);
- #ifdef ASMJS_PLAT
- void TransitionEnvironmentForDebugger(ScriptFunction * scriptFunction);
- #endif
- #endif
- // To be called directly only when the thread context is shutting down
- void ShutdownClearSourceLists();
- #if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING)
- void RegisterDebugThunk(bool calledDuringAttach = true);
- void UnRegisterDebugThunk();
- static void SetEntryPointToProfileThunk(JavascriptFunction* function);
- static void RestoreEntryPointFromProfileThunk(JavascriptFunction* function);
- static void RecyclerEnumClassEnumeratorCallback(void *address, size_t size);
- #endif
- #if ENABLE_NATIVE_CODEGEN
- HRESULT RecreateNativeCodeGenerator(NativeCodeGenerator ** previousCodeGen = nullptr);
- void DeletePreviousNativeCodeGenerator(NativeCodeGenerator * codeGen);
- HRESULT OnDebuggerAttachedDetached(bool attach, NativeCodeGenerator ** previousCodeGenHolder = nullptr);
- #else
- HRESULT OnDebuggerAttachedDetached(bool attach);
- #endif
- bool IsForceNoNative();
- #ifdef ENABLE_SCRIPT_DEBUGGING
- HRESULT OnDebuggerAttached();
- HRESULT OnDebuggerDetached();
- void InitializeDebugging();
- bool IsEnumeratingRecyclerObjects() const { return isEnumeratingRecyclerObjects; }
- private:
- class AutoEnumeratingRecyclerObjects
- {
- public:
- AutoEnumeratingRecyclerObjects(ScriptContext* scriptContext):
- m_scriptContext(scriptContext)
- {
- Assert(!m_scriptContext->IsEnumeratingRecyclerObjects());
- m_scriptContext->isEnumeratingRecyclerObjects = true;
- }
- ~AutoEnumeratingRecyclerObjects()
- {
- Assert(m_scriptContext->IsEnumeratingRecyclerObjects());
- m_scriptContext->isEnumeratingRecyclerObjects = false;
- }
- private:
- ScriptContext* m_scriptContext;
- };
- #endif
- #ifdef EDIT_AND_CONTINUE
- private:
- ScriptEditQuery* activeScriptEditQuery;
- void BeginScriptEditEnumFunctions(ScriptEditQuery* scriptEditQuery) { Assert(!activeScriptEditQuery); activeScriptEditQuery = scriptEditQuery; }
- void EndScriptEditEnumFunctions() { Assert(activeScriptEditQuery); activeScriptEditQuery = nullptr; }
- public:
- ScriptEditQuery* GetActiveScriptEditQuery() const { return activeScriptEditQuery; }
- class AutoScriptEditEnumFunctions
- {
- public:
- AutoScriptEditEnumFunctions(ScriptContext* scriptContext, ScriptEditQuery* scriptEditQuery) : m_scriptContext(scriptContext)
- {
- scriptContext->BeginScriptEditEnumFunctions(scriptEditQuery);
- }
- ~AutoScriptEditEnumFunctions() { m_scriptContext->EndScriptEditEnumFunctions(); }
- private:
- ScriptContext* m_scriptContext;
- };
- #endif
- private:
- typedef JsUtil::BaseDictionary<JavascriptMethod, Js::PropertyId, ArenaAllocator, PrimeSizePolicy> BuiltinFunctionIdDictionary;
- BuiltinFunctionIdDictionary *m_pBuiltinFunctionIdMap;
- Js::PropertyId GetFunctionNumber(JavascriptMethod entryPoint);
- static const char16* CopyString(const char16* str, size_t charCount, ArenaAllocator* alloc);
- #ifdef ENABLE_JS_ETW
- static charcount_t AppendWithEscapeCharacters(Js::StringBuilder<ArenaAllocator>* stringBuilder, const WCHAR* sourceString, charcount_t sourceStringLen, WCHAR escapeChar, WCHAR charToEscape);
- #endif
- public:
- #if DYNAMIC_INTERPRETER_THUNK
- JavascriptMethod GetNextDynamicAsmJsInterpreterThunk(PVOID* ppDynamicInterpreterThunk);
- JavascriptMethod GetNextDynamicInterpreterThunk(PVOID* ppDynamicInterpreterThunk);
- #if DBG
- BOOL IsDynamicInterpreterThunk(JavascriptMethod address);
- #endif
- void ReleaseDynamicInterpreterThunk(BYTE* address, bool addtoFreeList);
- void ReleaseDynamicAsmJsInterpreterThunk(BYTE* address, bool addtoFreeList);
- #endif
- static Var DebugProfileProbeThunk(RecyclableObject* function, CallInfo callInfo, ...);
- static JavascriptMethod ProfileModeDeferredParse(ScriptFunction **function);
- static Var ProfileModeDeferredParsingThunk(RecyclableObject* function, CallInfo callInfo, ...);
- // Thunks for deferred deserialization of function bodies from the byte code cache
- static JavascriptMethod ProfileModeDeferredDeserialize(ScriptFunction* function);
- static Var ProfileModeDeferredDeserializeThunk(RecyclableObject* function, CallInfo callInfo, ...);
- #if defined(ENABLE_SCRIPT_DEBUGGING) || defined(ENABLE_SCRIPT_PROFILING)
- static Var ProfileModeThunk_DebugModeWrapper(JavascriptFunction* function, ScriptContext* scriptContext, JavascriptMethod entryPoint, Arguments& args);
- static JavascriptMethod GetProfileModeThunk(JavascriptMethod entryPoint);
- #endif
- #ifdef ENABLE_SCRIPT_PROFILING
- void SetProfileMode(BOOL fSet);
- BOOL GetProfileInfo(
- JavascriptFunction* function,
- PROFILER_TOKEN &scriptId,
- PROFILER_TOKEN &functionId);
- HRESULT OnScriptCompiled(PROFILER_TOKEN scriptId, PROFILER_SCRIPT_TYPE type, IUnknown *pIDebugDocumentContext);
- HRESULT OnFunctionCompiled(
- PROFILER_TOKEN functionId,
- PROFILER_TOKEN scriptId,
- const WCHAR *pwszFunctionName,
- const WCHAR *pwszFunctionNameHint,
- IUnknown *pIDebugDocumentContext);
- HRESULT OnFunctionEnter(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId);
- HRESULT OnFunctionExit(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId);
- static HRESULT FunctionExitSenderThunk(PROFILER_TOKEN functionId, PROFILER_TOKEN scriptId, ScriptContext *pScriptContext);
- static HRESULT FunctionExitByNameSenderThunk(const char16 *pwszFunctionName, ScriptContext *pScriptContext);
- bool SetDispatchProfile(bool fSet, JavascriptMethod dispatchInvoke);
- HRESULT OnDispatchFunctionEnter(const WCHAR *pwszFunctionName);
- HRESULT OnDispatchFunctionExit(const WCHAR *pwszFunctionName);
- #endif // ENABLE_SCRIPT_PROFILING
- void OnStartupComplete();
- void SaveStartupProfileAndRelease(bool isSaveOnClose = false);
- #if ENABLE_PROFILE_INFO
- template<template<typename> class BarrierT>
- void AddDynamicProfileInfo(FunctionBody * functionBody, BarrierT<DynamicProfileInfo>& dynamicProfileInfo);
- #endif
- #if DBG || defined(RUNTIME_DATA_COLLECTION)
- uint allocId;
- #endif
- #ifdef PROFILE_EXEC
- void DisableProfiler();
- void SetRecyclerProfiler();
- void SetProfilerFromScriptContext(ScriptContext * scriptContext);
- void ProfileBegin(Js::Phase);
- void ProfileEnd(Js::Phase);
- void ProfileSuspend(Js::Phase, Js::Profiler::SuspendRecord * suspendRecord);
- void ProfileResume(Js::Profiler::SuspendRecord * suspendRecord);
- void ProfilePrint();
- bool IsProfilerCreated() const { return isProfilerCreated; }
- #endif
- #ifdef PROFILE_MEM
- void DisableProfileMemoryDumpOnDelete() { profileMemoryDump = false; }
- #endif
- #ifdef PROFILE_STRINGS
- StringProfiler * GetStringProfiler(); // May be null if string profiling not enabled
- #endif
- public:
- virtual intptr_t GetNullAddr() const override;
- virtual intptr_t GetUndefinedAddr() const override;
- virtual intptr_t GetTrueAddr() const override;
- virtual intptr_t GetFalseAddr() const override;
- virtual intptr_t GetUndeclBlockVarAddr() const override;
- virtual intptr_t GetEmptyStringAddr() const override;
- virtual intptr_t GetNegativeZeroAddr() const override;
- virtual intptr_t GetNumberTypeStaticAddr() const override;
- virtual intptr_t GetStringTypeStaticAddr() const override;
- virtual intptr_t GetSymbolTypeStaticAddr() const override;
- virtual intptr_t GetObjectTypeAddr() const override;
- virtual intptr_t GetObjectHeaderInlinedTypeAddr() const override;
- virtual intptr_t GetRegexTypeAddr() const override;
- virtual intptr_t GetArrayTypeAddr() const override;
- virtual intptr_t GetNativeIntArrayTypeAddr() const override;
- virtual intptr_t GetNativeFloatArrayTypeAddr() const override;
- virtual intptr_t GetArrayConstructorAddr() const override;
- virtual intptr_t GetCharStringCacheAddr() const override;
- virtual intptr_t GetSideEffectsAddr() const override;
- virtual intptr_t GetArraySetElementFastPathVtableAddr() const override;
- virtual intptr_t GetIntArraySetElementFastPathVtableAddr() const override;
- virtual intptr_t GetFloatArraySetElementFastPathVtableAddr() const override;
- virtual intptr_t GetLibraryAddr() const override;
- virtual intptr_t GetGlobalObjectAddr() const override;
- virtual intptr_t GetGlobalObjectThisAddr() const override;
- virtual intptr_t GetObjectPrototypeAddr() const;
- virtual intptr_t GetFunctionPrototypeAddr() const;
- virtual intptr_t GetNumberAllocatorAddr() const override;
- virtual intptr_t GetRecyclerAddr() const override;
- virtual bool GetRecyclerAllowNativeCodeBumpAllocation() const override;
- virtual bool IsPRNGSeeded() const override;
- virtual intptr_t GetBuiltinFunctionsBaseAddr() const override;
- #ifdef ENABLE_SCRIPT_DEBUGGING
- virtual intptr_t GetDebuggingFlagsAddr() const override;
- virtual intptr_t GetDebugStepTypeAddr() const override;
- virtual intptr_t GetDebugFrameAddressAddr() const override;
- virtual intptr_t GetDebugScriptIdWhenSetAddr() const override;
- #endif
- virtual intptr_t GetChakraLibAddr() const override;
- virtual intptr_t GetAddr() const override;
- virtual intptr_t GetVTableAddress(VTableValue vtableType) const override;
- virtual bool IsRecyclerVerifyEnabled() const override;
- virtual uint GetRecyclerVerifyPad() const override;
- virtual Field(Js::Var)* GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex) override;
- Js::SourceTextModuleRecord* GetModuleRecord(uint moduleId) const
- {
- return javascriptLibrary->GetModuleRecord(moduleId);
- }
- void SetBuiltInLibraryFunction(JavascriptMethod entryPoint, JavascriptFunction* function);
- JavascriptFunction* GetBuiltInLibraryFunction(JavascriptMethod entryPoint);
- private:
- BuiltInLibraryFunctionMap* builtInLibraryFunctions;
- #ifdef RECYCLER_PERF_COUNTERS
- size_t bindReferenceCount;
- #endif
- ScriptContext * nextPendingClose;
- public:
- void SetNextPendingClose(ScriptContext * nextPendingClose);
- inline ScriptContext * GetNextPendingClose() const { return nextPendingClose; }
- #ifdef ENABLE_MUTATION_BREAKPOINT
- // Keep track of all breakpoints in order to properly clean up on debugger detach
- bool HasMutationBreakpoints();
- void InsertMutationBreakpoint(Js::MutationBreakpoint *mutationBreakpoint);
- #endif
- };
- class AutoDynamicCodeReference
- {
- public:
- AutoDynamicCodeReference(ScriptContext* scriptContext):
- m_scriptContext(scriptContext)
- {
- scriptContext->GetLibrary()->BeginDynamicFunctionReferences();
- }
- ~AutoDynamicCodeReference()
- {
- m_scriptContext->GetLibrary()->EndDynamicFunctionReferences();
- }
- private:
- ScriptContext* m_scriptContext;
- };
- template <typename TCacheType>
- void ScriptContext::CleanDynamicFunctionCache(TCacheType* cacheType)
- {
- // Remove eval map functions that haven't been recently used
- // TODO: Metric based on allocation size too? So don't clean if there hasn't been much allocated?
- cacheType->Clean([this](const typename TCacheType::KeyType& key, typename TCacheType::ValueType value) {
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (CONFIG_FLAG(DumpEvalStringOnRemoval))
- {
- Output::Print(_u("EvalMap: Removing Dynamic Function String from dynamic function cache: %s\n"), key.str.GetBuffer()); Output::Flush();
- }
- #endif
- });
- }
- template <class TDelegate>
- void ScriptContext::MapFunction(TDelegate mapper)
- {
- if (this->sourceList)
- {
- this->sourceList->Map([&mapper](int, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfo)
- {
- Utf8SourceInfo* sourceInfoStrongRef = sourceInfo->Get();
- if (sourceInfoStrongRef)
- {
- sourceInfoStrongRef->MapFunction(mapper);
- }
- });
- }
- }
- template <class TDelegate>
- FunctionBody* ScriptContext::FindFunction(TDelegate predicate)
- {
- FunctionBody* functionBody = nullptr;
- this->sourceList->MapUntil([&functionBody, &predicate](int, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfo) -> bool
- {
- Utf8SourceInfo* sourceInfoStrongRef = sourceInfo->Get();
- if (sourceInfoStrongRef)
- {
- functionBody = sourceInfoStrongRef->FindFunction(predicate);
- if (functionBody)
- {
- return true;
- }
- }
- return false;
- });
- return functionBody;
- }
- class AutoProfilingPhase
- {
- public:
- AutoProfilingPhase(ScriptContext* scriptcontext, Js::Phase phase) : scriptcontext(scriptcontext), phase(phase), isPhaseComplete(false)
- {
- #ifdef PROFILE_EXEC
- scriptcontext->ProfileBegin(phase);
- #endif
- }
- ~AutoProfilingPhase()
- {
- if(!this->isPhaseComplete)
- {
- EndProfile();
- }
- }
- void EndProfile()
- {
- this->isPhaseComplete = true;
- #ifdef PROFILE_EXEC
- scriptcontext->ProfileEnd(phase);
- #endif
- }
- private:
- ScriptContext* scriptcontext;
- Js::Phase phase;
- bool isPhaseComplete;
- };
- #ifdef ENABLE_SCRIPT_DEBUGGING
- // Set up a scope in which we will initialize library JS code (like Intl.js),
- // which should not be treated as user-level JS code.
- // We should not profile and should not log debugger information in such a scope.
- class AutoInitLibraryCodeScope
- {
- private:
- ScriptContext * const scriptContext;
- const bool oldIsProfilingUserCode;
- const bool oldIsDebuggerRecording;
- public:
- AutoInitLibraryCodeScope(ScriptContext *scriptContext) :
- scriptContext(scriptContext),
- oldIsProfilingUserCode(scriptContext->GetThreadContext()->IsProfilingUserCode()),
- oldIsDebuggerRecording(scriptContext->IsDebuggerRecording())
- {
- this->scriptContext->GetThreadContext()->SetIsProfilingUserCode(false);
- this->scriptContext->SetIsDebuggerRecording(false);
- }
- ~AutoInitLibraryCodeScope()
- {
- this->scriptContext->GetThreadContext()->SetIsProfilingUserCode(this->oldIsProfilingUserCode);
- this->scriptContext->SetIsDebuggerRecording(this->oldIsDebuggerRecording);
- }
- };
- #endif
- }
- #define BEGIN_TEMP_ALLOCATOR(allocator, scriptContext, name) \
- Js::TempArenaAllocatorObject *temp##allocator = scriptContext->GetTemporaryAllocator(name); \
- ArenaAllocator * allocator = temp##allocator->GetAllocator();
- #define END_TEMP_ALLOCATOR(allocator, scriptContext) \
- scriptContext->ReleaseTemporaryAllocator(temp##allocator);
- #define DECLARE_TEMP_ALLOCATOR(allocator) \
- Js::TempArenaAllocatorObject *temp##allocator = nullptr; \
- ArenaAllocator * allocator = nullptr;
- #define ACQUIRE_TEMP_ALLOCATOR(allocator, scriptContext, name) \
- temp##allocator = scriptContext->GetTemporaryAllocator(name); \
- allocator = temp##allocator->GetAllocator();
- #define RELEASE_TEMP_ALLOCATOR(allocator, scriptContext) \
- if (temp##allocator) \
- scriptContext->ReleaseTemporaryAllocator(temp##allocator);
- #define DECLARE_TEMP_GUEST_ALLOCATOR(allocator) \
- Js::TempGuestArenaAllocatorObject *tempGuest##allocator = nullptr; \
- ArenaAllocator * allocator = nullptr;
- #define ACQUIRE_TEMP_GUEST_ALLOCATOR(allocator, scriptContext, name) \
- tempGuest##allocator = scriptContext->GetTemporaryGuestAllocator(name); \
- allocator = tempGuest##allocator->GetAllocator();
- #define RELEASE_TEMP_GUEST_ALLOCATOR(allocator, scriptContext) \
- if (tempGuest##allocator) \
- scriptContext->ReleaseTemporaryGuestAllocator(tempGuest##allocator);
|