void ScriptContextTTD::GetLoadedSources(const JsUtil::BaseHashSet<Js::FunctionBody*, HeapAllocator>* onlyLiveTopLevelBodies, JsUtil::List<TTD::TopLevelFunctionInContextRelation, HeapAllocator>& topLevelScriptLoad, JsUtil::List<TTD::TopLevelFunctionInContextRelation, HeapAllocator>& topLevelNewFunction, JsUtil::List<TTD::TopLevelFunctionInContextRelation, HeapAllocator>& topLevelEval) { TTDAssert(topLevelScriptLoad.Count() == 0 && topLevelNewFunction.Count() == 0 && topLevelEval.Count() == 0, "Should be empty when you call this."); for(auto iter = this->m_ttdTopLevelScriptLoad.GetIterator(); iter.IsValid(); iter.MoveNext()) { Js::FunctionBody* body = TTD_COERCE_PTR_ID_TO_FUNCTIONBODY(iter.CurrentValue().ContextSpecificBodyPtrId); if(onlyLiveTopLevelBodies == nullptr || onlyLiveTopLevelBodies->Contains(body)) { topLevelScriptLoad.Add(iter.CurrentValue()); } } for(auto iter = this->m_ttdTopLevelNewFunction.GetIterator(); iter.IsValid(); iter.MoveNext()) { Js::FunctionBody* body = TTD_COERCE_PTR_ID_TO_FUNCTIONBODY(iter.CurrentValue().ContextSpecificBodyPtrId); if(onlyLiveTopLevelBodies == nullptr || onlyLiveTopLevelBodies->Contains(body)) { topLevelNewFunction.Add(iter.CurrentValue()); } } for(auto iter = this->m_ttdTopLevelEval.GetIterator(); iter.IsValid(); iter.MoveNext()) { Js::FunctionBody* body = TTD_COERCE_PTR_ID_TO_FUNCTIONBODY(iter.CurrentValue().ContextSpecificBodyPtrId); if(onlyLiveTopLevelBodies == nullptr || onlyLiveTopLevelBodies->Contains(body)) { topLevelEval.Add(iter.CurrentValue()); } } }
void ThreadContextTTD::ClearContextsForSnapRestore(JsUtil::List<FinalizableObject*, HeapAllocator>& deadCtxs) { for(int32 i = 0; i < this->m_contextList.Count(); ++i) { Js::ScriptContext* ctx = this->m_contextList.Item(i); FinalizableObject* externalCtx = this->m_ttdContextToExternalRefMap.Item(ctx); deadCtxs.Add(externalCtx); } this->m_ttdContextToExternalRefMap.Clear(); this->m_contextList.Clear(); this->m_activeContext = nullptr; }
void RuntimeContextInfo::LoadAndOrderPropertyNames(Js::RecyclableObject* obj, JsUtil::List<const Js::PropertyRecord*, HeapAllocator>& propertyList) { TTDAssert(propertyList.Count() == 0, "This should be empty."); Js::ScriptContext* ctx = obj->GetScriptContext(); uint32 propcount = (uint32)obj->GetPropertyCount(); //get all of the properties for(uint32 i = 0; i < propcount; ++i) { Js::PropertyIndex propertyIndex = (Js::PropertyIndex)i; Js::PropertyId propertyId = obj->GetPropertyId(propertyIndex); if((propertyId != Js::Constants::NoProperty) & (!Js::IsInternalPropertyId(propertyId))) { TTDAssert(obj->HasOwnProperty(propertyId), "We are assuming this is own property count."); propertyList.Add(ctx->GetPropertyName(propertyId)); } } //now sort the list so the traversal order is stable //Rock a custom shell sort!!!! const int32 gaps[6] = { 132, 57, 23, 10, 4, 1 }; int32 llen = propertyList.Count(); for(uint32 gapi = 0; gapi < 6; ++gapi) { int32 gap = gaps[gapi]; for(int32 i = gap; i < llen; i++) { const Js::PropertyRecord* temp = propertyList.Item(i); int32 j = 0; for(j = i; j >= gap && PropertyNameCmp(propertyList.Item(j - gap), temp); j -= gap) { const Js::PropertyRecord* shiftElem = propertyList.Item(j - gap); propertyList.SetItem(j, shiftElem); } propertyList.SetItem(j, temp); } } }