void BoundFunction::ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) { TTD::NSSnapObjects::SnapBoundFunctionInfo* bfi = alloc.SlabAllocateStruct<TTD::NSSnapObjects::SnapBoundFunctionInfo>(); bfi->TargetFunction = TTD_CONVERT_VAR_TO_PTR_ID(static_cast<RecyclableObject*>(this->targetFunction)); bfi->BoundThis = (this->boundThis != nullptr) ? TTD_CONVERT_VAR_TO_PTR_ID(static_cast<Var>(this->boundThis)) : TTD_INVALID_PTR_ID; bfi->ArgCount = this->count; bfi->ArgArray = nullptr; if(bfi->ArgCount > 0) { bfi->ArgArray = alloc.SlabAllocateArray<TTD::TTDVar>(bfi->ArgCount); } TTD_PTR_ID* depArray = alloc.SlabReserveArraySpace<TTD_PTR_ID>(bfi->ArgCount + 2 /*this and bound function*/); depArray[0] = bfi->TargetFunction; uint32 depCount = 1; if(this->boundThis != nullptr && TTD::JsSupport::IsVarComplexKind(this->boundThis)) { depArray[depCount] = bfi->BoundThis; depCount++; } if(bfi->ArgCount > 0) { for(uint32 i = 0; i < bfi->ArgCount; ++i) { bfi->ArgArray[i] = this->boundArgs[i]; //Primitive kinds always inflated first so we only need to deal with complex kinds as depends on if(TTD::JsSupport::IsVarComplexKind(this->boundArgs[i])) { depArray[depCount] = TTD_CONVERT_VAR_TO_PTR_ID(this->boundArgs[i]); depCount++; } } } alloc.SlabCommitArraySpace<TTD_PTR_ID>(depCount, depCount + bfi->ArgCount); TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD::NSSnapObjects::SnapBoundFunctionInfo*, TTD::NSSnapObjects::SnapObjectType::SnapBoundFunctionObject>(objData, bfi, alloc, depCount, depArray); }
Js::Var InflateMap::InflateTTDVar(TTDVar var) const { if(Js::TaggedNumber::Is(var)) { return static_cast<Js::Var>(var); } else { return this->LookupObject(TTD_CONVERT_VAR_TO_PTR_ID(var)); } }
void SnapshotExtractor::ExtractSlotArrayIfNeeded(Js::ScriptContext* ctx, Js::Var* scope) { if(this->m_marks.IsMarked(scope)) { NSSnapValues::SlotArrayInfo* slotInfo = this->m_pendingSnap->GetNextAvailableSlotArrayEntry(); Js::ScopeSlots slots(scope); slotInfo->SlotId = TTD_CONVERT_VAR_TO_PTR_ID(scope); slotInfo->ScriptContextLogId = ctx->ScriptContextLogTag; slotInfo->SlotCount = slots.GetCount(); slotInfo->Slots = this->m_pendingSnap->GetSnapshotSlabAllocator().SlabAllocateArray<TTDVar>(slotInfo->SlotCount); for(uint32 j = 0; j < slotInfo->SlotCount; ++j) { slotInfo->Slots[j] = slots.Get(j); } if(slots.IsFunctionScopeSlotArray()) { Js::FunctionBody* fb = slots.GetFunctionBody(); slotInfo->isFunctionBodyMetaData = true; slotInfo->OptFunctionBodyId = TTD_CONVERT_FUNCTIONBODY_TO_PTR_ID(fb); #if ENABLE_TTD_INTERNAL_DIAGNOSTICS Js::PropertyId* propertyIds = fb->GetPropertyIdsForScopeSlotArray(); slotInfo->DebugPIDArray = this->m_pendingSnap->GetSnapshotSlabAllocator().SlabAllocateArray<Js::PropertyId>(slotInfo->SlotCount); for(uint32 j = 0; j < slotInfo->SlotCount; ++j) { slotInfo->DebugPIDArray[j] = propertyIds[j]; } #endif } else { slotInfo->isFunctionBodyMetaData = false; slotInfo->OptFunctionBodyId = TTD_INVALID_PTR_ID; #if ENABLE_TTD_INTERNAL_DIAGNOSTICS slotInfo->DebugPIDArray = this->m_pendingSnap->GetSnapshotSlabAllocator().SlabAllocateArray<Js::PropertyId>(slotInfo->SlotCount); for(uint32 j = 0; j < slotInfo->SlotCount; ++j) { slotInfo->DebugPIDArray[j] = (Js::PropertyId)0; } #endif } this->m_marks.ClearMark(scope); } }
void HeapArgumentsObject::ExtractSnapObjectDataInto_Helper(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) { TTD::NSSnapObjects::SnapHeapArgumentsInfo* argsInfo = alloc.SlabAllocateStruct<TTD::NSSnapObjects::SnapHeapArgumentsInfo>(); TTDAssert(this->callerDeleted == 0, "This never seems to be set but I want to assert just to be safe."); argsInfo->NumOfArguments = this->numOfArguments; argsInfo->FormalCount = this->formalCount; uint32 depOnCount = 0; TTD_PTR_ID* depOnArray = nullptr; argsInfo->IsFrameNullPtr = false; argsInfo->FrameObject = TTD_INVALID_PTR_ID; if(this->frameObject == nullptr) { argsInfo->IsFrameNullPtr = true; } else { argsInfo->FrameObject = TTD_CONVERT_VAR_TO_PTR_ID(this->frameObject); //Primitive kinds always inflated first so we only need to deal with complex kinds as depends on if(TTD::JsSupport::IsVarComplexKind(this->frameObject)) { depOnCount = 1; depOnArray = alloc.SlabAllocateArray<TTD_PTR_ID>(depOnCount); depOnArray[0] = argsInfo->FrameObject; } } argsInfo->DeletedArgFlags = (this->formalCount != 0) ? alloc.SlabAllocateArrayZ<byte>(argsInfo->FormalCount) : nullptr; if(this->deletedArgs != nullptr) { for(uint32 i = 0; i < this->formalCount; ++i) { if(this->deletedArgs->Test(i)) { argsInfo->DeletedArgFlags[i] = true; } } } if(depOnCount == 0) { TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD::NSSnapObjects::SnapHeapArgumentsInfo*, argsKind>(objData, argsInfo); } else { TTD::NSSnapObjects::StdExtractSetKindSpecificInfo<TTD::NSSnapObjects::SnapHeapArgumentsInfo*, argsKind>(objData, argsInfo, alloc, depOnCount, depOnArray); } }
void SnapshotExtractor::ExtractScopeIfNeeded(Js::ScriptContext* ctx, Js::FrameDisplay* environment) { if(this->m_marks.IsMarked(environment)) { AssertMsg(environment->GetLength() > 0, "This doesn't make sense"); NSSnapValues::ScriptFunctionScopeInfo* funcScopeInfo = this->m_pendingSnap->GetNextAvailableFunctionScopeEntry(); funcScopeInfo->ScopeId = TTD_CONVERT_ENV_TO_PTR_ID(environment); funcScopeInfo->ScriptContextLogId = ctx->ScriptContextLogTag; funcScopeInfo->ScopeCount = environment->GetLength(); funcScopeInfo->ScopeArray = this->m_pendingSnap->GetSnapshotSlabAllocator().SlabAllocateArray<NSSnapValues::ScopeInfoEntry>(funcScopeInfo->ScopeCount); for(uint16 i = 0; i < funcScopeInfo->ScopeCount; ++i) { void* scope = environment->GetItem(i); NSSnapValues::ScopeInfoEntry* entryInfo = (funcScopeInfo->ScopeArray + i); entryInfo->Tag = environment->GetScopeType(scope); switch(entryInfo->Tag) { case Js::ScopeType::ScopeType_ActivationObject: case Js::ScopeType::ScopeType_WithScope: entryInfo->IDValue = TTD_CONVERT_VAR_TO_PTR_ID((Js::Var)scope); break; case Js::ScopeType::ScopeType_SlotArray: { this->ExtractSlotArrayIfNeeded(ctx, (Js::Var*)scope); entryInfo->IDValue = TTD_CONVERT_SLOTARRAY_TO_PTR_ID((Js::Var*)scope); break; } default: AssertMsg(false, "Unknown scope kind"); entryInfo->IDValue = TTD_INVALID_PTR_ID; break; } } this->m_marks.ClearMark(environment); } }