| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- //-------------------------------------------------------------------------------------------------------
- // 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 ENABLE_NATIVE_CODEGEN
- // forward ref
- struct FunctionBodyDataIDL;
- namespace Js
- {
- // - Data generated for jitting purposes
- // - Recycler-allocated, lifetime is from when a code gen work item is added to the jit queue, to when jitting is complete
- // - Also keeps the function body and inlinee function bodies alive while jitting.
- class FunctionCodeGenJitTimeData
- {
- private:
- FunctionInfo *const functionInfo;
- // Point's to an entry point if the work item needs the entry point alive- null for cases where the entry point isn't used
- EntryPointInfo *const entryPointInfo;
- // These cloned inline caches are guaranteed to have stable data while jitting, but will be collectible after jitting
- ObjTypeSpecFldInfoArray objTypeSpecFldInfoArray;
- // Globally ordered list of all object type specialized property access information (monomorphic and polymorphic caches combined).
- uint globalObjTypeSpecFldInfoCount;
- ObjTypeSpecFldInfo** globalObjTypeSpecFldInfoArray;
- // There will be a non-null entry for each profiled call site where a function is to be inlined
- FunctionCodeGenJitTimeData **inlinees;
- FunctionCodeGenJitTimeData **ldFldInlinees;
- RecyclerWeakReference<FunctionBody> *weakFuncRef;
- PolymorphicInlineCacheInfoIDL* inlineeInfo;
- PolymorphicInlineCacheInfoIDL* selfInfo;
- PolymorphicInlineCacheIDL* polymorphicInlineCaches;
- // current value of global this object, may be changed in case of script engine invalidation
- Var globalThisObject;
- // Number of functions that are to be inlined (this is not the length of the 'inlinees' array above, includes getter setter inlinee count)
- uint inlineeCount;
- // Number of counts of getter setter to be inlined. This is not an exact count as inline caches are shared and we have no way of knowing
- // accurate count.
- uint ldFldInlineeCount;
- // For polymorphic call site we will have linked list of FunctionCodeGenJitTimeData
- // Each is differentiated by id starting from 0, 1
- FunctionCodeGenJitTimeData *next;
- bool isInlined;
- // This indicates the function is aggressively Inlined(see NativeCodeGenerator::TryAggressiveInlining) .
- bool isAggressiveInliningEnabled;
- // The profiled iterations need to be determined at the time of gathering code gen data on the main thread
- const uint16 profiledIterations;
- #ifdef FIELD_ACCESS_STATS
- public:
- FieldAccessStatsPtr inlineCacheStats;
- void EnsureInlineCacheStats(Recycler* recycler);
- void AddInlineeInlineCacheStats(FunctionCodeGenJitTimeData* inlineeJitTimeData);
- #endif
- public:
- FunctionCodeGenJitTimeData(FunctionInfo *const functionInfo, EntryPointInfo *const entryPoint, bool isInlined = true);
- public:
- BVFixed *inlineesBv;
- FunctionInfo *GetFunctionInfo() const;
- FunctionBody *GetFunctionBody() const;
- Var GetGlobalThisObject() const;
- FunctionBodyDataIDL *GetJITBody() const;
- FunctionCodeGenJitTimeData *GetNext() const { return next; }
- const ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() const { return &this->objTypeSpecFldInfoArray; }
- ObjTypeSpecFldInfoArray* GetObjTypeSpecFldInfoArray() { return &this->objTypeSpecFldInfoArray; }
- EntryPointInfo* GetEntryPointInfo() const { return this->entryPointInfo; }
- public:
- const FunctionCodeGenJitTimeData *GetInlinee(const ProfileId profiledCallSiteId) const;
- FunctionCodeGenJitTimeData ** GetInlinees();
- const FunctionCodeGenJitTimeData *GetLdFldInlinee(const InlineCacheIndex inlineCacheIndex) const;
- FunctionCodeGenJitTimeData ** GetLdFldInlinees();
- FunctionCodeGenJitTimeData *AddInlinee(
- Recycler *const recycler,
- const ProfileId profiledCallSiteId,
- FunctionInfo *const inlinee,
- bool isInlined = true);
- uint InlineeCount() const;
- uint LdFldInlineeCount() const;
- bool IsLdFldInlineePresent() const { return ldFldInlineeCount != 0; }
- RecyclerWeakReference<FunctionBody> *GetWeakFuncRef() const { return this->weakFuncRef; }
- void SetWeakFuncRef(RecyclerWeakReference<FunctionBody> *weakFuncRef)
- {
- Assert(this->weakFuncRef == nullptr || weakFuncRef == nullptr || this->weakFuncRef == weakFuncRef);
- this->weakFuncRef = weakFuncRef;
- }
- void SetPolymorphicInlineInfo(PolymorphicInlineCacheInfoIDL* inlineeInfo, PolymorphicInlineCacheInfoIDL* selfInfo, PolymorphicInlineCacheIDL* polymorphicInlineCaches)
- {
- this->inlineeInfo = inlineeInfo;
- this->selfInfo = selfInfo;
- this->polymorphicInlineCaches = polymorphicInlineCaches;
- }
- FunctionCodeGenJitTimeData *AddLdFldInlinee(
- Recycler *const recycler,
- const InlineCacheIndex inlineCacheIndex,
- FunctionInfo *const inlinee);
- bool IsPolymorphicCallSite(const ProfileId profiledCallSiteId) const;
- // This function walks all the chained jittimedata and returns the one which match the functionInfo.
- // This can return null, if the functionInfo doesn't match.
- const FunctionCodeGenJitTimeData *GetJitTimeDataFromFunctionInfo(FunctionInfo *polyFunctionInfo) const;
- uint GetGlobalObjTypeSpecFldInfoCount() const { return this->globalObjTypeSpecFldInfoCount; }
- ObjTypeSpecFldInfo** GetGlobalObjTypeSpecFldInfoArray() const {return this->globalObjTypeSpecFldInfoArray; }
- ObjTypeSpecFldInfo* GetGlobalObjTypeSpecFldInfo(uint propertyInfoId) const
- {
- Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
- return this->globalObjTypeSpecFldInfoArray[propertyInfoId];
- }
- void SetGlobalObjTypeSpecFldInfo(uint propertyInfoId, ObjTypeSpecFldInfo* info) const
- {
- Assert(this->globalObjTypeSpecFldInfoArray != nullptr && propertyInfoId < this->globalObjTypeSpecFldInfoCount);
- this->globalObjTypeSpecFldInfoArray[propertyInfoId] = info;
- }
- void SetGlobalObjTypeSpecFldInfoArray(ObjTypeSpecFldInfo** array, uint count)
- {
- Assert(array != nullptr);
- this->globalObjTypeSpecFldInfoArray = array;
- this->globalObjTypeSpecFldInfoCount = count;
- }
- bool GetIsInlined() const
- {
- return isInlined;
- }
- bool GetIsAggressiveInliningEnabled() const
- {
- return isAggressiveInliningEnabled;
- }
- void SetIsAggressiveInliningEnabled()
- {
- isAggressiveInliningEnabled = true;
- }
- void SetupRecursiveInlineeChain(
- Recycler *const recycler,
- const ProfileId profiledCallSiteId)
- {
- if (!inlinees)
- {
- inlinees = RecyclerNewArrayZ(recycler, FunctionCodeGenJitTimeData *, GetFunctionBody()->GetProfiledCallSiteCount());
- }
- inlinees[profiledCallSiteId] = this;
- inlineeCount++;
- }
- uint16 GetProfiledIterations() const;
- PREVENT_COPY(FunctionCodeGenJitTimeData)
- };
- }
- #endif
|