| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- JITTimeFunctionBody::JITTimeFunctionBody(FunctionBodyDataIDL * bodyData) :
- m_bodyData(*bodyData)
- {
- CompileAssert(sizeof(JITTimeFunctionBody) == sizeof(FunctionBodyDataIDL));
- }
- /* static */
- void
- JITTimeFunctionBody::InitializeJITFunctionData(
- __in ArenaAllocator * arena,
- __in Js::FunctionBody *functionBody,
- __out FunctionBodyDataIDL * jitBody)
- {
- Assert(functionBody != nullptr);
- // const table
- jitBody->constCount = functionBody->GetConstantCount();
- if (functionBody->GetConstantCount() > 0)
- {
- jitBody->constTable = (intptr_t *)PointerValue(functionBody->GetConstTable());
- if (!functionBody->GetIsAsmJsFunction())
- {
- jitBody->constTableContent = AnewStructZ(arena, ConstTableContentIDL);
- jitBody->constTableContent->count = functionBody->GetConstantCount();
- jitBody->constTableContent->content = AnewArrayZ(arena, RecyclableObjectIDL*, functionBody->GetConstantCount());
- for (Js::RegSlot reg = Js::FunctionBody::FirstRegSlot; reg < functionBody->GetConstantCount(); ++reg)
- {
- Js::Var varConst = functionBody->GetConstantVar(reg);
- Assert(varConst != nullptr);
- if (Js::TaggedInt::Is(varConst) ||
- varConst == (Js::Var)&Js::NullFrameDisplay ||
- varConst == (Js::Var)&Js::StrictNullFrameDisplay)
- {
- // don't need TypeId for these
- }
- else
- {
- if (Js::TaggedNumber::Is(varConst))
- {
- // the typeid should be TypeIds_Number, determine this directly from const table
- }
- else
- {
- jitBody->constTableContent->content[reg - Js::FunctionBody::FirstRegSlot] = (RecyclableObjectIDL*)varConst;
- }
- }
- }
- }
- else if (functionBody->IsWasmFunction())
- {
- // no consts in wasm
- Assert(jitBody->constTable == nullptr);
- jitBody->constCount = 0;
- }
- }
- Js::SmallSpanSequence * statementMap = functionBody->GetStatementMapSpanSequence();
- // REVIEW: OOP JIT, is it possible for this to not match with isJitInDebugMode?
- if (functionBody->IsInDebugMode())
- {
- Assert(!statementMap);
- jitBody->byteCodeLength = functionBody->GetOriginalByteCode()->GetLength();
- jitBody->byteCodeBuffer = functionBody->GetOriginalByteCode()->GetBuffer();
- auto fullStatementMaps = functionBody->GetStatementMaps();
- jitBody->fullStatementMapCount = fullStatementMaps->Count();
- jitBody->fullStatementMaps = AnewArrayZ(arena, StatementMapIDL, jitBody->fullStatementMapCount);
- fullStatementMaps->Map([jitBody](int index, Js::FunctionBody::StatementMap * map) {
- jitBody->fullStatementMaps[index] = *(StatementMapIDL*)map;
- Assert(jitBody->fullStatementMaps[index].byteCodeSpanBegin == map->byteCodeSpan.Begin());
- Assert(jitBody->fullStatementMaps[index].byteCodeSpanEnd == map->byteCodeSpan.End());
- Assert(jitBody->fullStatementMaps[index].sourceSpanBegin == map->sourceSpan.Begin());
- Assert(jitBody->fullStatementMaps[index].sourceSpanEnd == map->sourceSpan.End());
- Assert((jitBody->fullStatementMaps[index].isSubExpression != FALSE) == map->isSubexpression);
- });
- Js::PropertyIdOnRegSlotsContainer * propOnRegSlots = functionBody->GetPropertyIdOnRegSlotsContainerWithLock();
- if (propOnRegSlots)
- {
- jitBody->propertyIdsForRegSlotsCount = propOnRegSlots->length;
- jitBody->propertyIdsForRegSlots = propOnRegSlots->propertyIdsForRegSlots;
- }
- }
- else
- {
- jitBody->byteCodeLength = functionBody->GetByteCode()->GetLength();
- jitBody->byteCodeBuffer = functionBody->GetByteCode()->GetBuffer();
- if (!functionBody->IsWasmFunction()) {
- Assert(statementMap);
- jitBody->statementMap = AnewStructZ(arena, SmallSpanSequenceIDL);
- jitBody->statementMap->baseValue = statementMap->baseValue;
- if (statementMap->pActualOffsetList)
- {
- jitBody->statementMap->actualOffsetLength = statementMap->pActualOffsetList->Count();
- jitBody->statementMap->actualOffsetList = statementMap->pActualOffsetList->GetBuffer();
- }
- if (statementMap->pStatementBuffer)
- {
- jitBody->statementMap->statementLength = statementMap->pStatementBuffer->Count();
- jitBody->statementMap->statementBuffer = statementMap->pStatementBuffer->GetBuffer();
- }
- }
- }
- jitBody->inlineCacheCount = functionBody->GetInlineCacheCount();
- if (functionBody->GetInlineCacheCount() > 0)
- {
- jitBody->cacheIdToPropertyIdMap = functionBody->GetCacheIdToPropertyIdMap();
- }
- jitBody->inlineCaches = reinterpret_cast<intptr_t*>(functionBody->GetInlineCaches());
- // body data
- jitBody->functionBodyAddr = (intptr_t)functionBody;
- jitBody->funcNumber = functionBody->GetFunctionNumber();
- jitBody->sourceContextId = functionBody->GetSourceContextId();
- jitBody->nestedCount = functionBody->GetNestedCount();
- if (functionBody->GetNestedCount() > 0)
- {
- jitBody->nestedFuncArrayAddr = (intptr_t)functionBody->GetNestedFuncArray();
- }
- jitBody->scopeSlotArraySize = functionBody->scopeSlotArraySize;
- jitBody->paramScopeSlotArraySize = functionBody->paramScopeSlotArraySize;
- jitBody->attributes = functionBody->GetAttributes();
- jitBody->isInstInlineCacheCount = functionBody->GetIsInstInlineCacheCount();
- jitBody->byteCodeCount = functionBody->GetByteCodeCount();
- jitBody->byteCodeInLoopCount = functionBody->GetByteCodeInLoopCount();
- jitBody->nonLoadByteCodeCount = functionBody->GetByteCodeWithoutLDACount();
- jitBody->loopCount = functionBody->GetLoopCount();
- Js::LoopHeader * loopHeaders = functionBody->GetLoopHeaderArrayWithLock();
- if (loopHeaders != nullptr)
- {
- jitBody->loopHeaderArrayAddr = (intptr_t)loopHeaders;
- jitBody->loopHeaderArrayLength = functionBody->GetLoopCount();
- jitBody->loopHeaders = AnewArray(arena, JITLoopHeaderIDL, functionBody->GetLoopCount());
- for (uint i = 0; i < functionBody->GetLoopCount(); ++i)
- {
- jitBody->loopHeaders[i].startOffset = loopHeaders[i].startOffset;
- jitBody->loopHeaders[i].endOffset = loopHeaders[i].endOffset;
- jitBody->loopHeaders[i].isNested = loopHeaders[i].isNested;
- jitBody->loopHeaders[i].isInTry = loopHeaders[i].isInTry;
- jitBody->loopHeaders[i].interpretCount = functionBody->GetLoopInterpretCount(&loopHeaders[i]);
- }
- }
- jitBody->localFrameDisplayReg = functionBody->GetLocalFrameDisplayRegister();
- jitBody->localClosureReg = functionBody->GetLocalClosureRegister();
- jitBody->envReg = functionBody->GetEnvRegister();
- jitBody->firstTmpReg = functionBody->GetFirstTmpReg();
- jitBody->varCount = functionBody->GetVarCount();
- jitBody->innerScopeCount = functionBody->GetInnerScopeCount();
- if (functionBody->GetInnerScopeCount() > 0)
- {
- jitBody->firstInnerScopeReg = functionBody->GetFirstInnerScopeRegister();
- }
- jitBody->envDepth = functionBody->GetEnvDepth();
- jitBody->profiledCallSiteCount = functionBody->GetProfiledCallSiteCount();
- jitBody->inParamCount = functionBody->GetInParamsCount();
- jitBody->thisRegisterForEventHandler = functionBody->GetThisRegisterForEventHandler();
- jitBody->funcExprScopeRegister = functionBody->GetFuncExprScopeRegister();
- jitBody->recursiveCallSiteCount = functionBody->GetNumberOfRecursiveCallSites();
- jitBody->forInLoopDepth = functionBody->GetForInLoopDepth();
- jitBody->argUsedForBranch = functionBody->m_argUsedForBranch;
- jitBody->flags = functionBody->GetFlags();
- jitBody->doBackendArgumentsOptimization = functionBody->GetDoBackendArgumentsOptimization();
- jitBody->isLibraryCode = functionBody->GetUtf8SourceInfo()->GetIsLibraryCode();
- jitBody->isAsmJsMode = functionBody->GetIsAsmjsMode();
- jitBody->isWasmFunction = functionBody->IsWasmFunction();
- jitBody->isStrictMode = functionBody->GetIsStrictMode();
- jitBody->isEval = functionBody->IsEval();
- jitBody->isGlobalFunc = functionBody->GetIsGlobalFunc();
- jitBody->isInlineApplyDisabled = functionBody->IsInlineApplyDisabled();
- jitBody->doJITLoopBody = functionBody->DoJITLoopBody();
- jitBody->hasScopeObject = functionBody->HasScopeObject();
- jitBody->hasImplicitArgIns = functionBody->GetHasImplicitArgIns();
- jitBody->hasCachedScopePropIds = functionBody->HasCachedScopePropIds();
- jitBody->inlineCachesOnFunctionObject = functionBody->GetInlineCachesOnFunctionObject();
- jitBody->doInterruptProbe = functionBody->GetScriptContext()->GetThreadContext()->DoInterruptProbe(functionBody);
- jitBody->disableInlineSpread = functionBody->IsInlineSpreadDisabled();
- jitBody->hasNestedLoop = functionBody->GetHasNestedLoop();
- jitBody->isParamAndBodyScopeMerged = functionBody->IsParamAndBodyScopeMerged();
- jitBody->paramClosureReg = functionBody->GetParamClosureRegister();
- jitBody->usesArgumentsObject = functionBody->GetUsesArgumentsObject();
- jitBody->doScopeObjectCreation = functionBody->GetDoScopeObjectCreation();
-
- //CompileAssert(sizeof(PropertyIdArrayIDL) == sizeof(Js::PropertyIdArray));
- jitBody->formalsPropIdArray = (PropertyIdArrayIDL*)functionBody->GetFormalsPropIdArray(false);
- jitBody->formalsPropIdArrayAddr = (intptr_t)functionBody->GetFormalsPropIdArray(false);
- jitBody->forInCacheArrayAddr = (intptr_t)functionBody->GetForInCacheArray();
- if (functionBody->HasDynamicProfileInfo() && Js::DynamicProfileInfo::HasCallSiteInfo(functionBody))
- {
- jitBody->hasNonBuiltInCallee = functionBody->HasNonBuiltInCallee();
- }
- Js::ByteBlock * auxData = functionBody->GetAuxiliaryDataWithLock();
- if (auxData != nullptr)
- {
- jitBody->auxDataCount = auxData->GetLength();
- jitBody->auxData = auxData->GetBuffer();
- jitBody->auxDataBufferAddr = (intptr_t)auxData->GetBuffer();
- }
- Js::ByteBlock * auxContextData = functionBody->GetAuxiliaryContextDataWithLock();
- if (auxContextData != nullptr)
- {
- jitBody->auxContextDataCount = auxContextData->GetLength();
- jitBody->auxContextData = auxContextData->GetBuffer();
- }
- jitBody->scriptIdAddr = (intptr_t)functionBody->GetAddressOfScriptId();
- jitBody->flagsAddr = (intptr_t)functionBody->GetAddressOfFlags();
- jitBody->probeCountAddr = (intptr_t)&functionBody->GetSourceInfo()->m_probeCount;
- jitBody->regAllocLoadCountAddr = (intptr_t)&functionBody->regAllocLoadCount;
- jitBody->regAllocStoreCountAddr = (intptr_t)&functionBody->regAllocStoreCount;
- jitBody->callCountStatsAddr = (intptr_t)&functionBody->callCountStats;
- jitBody->referencedPropertyIdCount = functionBody->GetReferencedPropertyIdCount();
- jitBody->referencedPropertyIdMap = functionBody->GetReferencedPropertyIdMapWithLock();
- jitBody->hasFinally = functionBody->GetHasFinally();
- jitBody->nameLength = functionBody->GetDisplayNameLength() + 1; // +1 for null terminator
- jitBody->displayName = (char16 *)functionBody->GetDisplayName();
- jitBody->objectLiteralTypesAddr = (intptr_t)functionBody->GetObjectLiteralTypesWithLock();
- jitBody->literalRegexCount = functionBody->GetLiteralRegexCount();
- jitBody->literalRegexes = (intptr_t*)functionBody->GetLiteralRegexesWithLock();
- #ifdef ASMJS_PLAT
- if (functionBody->GetIsAsmJsFunction())
- {
- jitBody->asmJsData = Anew(arena, AsmJsDataIDL);
- Js::AsmJsFunctionInfo * asmFuncInfo = functionBody->GetAsmJsFunctionInfoWithLock();
- // 5 is hard coded in JITTypes.h
- CompileAssert(WAsmJs::LIMIT == 5);
- for (int i = 0; i < WAsmJs::LIMIT; ++i)
- {
- WAsmJs::Types type = (WAsmJs::Types)i;
- const auto typedInfo = asmFuncInfo->GetTypedSlotInfo(type);
- jitBody->asmJsData->typedSlotInfos[i].byteOffset = typedInfo->byteOffset;
- jitBody->asmJsData->typedSlotInfos[i].constCount = typedInfo->constCount;
- jitBody->asmJsData->typedSlotInfos[i].constSrcByteOffset = typedInfo->constSrcByteOffset;
- jitBody->asmJsData->typedSlotInfos[i].tmpCount = typedInfo->tmpCount;
- jitBody->asmJsData->typedSlotInfos[i].varCount = typedInfo->varCount;
- }
- jitBody->asmJsData->argCount = asmFuncInfo->GetArgCount();
- jitBody->asmJsData->argTypeArray = (byte*)asmFuncInfo->GetArgTypeArray();
- jitBody->asmJsData->argByteSize = asmFuncInfo->GetArgByteSize();
- jitBody->asmJsData->retType = asmFuncInfo->GetReturnType().which();
- jitBody->asmJsData->isHeapBufferConst = asmFuncInfo->IsHeapBufferConst();
- jitBody->asmJsData->usesHeapBuffer = asmFuncInfo->UsesHeapBuffer();
- jitBody->asmJsData->totalSizeInBytes = asmFuncInfo->GetTotalSizeinBytes();
- #ifdef ENABLE_WASM
- if (functionBody->IsWasmFunction())
- {
- jitBody->asmJsData->wasmSignatureCount = asmFuncInfo->GetWebAssemblyModule()->GetSignatureCount();
- jitBody->asmJsData->wasmSignaturesBaseAddr = (intptr_t)asmFuncInfo->GetWebAssemblyModule()->GetSignatures();
- jitBody->asmJsData->wasmSignatures = (WasmSignatureIDL*)asmFuncInfo->GetWebAssemblyModule()->GetSignatures();
- }
- #endif
- }
- #endif
- }
- intptr_t
- JITTimeFunctionBody::GetAddr() const
- {
- return m_bodyData.functionBodyAddr;
- }
- uint
- JITTimeFunctionBody::GetFunctionNumber() const
- {
- return m_bodyData.funcNumber;
- }
- uint
- JITTimeFunctionBody::GetSourceContextId() const
- {
- return m_bodyData.sourceContextId;
- }
- uint
- JITTimeFunctionBody::GetNestedCount() const
- {
- return m_bodyData.nestedCount;
- }
- uint
- JITTimeFunctionBody::GetScopeSlotArraySize() const
- {
- return m_bodyData.scopeSlotArraySize;
- }
- uint
- JITTimeFunctionBody::GetParamScopeSlotArraySize() const
- {
- return m_bodyData.paramScopeSlotArraySize;
- }
- uint
- JITTimeFunctionBody::GetByteCodeCount() const
- {
- return m_bodyData.byteCodeCount;
- }
- uint
- JITTimeFunctionBody::GetByteCodeInLoopCount() const
- {
- return m_bodyData.byteCodeInLoopCount;
- }
- uint
- JITTimeFunctionBody::GetNonLoadByteCodeCount() const
- {
- return m_bodyData.nonLoadByteCodeCount;
- }
- uint
- JITTimeFunctionBody::GetLoopCount() const
- {
- return m_bodyData.loopCount;
- }
- bool
- JITTimeFunctionBody::HasLoops() const
- {
- return GetLoopCount() != 0;
- }
- uint
- JITTimeFunctionBody::GetByteCodeLength() const
- {
- return m_bodyData.byteCodeLength;
- }
- uint
- JITTimeFunctionBody::GetInnerScopeCount() const
- {
- return m_bodyData.innerScopeCount;
- }
- uint
- JITTimeFunctionBody::GetInlineCacheCount() const
- {
- return m_bodyData.inlineCacheCount;
- }
- uint
- JITTimeFunctionBody::GetRecursiveCallSiteCount() const
- {
- return m_bodyData.recursiveCallSiteCount;
- }
- uint
- JITTimeFunctionBody::GetForInLoopDepth() const
- {
- return m_bodyData.forInLoopDepth;
- }
- Js::RegSlot
- JITTimeFunctionBody::GetLocalFrameDisplayReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.localFrameDisplayReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetLocalClosureReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.localClosureReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetEnvReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.envReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetFirstTmpReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.firstTmpReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetFirstInnerScopeReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.firstInnerScopeReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetVarCount() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.varCount);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetConstCount() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.constCount);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetLocalsCount() const
- {
- return GetConstCount() + GetVarCount();
- }
- Js::RegSlot
- JITTimeFunctionBody::GetTempCount() const
- {
- return GetLocalsCount() - GetFirstTmpReg();
- }
- Js::RegSlot
- JITTimeFunctionBody::GetFuncExprScopeReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.funcExprScopeRegister);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetThisRegForEventHandler() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.thisRegisterForEventHandler);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetParamClosureReg() const
- {
- return static_cast<Js::RegSlot>(m_bodyData.paramClosureReg);
- }
- Js::RegSlot
- JITTimeFunctionBody::GetFirstNonTempLocalIndex() const
- {
- // First local var starts when the const vars end.
- return GetConstCount();
- }
- Js::RegSlot
- JITTimeFunctionBody::GetEndNonTempLocalIndex() const
- {
- // It will give the index on which current non temp locals ends, which is a first temp reg.
- return GetFirstTmpReg() != Js::Constants::NoRegister ? GetFirstTmpReg() : GetLocalsCount();
- }
- Js::RegSlot
- JITTimeFunctionBody::GetNonTempLocalVarCount() const
- {
- Assert(GetEndNonTempLocalIndex() >= GetFirstNonTempLocalIndex());
- return GetEndNonTempLocalIndex() - GetFirstNonTempLocalIndex();
- }
- Js::RegSlot
- JITTimeFunctionBody::GetRestParamRegSlot() const
- {
- Js::RegSlot dstRegSlot = GetConstCount();
- if (HasImplicitArgIns())
- {
- dstRegSlot += GetInParamsCount() - 1;
- }
- return dstRegSlot;
- }
- Js::PropertyId
- JITTimeFunctionBody::GetPropertyIdFromCacheId(uint cacheId) const
- {
- Assert(m_bodyData.cacheIdToPropertyIdMap);
- Assert(cacheId < GetInlineCacheCount());
- return static_cast<Js::PropertyId>(m_bodyData.cacheIdToPropertyIdMap[cacheId]);
- }
- Js::PropertyId
- JITTimeFunctionBody::GetReferencedPropertyId(uint index) const
- {
- if (index < (uint)TotalNumberOfBuiltInProperties)
- {
- return index;
- }
- uint mapIndex = index - TotalNumberOfBuiltInProperties;
- Assert(m_bodyData.referencedPropertyIdMap != nullptr);
- Assert(mapIndex < m_bodyData.referencedPropertyIdCount);
- return m_bodyData.referencedPropertyIdMap[mapIndex];
- }
- uint16
- JITTimeFunctionBody::GetArgUsedForBranch() const
- {
- return m_bodyData.argUsedForBranch;
- }
- uint16
- JITTimeFunctionBody::GetEnvDepth() const
- {
- return m_bodyData.envDepth;
- }
- Js::ProfileId
- JITTimeFunctionBody::GetProfiledCallSiteCount() const
- {
- return static_cast<Js::ProfileId>(m_bodyData.profiledCallSiteCount);
- }
- Js::ArgSlot
- JITTimeFunctionBody::GetInParamsCount() const
- {
- return static_cast<Js::ArgSlot>(m_bodyData.inParamCount);
- }
- bool
- JITTimeFunctionBody::DoStackNestedFunc() const
- {
- return Js::FunctionBody::DoStackNestedFunc(GetFlags());
- }
- bool
- JITTimeFunctionBody::DoStackClosure() const
- {
- return Js::FunctionBody::DoStackClosure(this);
- }
- bool
- JITTimeFunctionBody::HasTry() const
- {
- return Js::FunctionBody::GetHasTry(GetFlags());
- }
- bool
- JITTimeFunctionBody::HasThis() const
- {
- return Js::FunctionBody::GetHasThis(GetFlags());
- }
- bool
- JITTimeFunctionBody::HasFinally() const
- {
- return m_bodyData.hasFinally != FALSE;
- }
- bool
- JITTimeFunctionBody::HasOrParentHasArguments() const
- {
- return Js::FunctionBody::GetHasOrParentHasArguments(GetFlags());
- }
- bool
- JITTimeFunctionBody::DoBackendArgumentsOptimization() const
- {
- return m_bodyData.doBackendArgumentsOptimization != FALSE;
- }
- bool
- JITTimeFunctionBody::IsLibraryCode() const
- {
- return m_bodyData.isLibraryCode != FALSE;
- }
- bool
- JITTimeFunctionBody::IsAsmJsMode() const
- {
- return m_bodyData.isAsmJsMode != FALSE;
- }
- bool
- JITTimeFunctionBody::IsWasmFunction() const
- {
- return m_bodyData.isWasmFunction != FALSE;
- }
- bool
- JITTimeFunctionBody::IsStrictMode() const
- {
- return m_bodyData.isStrictMode != FALSE;
- }
- bool
- JITTimeFunctionBody::IsEval() const
- {
- return m_bodyData.isEval != FALSE;
- }
- bool
- JITTimeFunctionBody::HasScopeObject() const
- {
- return m_bodyData.hasScopeObject != FALSE;
- }
- bool
- JITTimeFunctionBody::HasNestedLoop() const
- {
- return m_bodyData.hasNestedLoop != FALSE;
- }
- bool
- JITTimeFunctionBody::UsesArgumentsObject() const
- {
- return m_bodyData.usesArgumentsObject != FALSE;
- }
- bool
- JITTimeFunctionBody::IsParamAndBodyScopeMerged() const
- {
- return m_bodyData.isParamAndBodyScopeMerged != FALSE;
- }
- bool
- JITTimeFunctionBody::IsCoroutine() const
- {
- return Js::FunctionInfo::IsCoroutine(GetAttributes());
- }
- bool
- JITTimeFunctionBody::IsGenerator() const
- {
- return Js::FunctionInfo::IsGenerator(GetAttributes());
- }
- bool
- JITTimeFunctionBody::IsLambda() const
- {
- return Js::FunctionInfo::IsLambda(GetAttributes());
- }
- bool
- JITTimeFunctionBody::HasImplicitArgIns() const
- {
- return m_bodyData.hasImplicitArgIns != FALSE;
- }
- bool
- JITTimeFunctionBody::HasCachedScopePropIds() const
- {
- return m_bodyData.hasCachedScopePropIds != FALSE;
- }
- bool
- JITTimeFunctionBody::HasInlineCachesOnFunctionObject() const
- {
- return m_bodyData.inlineCachesOnFunctionObject != FALSE;
- }
- bool
- JITTimeFunctionBody::DoInterruptProbe() const
- {
- // TODO michhol: this is technically a threadcontext flag,
- // may want to pass all these when initializing thread context
- return m_bodyData.doInterruptProbe != FALSE;
- }
- bool
- JITTimeFunctionBody::HasRestParameter() const
- {
- return Js::FunctionBody::GetHasRestParameter(GetFlags());
- }
- bool
- JITTimeFunctionBody::IsGlobalFunc() const
- {
- return m_bodyData.isGlobalFunc != FALSE;
- }
- void
- JITTimeFunctionBody::DisableInlineApply()
- {
- m_bodyData.isInlineApplyDisabled = TRUE;
- }
- bool
- JITTimeFunctionBody::IsInlineApplyDisabled() const
- {
- return m_bodyData.isInlineApplyDisabled != FALSE;
- }
- bool
- JITTimeFunctionBody::IsNonTempLocalVar(uint32 varIndex) const
- {
- return GetFirstNonTempLocalIndex() <= varIndex && varIndex < GetEndNonTempLocalIndex();
- }
- bool
- JITTimeFunctionBody::DoJITLoopBody() const
- {
- return m_bodyData.doJITLoopBody != FALSE;
- }
- void
- JITTimeFunctionBody::DisableInlineSpread()
- {
- m_bodyData.disableInlineSpread = TRUE;
- }
- bool
- JITTimeFunctionBody::IsInlineSpreadDisabled() const
- {
- return m_bodyData.disableInlineSpread != FALSE;
- }
- bool
- JITTimeFunctionBody::HasNonBuiltInCallee() const
- {
- return m_bodyData.hasNonBuiltInCallee != FALSE;
- }
- bool
- JITTimeFunctionBody::CanInlineRecursively(uint depth, bool tryAggressive) const
- {
- uint recursiveInlineSpan = GetRecursiveCallSiteCount();
- uint minRecursiveInlineDepth = (uint)CONFIG_FLAG(RecursiveInlineDepthMin);
- if (recursiveInlineSpan != GetProfiledCallSiteCount() || tryAggressive == false)
- {
- return depth < minRecursiveInlineDepth;
- }
- uint maxRecursiveInlineDepth = (uint)CONFIG_FLAG(RecursiveInlineDepthMax);
- uint maxRecursiveBytecodeBudget = (uint)CONFIG_FLAG(RecursiveInlineThreshold);
- uint numberOfAllowedFuncs = maxRecursiveBytecodeBudget / GetNonLoadByteCodeCount();
- uint maxDepth;
- if (recursiveInlineSpan == 1)
- {
- maxDepth = numberOfAllowedFuncs;
- }
- else
- {
- maxDepth = (uint)ceil(log((double)((double)numberOfAllowedFuncs) / log((double)recursiveInlineSpan)));
- }
- maxDepth = maxDepth < minRecursiveInlineDepth ? minRecursiveInlineDepth : maxDepth;
- maxDepth = maxDepth < maxRecursiveInlineDepth ? maxDepth : maxRecursiveInlineDepth;
- return depth < maxDepth;
- }
- bool
- JITTimeFunctionBody::NeedScopeObjectForArguments(bool hasNonSimpleParams) const
- {
- // TODO: OOP JIT, enable assert
- //Assert(HasReferenceableBuiltInArguments());
- // We can avoid creating a scope object with arguments present if:
- bool dontNeedScopeObject =
- // Either we are in strict mode, or have strict mode formal semantics from a non-simple parameter list, and
- (IsStrictMode() || hasNonSimpleParams)
- // Neither of the scopes are objects
- && !HasScopeObject();
- return
- // Regardless of the conditions above, we won't need a scope object if there aren't any formals.
- (GetInParamsCount() > 1 || HasRestParameter())
- && !dontNeedScopeObject;
- }
- bool
- JITTimeFunctionBody::GetDoScopeObjectCreation() const
- {
- return !!m_bodyData.doScopeObjectCreation;
- }
- const byte *
- JITTimeFunctionBody::GetByteCodeBuffer() const
- {
- return m_bodyData.byteCodeBuffer;
- }
- StatementMapIDL *
- JITTimeFunctionBody::GetFullStatementMap() const
- {
- return m_bodyData.fullStatementMaps;
- }
- uint
- JITTimeFunctionBody::GetFullStatementMapCount() const
- {
- return m_bodyData.fullStatementMapCount;
- }
- intptr_t
- JITTimeFunctionBody::GetScriptIdAddr() const
- {
- return m_bodyData.scriptIdAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetProbeCountAddr() const
- {
- return m_bodyData.probeCountAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetFlagsAddr() const
- {
- return m_bodyData.flagsAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetRegAllocLoadCountAddr() const
- {
- return m_bodyData.regAllocLoadCountAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetFormalsPropIdArrayAddr() const
- {
- return m_bodyData.formalsPropIdArrayAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetRegAllocStoreCountAddr() const
- {
- return m_bodyData.regAllocStoreCountAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetCallCountStatsAddr() const
- {
- return m_bodyData.callCountStatsAddr;
- }
- intptr_t
- JITTimeFunctionBody::GetObjectLiteralTypeRef(uint index) const
- {
- Assert(m_bodyData.objectLiteralTypesAddr != 0);
- return m_bodyData.objectLiteralTypesAddr + index * MachPtr;
- }
- intptr_t
- JITTimeFunctionBody::GetConstantVar(Js::RegSlot location) const
- {
- Assert(m_bodyData.constTable != nullptr);
- Assert(location < GetConstCount());
- Assert(location != 0);
- return static_cast<intptr_t>(m_bodyData.constTable[location - Js::FunctionBody::FirstRegSlot]);
- }
- JITRecyclableObject *
- JITTimeFunctionBody::GetConstantContent(Js::RegSlot location) const
- {
- Assert(m_bodyData.constTableContent != nullptr);
- Assert(m_bodyData.constTableContent->content != nullptr);
- Assert(location < GetConstCount());
- Assert(location != 0);
- JITRecyclableObject * obj = (JITRecyclableObject *)m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
- Assert(obj);
- return obj;
- }
- intptr_t
- JITTimeFunctionBody::GetInlineCache(uint index) const
- {
- Assert(m_bodyData.inlineCaches != nullptr);
- Assert(index < GetInlineCacheCount());
- #if 0 // TODO: michhol OOP JIT, add these asserts
- Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
- this->m_inlineCacheTypes[index] == InlineCacheTypeInlineCache);
- this->m_inlineCacheTypes[index] = InlineCacheTypeInlineCache;
- #endif
- return static_cast<intptr_t>(m_bodyData.inlineCaches[index]);
- }
- intptr_t
- JITTimeFunctionBody::GetIsInstInlineCache(uint index) const
- {
- Assert(m_bodyData.inlineCaches != nullptr);
- Assert(index < m_bodyData.isInstInlineCacheCount);
- index += GetInlineCacheCount();
- #if 0 // TODO: michhol OOP JIT, add these asserts
- Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
- this->m_inlineCacheTypes[index] == InlineCacheTypeIsInst);
- this->m_inlineCacheTypes[index] = InlineCacheTypeIsInst;
- #endif
- return static_cast<intptr_t>(m_bodyData.inlineCaches[index]);
- }
- Js::TypeId
- JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const
- {
- Assert(m_bodyData.constTable != nullptr);
- Assert(m_bodyData.constTableContent != nullptr);
- Assert(location < GetConstCount());
- Assert(location != 0);
- auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
- if (obj == nullptr)
- {
- if (Js::TaggedNumber::Is((Js::Var)GetConstantVar(location)))
- {
- // tagged float
- return Js::TypeId::TypeIds_Number;
- }
- else
- {
- return Js::TypeId::TypeIds_Limit;
- }
- }
- return static_cast<Js::TypeId>(*(obj->typeId));
- }
- intptr_t
- JITTimeFunctionBody::GetLiteralRegexAddr(uint index) const
- {
- Assert(index < m_bodyData.literalRegexCount);
- return m_bodyData.literalRegexes[index];
- }
- void *
- JITTimeFunctionBody::GetConstTable() const
- {
- return m_bodyData.constTable;
- }
- bool
- JITTimeFunctionBody::IsConstRegPropertyString(Js::RegSlot reg, ScriptContextInfo * context) const
- {
- RecyclableObjectIDL * content = m_bodyData.constTableContent->content[reg - Js::FunctionBody::FirstRegSlot];
- if (content != nullptr && content->vtbl == context->GetVTableAddress(VtablePropertyString))
- {
- return true;
- }
- return false;
- }
- intptr_t
- JITTimeFunctionBody::GetRootObject() const
- {
- Assert(m_bodyData.constTable != nullptr);
- return m_bodyData.constTable[Js::FunctionBody::RootObjectRegSlot - Js::FunctionBody::FirstRegSlot];
- }
- Js::FunctionInfoPtrPtr
- JITTimeFunctionBody::GetNestedFuncRef(uint index) const
- {
- Assert(index < GetNestedCount());
- Js::FunctionInfoPtrPtr baseAddr = (Js::FunctionInfoPtrPtr)m_bodyData.nestedFuncArrayAddr;
- return baseAddr + index;
- }
- intptr_t
- JITTimeFunctionBody::GetLoopHeaderAddr(uint loopNum) const
- {
- Assert(loopNum < GetLoopCount());
- intptr_t baseAddr = m_bodyData.loopHeaderArrayAddr;
- return baseAddr + (loopNum * sizeof(Js::LoopHeader));
- }
- const JITLoopHeaderIDL *
- JITTimeFunctionBody::GetLoopHeaderData(uint loopNum) const
- {
- Assert(loopNum < GetLoopCount());
- return &m_bodyData.loopHeaders[loopNum];
- }
- const AsmJsJITInfo *
- JITTimeFunctionBody::GetAsmJsInfo() const
- {
- return reinterpret_cast<const AsmJsJITInfo *>(m_bodyData.asmJsData);
- }
- JITTimeProfileInfo *
- JITTimeFunctionBody::GetProfileInfo() const
- {
- return reinterpret_cast<JITTimeProfileInfo *>(m_bodyData.profileData);
- }
- const JITTimeProfileInfo *
- JITTimeFunctionBody::GetReadOnlyProfileInfo() const
- {
- return reinterpret_cast<const JITTimeProfileInfo *>(m_bodyData.profileData);
- }
- bool
- JITTimeFunctionBody::HasProfileInfo() const
- {
- return m_bodyData.profileData != nullptr;
- }
- bool
- JITTimeFunctionBody::HasPropIdToFormalsMap() const
- {
- return m_bodyData.propertyIdsForRegSlotsCount > 0 && GetFormalsPropIdArray() != nullptr;
- }
- bool
- JITTimeFunctionBody::IsRegSlotFormal(Js::RegSlot reg) const
- {
- Assert(reg < m_bodyData.propertyIdsForRegSlotsCount);
- Js::PropertyId propId = (Js::PropertyId)m_bodyData.propertyIdsForRegSlots[reg];
- Js::PropertyIdArray * formalProps = GetFormalsPropIdArray();
- for (uint32 i = 0; i < formalProps->count; i++)
- {
- if (formalProps->elements[i] == propId)
- {
- return true;
- }
- }
- return false;
- }
- /* static */
- bool
- JITTimeFunctionBody::LoopContains(const JITLoopHeaderIDL * loop1, const JITLoopHeaderIDL * loop2)
- {
- return (loop1->startOffset <= loop2->startOffset && loop2->endOffset <= loop1->endOffset);
- }
- Js::FunctionBody::FunctionBodyFlags
- JITTimeFunctionBody::GetFlags() const
- {
- return static_cast<Js::FunctionBody::FunctionBodyFlags>(m_bodyData.flags);
- }
- Js::FunctionInfo::Attributes
- JITTimeFunctionBody::GetAttributes() const
- {
- return static_cast<Js::FunctionInfo::Attributes>(m_bodyData.attributes);
- }
- intptr_t
- JITTimeFunctionBody::GetAuxDataAddr(uint offset) const
- {
- return m_bodyData.auxDataBufferAddr + offset;
- }
- void *
- JITTimeFunctionBody::ReadFromAuxData(uint offset) const
- {
- return (void *)(m_bodyData.auxData + offset);
- }
- void *
- JITTimeFunctionBody::ReadFromAuxContextData(uint offset) const
- {
- return (void *)(m_bodyData.auxContextData + offset);
- }
- const Js::PropertyIdArray *
- JITTimeFunctionBody::ReadPropertyIdArrayFromAuxData(uint offset) const
- {
- Js::PropertyIdArray * auxArray = (Js::PropertyIdArray *)(m_bodyData.auxData + offset);
- Assert(offset + auxArray->GetDataSize() <= m_bodyData.auxDataCount);
- return auxArray;
- }
- Js::PropertyIdArray *
- JITTimeFunctionBody::GetFormalsPropIdArray() const
- {
- return (Js::PropertyIdArray *)m_bodyData.formalsPropIdArray;
- }
- Js::ForInCache *
- JITTimeFunctionBody::GetForInCache(uint profileId) const
- {
- return &((Js::ForInCache *)m_bodyData.forInCacheArrayAddr)[profileId];
- }
- bool
- JITTimeFunctionBody::InitializeStatementMap(Js::SmallSpanSequence * statementMap, ArenaAllocator* alloc) const
- {
- if (!m_bodyData.statementMap)
- {
- return false;
- }
- const uint statementsLength = m_bodyData.statementMap->statementLength;
- const uint offsetsLength = m_bodyData.statementMap->actualOffsetLength;
- statementMap->baseValue = m_bodyData.statementMap->baseValue;
- // TODO: (leish OOP JIT) using arena to prevent memory leak, fix to really implement GrowingUint32ArenaArray::Create()
- // or find other way to reuse like michhol's comments
- typedef JsUtil::GrowingArray<uint32, ArenaAllocator> GrowingUint32ArenaArray;
- if (statementsLength > 0)
- {
- // TODO: (michhol OOP JIT) should be able to directly use statementMap.statementBuffer
- statementMap->pStatementBuffer = (JsUtil::GrowingUint32HeapArray*)Anew(alloc, GrowingUint32ArenaArray, alloc, statementsLength);
- statementMap->pStatementBuffer->SetCount(statementsLength);
- js_memcpy_s(
- statementMap->pStatementBuffer->GetBuffer(),
- statementMap->pStatementBuffer->Count() * sizeof(uint32),
- m_bodyData.statementMap->statementBuffer,
- statementsLength * sizeof(uint32));
- }
- if (offsetsLength > 0)
- {
- statementMap->pActualOffsetList = (JsUtil::GrowingUint32HeapArray*)Anew(alloc, GrowingUint32ArenaArray, alloc, offsetsLength);
- statementMap->pActualOffsetList->SetCount(offsetsLength);
- js_memcpy_s(
- statementMap->pActualOffsetList->GetBuffer(),
- statementMap->pActualOffsetList->Count() * sizeof(uint32),
- m_bodyData.statementMap->actualOffsetList,
- offsetsLength * sizeof(uint32));
- }
- return true;
- }
- char16*
- JITTimeFunctionBody::GetDisplayName() const
- {
- return m_bodyData.displayName;
- }
|