| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151 |
- //-------------------------------------------------------------------------------------------------------
- // 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();
- Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray = functionBody->GetSlotIdInCachedScopeToNestedIndexArrayWithLock();
- if (slotIdInCachedScopeToNestedIndexArray)
- {
- jitBody->functionSlotsInCachedScopeCount = slotIdInCachedScopeToNestedIndexArray->count;
- jitBody->slotIdInCachedScopeToNestedIndexArray = slotIdInCachedScopeToNestedIndexArray->elements;
- }
- #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->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;
- }
- void
- JITTimeFunctionBody::EnsureConsistentConstCount() const
- {
- if (GetConstCount() == 0 || IsAsmJsMode())
- {
- AssertOrFailFast(m_bodyData.constTableContent == nullptr);
- }
- else
- {
- AssertOrFailFast(m_bodyData.constTableContent != nullptr && GetConstCount() == m_bodyData.constTableContent->count);
- }
- }
- 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];
- }
- uint
- JITTimeFunctionBody::GetNestedFuncIndexForSlotIdInCachedScope(uint index) const
- {
- AssertOrFailFast(m_bodyData.slotIdInCachedScopeToNestedIndexArray != nullptr);
- AssertOrFailFast(index < m_bodyData.functionSlotsInCachedScopeCount);
- return m_bodyData.slotIdInCachedScopeToNestedIndexArray[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
- {
- AssertOrFailFast(offset < m_bodyData.auxDataCount);
- return (void *)(m_bodyData.auxData + offset);
- }
- void *
- JITTimeFunctionBody::ReadFromAuxContextData(uint offset) const
- {
- AssertOrFailFast(offset < m_bodyData.auxContextDataCount);
- return (void *)(m_bodyData.auxContextData + offset);
- }
- const Js::PropertyIdArray *
- JITTimeFunctionBody::ReadPropertyIdArrayFromAuxData(uint offset) const
- {
- Js::PropertyIdArray * auxArray = (Js::PropertyIdArray *)(m_bodyData.auxData + offset);
- AssertOrFailFast(AllocSizeMath::Add(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;
- }
|