void SharedContents::Cleanup() { Assert(refCount == 0); buffer = nullptr; bufferLength = 0; #if DBG if (allowedAgents != nullptr) { HeapDelete(allowedAgents); allowedAgents = nullptr; } #endif if (indexToWaiterList != nullptr) { indexToWaiterList->Map([](uint index, WaiterList *waiters) { if (waiters != nullptr) { waiters->Cleanup(); HeapDelete(waiters); waiters = nullptr; } }); HeapDelete(indexToWaiterList); indexToWaiterList = nullptr; } }
void SharedContents::Cleanup() { Assert(refCount == 0); buffer = nullptr; bufferLength = 0; #if DBG { AutoCriticalSection autoCS(&csAgent); if (allowedAgents != nullptr) { HeapDelete(allowedAgents); allowedAgents = nullptr; } } #endif if (indexToWaiterList != nullptr) { // TODO: the map should be empty here? // or we need to wake all the waiters from current context? indexToWaiterList->Map([](uint index, WaiterList *waiters) { if (waiters != nullptr) { waiters->Cleanup(); HeapDelete(waiters); waiters = nullptr; } }); HeapDelete(indexToWaiterList); indexToWaiterList = nullptr; } }
JsrtRuntime::~JsrtRuntime() { HeapDelete(allocationPolicyManager); if (this->jsrtDebugManager != nullptr) { HeapDelete(this->jsrtDebugManager); this->jsrtDebugManager = nullptr; } }
JsrtRuntime::~JsrtRuntime() { HeapDelete(allocationPolicyManager); #ifdef ENABLE_SCRIPT_DEBUGGING if (this->jsrtDebugManager != nullptr) { HeapDelete(this->jsrtDebugManager); this->jsrtDebugManager = nullptr; } #endif }
ServerScriptContext::~ServerScriptContext() { HeapDelete(m_domFastPathHelperMap); m_moduleRecords.Map([](uint, Js::ServerSourceTextModuleRecord* record) { HeapDelete(record); }); #ifdef PROFILE_EXEC if (m_codeGenProfiler) { HeapDelete(m_codeGenProfiler); } #endif }
CodeGenWorkItem::~CodeGenWorkItem() { if(queuedFullJitWorkItem) { HeapDelete(queuedFullJitWorkItem); } }
~AutoCleanupSharedContents() { if (!allocationCompleted) { HeapDelete(sharedContents); } }
void WaiterList::Cleanup() { if (m_waiters != nullptr) { HeapDelete(m_waiters); m_waiters = nullptr; } }
void JsrtRuntime::DeleteJsrtDebugManager() { if (this->jsrtDebugManager != nullptr) { HeapDelete(this->jsrtDebugManager); this->jsrtDebugManager = nullptr; } }
void ServerThreadContext::Release() { InterlockedExchangeSubtract(&m_refCount, (uint)1); if (m_isClosed && m_refCount == 0) { HeapDelete(this); } }
ServerThreadContext::~ServerThreadContext() { processContext->Release(); if (this->m_numericPropertyBV != nullptr) { HeapDelete(m_numericPropertyBV); this->m_numericPropertyBV = nullptr; } }
void ThreadContextTLSEntry::CleanupThread() { ASSERT_ENTRY_INITIALIZED(); ThreadContextTLSEntry* entry = ENTRY_FOR_CURRENT_THREAD(); if (entry != NULL) { HeapDelete(entry); TlsSetValue(s_tlsSlot, NULL); } }
HEAP_DAT_T* GetAndRemoveHeapTop(PHeap Heap) { HEAP_DAT_T* ret; if (Heap->Used == 0) return NULL; ret = Heap->Entries[0]->pData; HeapDelete(Heap, 0); return ret; }
void ThreadContextTLSEntry::CleanupThread() { Assert(s_tlsSlot != TLS_OUT_OF_INDEXES); ThreadContextTLSEntry * entry = GetEntryForCurrentThread(); if (entry != NULL) { HeapDelete(entry); TlsSetValue(s_tlsSlot, NULL); } }
void XDataAllocator::ClearFreeList() { XDataAllocationEntry* next = this->freeList; XDataAllocationEntry* entry; while(next) { entry = next; next = entry->next; HeapDelete(entry); } this->freeList = NULL; }
void ThreadBoundThreadContextManager::DestroyAllContextsAndEntries() { AutoCriticalSection lock(ThreadContext::GetCriticalSection()); while (!entries.Empty()) { ThreadContextTLSEntry * entry = entries.Head(); ThreadContext * threadContext = static_cast<ThreadContext *>(entry->GetThreadContext()); entries.RemoveHead(); if (threadContext != nullptr) { #if DBG PageAllocator* pageAllocator = threadContext->GetPageAllocator(); if (pageAllocator) { pageAllocator->SetConcurrentThreadId(::GetCurrentThreadId()); } #endif threadContext->ShutdownThreads(); HeapDelete(threadContext); } ThreadContextTLSEntry::Delete(entry); } #if ENABLE_BACKGROUND_JOB_PROCESSOR if (s_sharedJobProcessor != NULL) { s_sharedJobProcessor->Close(); HeapDelete(s_sharedJobProcessor); s_sharedJobProcessor = NULL; } #endif }
BackgroundJobProcessor::~BackgroundJobProcessor() { // This should appear to be called from the same thread from which this instance was created Assert(IsClosed()); if (parallelThreadData) { for (unsigned int i = 0; i < this->threadCount; i++) { HeapDelete(parallelThreadData[i]); } HeapDeleteArray(this->maxThreadCount, parallelThreadData); } }
void ThreadContextManagerBase::ShutdownThreadContext(ThreadContext* threadContext) { #if DBG PageAllocator* pageAllocator = threadContext->GetPageAllocator(); if (pageAllocator) { pageAllocator->SetConcurrentThreadId(::GetCurrentThreadId()); } #endif threadContext->ShutdownThreads(); HeapDelete(threadContext); }
void CodeGenWorkItem::OnRemoveFromJitQueue(NativeCodeGenerator* generator) { // This is called from within the lock this->isInJitQueue = false; this->entryPointInfo->SetCodeGenPending(); functionBody->GetScriptContext()->GetThreadContext()->UnregisterCodeGenRecyclableData(this->recyclableData); this->recyclableData = nullptr; if(IS_JS_ETW(EventEnabledJSCRIPT_FUNCTION_JIT_DEQUEUED())) { WCHAR displayNameBuffer[256]; WCHAR* displayName = displayNameBuffer; size_t sizeInChars = this->GetDisplayName(displayName, 256); if(sizeInChars > 256) { displayName = HeapNewArray(WCHAR, sizeInChars); this->GetDisplayName(displayName, 256); } JS_ETW(EventWriteJSCRIPT_FUNCTION_JIT_DEQUEUED( this->GetFunctionNumber(), displayName, this->GetScriptContext(), this->GetInterpretedCount())); if(displayName != displayNameBuffer) { HeapDeleteArray(sizeInChars, displayName); } } if(this->Type() == JsLoopBodyWorkItemType) { // Go ahead and delete it and let it re-queue if more interpreting of the loop happens auto loopBodyWorkItem = static_cast<JsLoopBodyCodeGen*>(this); loopBodyWorkItem->loopHeader->ResetInterpreterCount(); loopBodyWorkItem->GetEntryPoint()->Reset(); HeapDelete(loopBodyWorkItem); } else { Assert(GetJitMode() == ExecutionMode::FullJit); // simple JIT work items are not removed from the queue GetFunctionBody()->OnFullJitDequeued(static_cast<Js::FunctionEntryPointInfo *>(GetEntryPoint())); // Add it back to the list of available functions to be jitted generator->AddWorkItem(this); } }
// This is called at process detach. // threadcontext created from runtime should not be destroyed in ThreadBoundThreadContext // we should clean them up at process detach only as runtime can be used in other threads // even after the current physical thread was destroyed. // This is called after ThreadBoundThreadContext are cleaned up, so the remaining items // in the globalthreadContext linklist should be for jsrt only. void JsrtRuntime::Uninitialize() { ThreadContext* currentThreadContext = ThreadContext::GetThreadContextList(); ThreadContext* tmpThreadContext; while (currentThreadContext) { Assert(!currentThreadContext->IsScriptActive()); JsrtRuntime* currentRuntime = static_cast<JsrtRuntime*>(currentThreadContext->GetJSRTRuntime()); tmpThreadContext = currentThreadContext; currentThreadContext = currentThreadContext->Next(); currentRuntime->CloseContexts(); RentalThreadContextManager::DestroyThreadContext(tmpThreadContext); HeapDelete(currentRuntime); } }
void JavascriptSharedArrayBuffer::Finalize(bool isShutdown) { if (sharedContents == nullptr) { return; } uint ref = sharedContents->Release(); if (ref == 0) { this->FreeBuffer(sharedContents->buffer, sharedContents->bufferLength, sharedContents->maxBufferLength); Recycler* recycler = GetType()->GetLibrary()->GetRecycler(); recycler->ReportExternalMemoryFree(sharedContents->bufferLength); sharedContents->Cleanup(); HeapDelete(sharedContents); } sharedContents = nullptr; }
void ParseMsgDivisionEnd(void) { MAINFO mi; char *p; if (!do_marea) return; if (! *prefix) { printf("\n\aError! MsgDivisionEnd on line %d has no correspondig MsgDivisionBegin!\n", linenum); Compiling(-1, NULL, NULL); return; } /* Strip off the trailing dot */ prefix[strlen(prefix)-1]=0; /* Now set the prefix back to the prior area */ if ((p=strrchr(prefix, '.')) != NULL) p[1]=0; else *prefix=0; MsgAreaWrite(NULL, FALSE); memset(&mi, 0, sizeof mi); mi.marea=TRUE; HeapNew(&mi.h, MAX_MSG_HEAP); mi.ma.attribs = MA_DIVEND; mi.ma.division = --division; HeapAdd(&mi.h, &mi.ma.acs, ""); MsgAreaWrite(&mi, FALSE); HeapDelete(&mi.h); }
bool XDataAllocator::Alloc(ULONG_PTR functionStart, DWORD functionSize, ushort pdataCount, ushort xdataSize, SecondaryAllocation* allocation) { XDataAllocation* xdata = static_cast<XDataAllocation*>(allocation); Assert(start != nullptr); Assert(current != nullptr); Assert(current >= start); Assert(xdataSize <= XDATA_SIZE); Assert(pdataCount == 1); // Allocate a new xdata entry if((End() - current) >= XDATA_SIZE) { xdata->address = current; current += XDATA_SIZE; } // try allocating from the free list else if(freeList) { auto entry = freeList; xdata->address = entry->address; this->freeList = entry->next; HeapDelete(entry); } else { xdata->address = nullptr; OUTPUT_TRACE(Js::XDataAllocatorPhase, _u("No space for XDATA.\n")); } #ifndef _WIN32 if (xdata->address) { ClearHead(xdata->address); // mark empty .eh_frame } #endif return xdata->address != nullptr; }
// This is called at process detach. // threadcontext created from runtime should not be destroyed in ThreadBoundThreadContext // we should clean them up at process detach only as runtime can be used in other threads // even after the current physical thread was destroyed. // This is called after ThreadBoundThreadContext are cleaned up, so the remaining items // in the globalthreadContext linklist should be for jsrt only. void JsrtRuntime::Uninitialize() { ThreadContext* currentThreadContext = ThreadContext::GetThreadContextList(); ThreadContext* tmpThreadContext; while (currentThreadContext) { Assert(!currentThreadContext->IsScriptActive()); JsrtRuntime* currentRuntime = static_cast<JsrtRuntime*>(currentThreadContext->GetJSRTRuntime()); tmpThreadContext = currentThreadContext; currentThreadContext = currentThreadContext->Next(); #ifdef CHAKRA_STATIC_LIBRARY // xplat-todo: Cleanup staticlib shutdown. This only shuts down threads. // Other closing contexts / finalizers having trouble with current // runtime/context. RentalThreadContextManager::DestroyThreadContext(tmpThreadContext); #else currentRuntime->CloseContexts(); RentalThreadContextManager::DestroyThreadContext(tmpThreadContext); HeapDelete(currentRuntime); #endif } }
void JavascriptSharedArrayBuffer::Finalize(bool isShutdown) { if (sharedContents == nullptr) { return; } uint ref = InterlockedDecrement(&sharedContents->refCount); if (ref == 0) { #if _WIN64 //AsmJS Virtual Free //TOD - see if isBufferCleared need to be added for free too if (IsValidVirtualBufferLength(sharedContents->bufferLength) && !sharedContents->isBufferCleared) { LPVOID startBuffer = (LPVOID)((uint64)sharedContents->buffer); BOOL fSuccess = VirtualFree((LPVOID)startBuffer, 0, MEM_RELEASE); Assert(fSuccess); sharedContents->isBufferCleared = true; } else { free(sharedContents->buffer); } #else free(sharedContents->buffer); #endif Recycler* recycler = GetType()->GetLibrary()->GetRecycler(); recycler->ReportExternalMemoryFree(sharedContents->bufferLength); sharedContents->Cleanup(); HeapDelete(sharedContents); } sharedContents = nullptr; }
void ParseMsgDivisionBegin(char *name, char *acs, char *displayfile, char *descript) { MAINFO mi; char fullname[PATHLEN]; if (!do_marea) return; if (strchr(name, '.')) BadDivisionName(); strcpy(fullname, prefix); strcat(fullname, name); strcat(prefix, name); strcat(prefix, "."); MsgAreaWrite(NULL, FALSE); memset(&mi, 0, sizeof mi); mi.marea=TRUE; HeapNew(&mi.h, MAX_MSG_HEAP); HeapAdd(&mi.h, &mi.ma.name, fullname); HeapAdd(&mi.h, &mi.ma.descript, descript); HeapAdd(&mi.h, &mi.ma.acs, acs); HeapAdd(&mi.h, &mi.ma.path, displayfile); mi.ma.attribs = MA_DIVBEGIN; mi.ma.division = division++; MsgAreaWrite(&mi, FALSE); HeapDelete(&mi.h); }
ThreadContext * ThreadBoundThreadContextManager::EnsureContextForCurrentThread() { AutoCriticalSection lock(ThreadContext::GetCriticalSection()); ThreadContextTLSEntry * entry = ThreadContextTLSEntry::GetEntryForCurrentThread(); if (entry == NULL) { ThreadContextTLSEntry::CreateEntryForCurrentThread(); entry = ThreadContextTLSEntry::GetEntryForCurrentThread(); entries.Prepend(entry); } ThreadContext * threadContext = entry->GetThreadContext(); // An existing TLS entry may have a null ThreadContext // DllCanUnload may have cleaned out all the TLS entry when the module lock count is 0, // but the library didn't get unloaded because someone is holding onto ref count via LoadLibrary. // Just reinitialize the thread context. if (threadContext == nullptr) { threadContext = HeapNew(ThreadContext); threadContext->SetIsThreadBound(); if (!ThreadContextTLSEntry::TrySetThreadContext(threadContext)) { HeapDelete(threadContext); return NULL; } } Assert(threadContext != NULL); s_maxNumberActiveThreadContexts = max(s_maxNumberActiveThreadContexts, GetActiveThreadContextCount()); return threadContext; }
size_t WeightedMatching(RowStarts *rowptr,ColIndices *colind,ValueType *C, ValueType *C1,ValueType *dist,ValueType *u,ValueType *v,Indices *p, Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){ size_t i,j,i1,jend,k,m_inv_prev; size_t match_size=0; ValueType curr_shortest_path = (ValueType)0; ValueType curr_aug_path = GetMaxTypeValue<ValueType>(); ValueType dist1; Indices itrace; BitArray_t *col_marker = CreateBitArray(n); BitArray_t *heap_marker = CreateBitArray(n); C--;m--;C1--;dist--;u--;v--;p--;m_inv--; rowptr--;colind--; #if BINARY_HEAP Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID); ValueType *dist_ptr = NULL; #endif assert(C1 && dist && u && v && p); ComputeInitialExtremeMatch<ValueType,Indices>(u,v,C1,C,m,m_inv,colind,rowptr,n,dist); match_size=0; for(i=1;i<=n;i++){ if(m_inv[i]){ match_size++; continue; } /* *Aim is to find a value for jend such that the path *from i-->jend is the shortest */ i1 = i; p[i1] = 0; jend=0; itrace=i; ResetAllBits(col_marker); ResetAllBits(heap_marker); #if BINARY_HEAP bin_heap->n = 0; dist_base = (unsigned long)&(dist[1]); #endif curr_shortest_path=(ValueType)0; curr_aug_path=GetMaxTypeValue<ValueType>(); while(1){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; if(CheckBit(col_marker,j)){ continue; } dist1 = curr_shortest_path + C1[k]; /*Prune any dist1's > curr_aug_path, since *all the costs>0 */ if(*((long long int *)&dist1) < *((long long int *)&curr_aug_path)){ if(!m[j]){ /*we need itrace because, the last i1 which *we explore may not actually give the shortest *augmenting path.*/ jend = j; itrace = i1; curr_aug_path = dist1; }else if(*((long long int *)&dist1) < *((long long int *)&(dist[j]))){ /*Update the dist*/ dist[j] = dist1; p[m[j]] = i1; #if SIMPLE_HEAP SetBit(heap_marker,j); #elif BINARY_HEAP if(CheckBit(heap_marker,j)){ DecreaseKey(bin_heap,j); }else{ InsertHeap(bin_heap,&(dist[j])); SetBit(heap_marker,j); } #endif } } } if(*((long long int *)&curr_aug_path) <= *((long long int *)&curr_shortest_path)){ break; } /*We now have a heap of matched cols, so pick the min*/ #ifdef SIMPLE_HEAP j = SimplePickMin(heap_marker,dist,n); if(j){ curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #elif BINARY_HEAP dist_ptr = (ValueType *) HeapDelete(bin_heap); if(dist_ptr){ assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]); j = ((((unsigned long)dist_ptr - (unsigned long)&dist[1]))/sizeof(double))+1; assert(j>=1 && j<=n); curr_shortest_path = dist[j]; UnsetBit(heap_marker,j); #endif SetBit(col_marker,j); i1 = m[j]; }else{ break; } } if(jend){ /*We found a shortest augmenting path*/ j=jend; node_t itrace_prev; //printf("Shortest augmenting Path {"); while(itrace){ m_inv_prev = m_inv[itrace]; m[j] = itrace; m_inv[itrace]=j; //printf("(%u,%u)",itrace,j); j=m_inv_prev; itrace_prev = itrace; itrace = p[itrace]; if(itrace){ // printf("(%u,%u)",itrace_prev,m_inv_prev); } } match_size++; //printf("}\n"); /*Update the cost with new match m*/ for(j=1;j<=n;j++){ if(CheckBit(col_marker,j)){ u[j] = (u[j]+dist[j])-curr_aug_path; /*Reset the dist values*/ } } for(i1=1;i1<=n;i1++){ if(!m_inv[i1]) continue; j = m_inv[i1]; for(k=rowptr[i1];k<rowptr[i1+1];k++){ if(colind[k] == j){ v[i1] = C[k] - u[j]; } } } /*Update the cost*/ for(i1=1;i1<=n;i1++){ for(k=rowptr[i1];k<rowptr[i1+1];k++){ j = colind[k]; C1[k] = C[k]-(u[j]+v[i1]); } /*The index should be j rather than i1 but just *avoiding another loop*/ dist[i1] = GetMaxTypeValue<double>(); } } } FreeBitArray(col_marker); FreeBitArray(heap_marker); #ifdef BINARY_HEAP FreeHeap(bin_heap); #endif return match_size; } /*O(n) time picking the maximum from the heap_marker */ node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){ node_t min_j=0;node_t j; double curr_min = MAX_DOUBLE_VALUE; for(j=1;j<=n;j++){ if(CheckBit(bit_heap,j) && dist[j] < curr_min){ min_j = j; curr_min = dist[j]; } } return min_j; }
int ParseMsgArea(FILE *ctlfile, char *name) { char line[PATHLEN]; char fullname[PATHLEN]; static MAINFO mi; OVRLIST ol; struct _vbtab verbs[]= { {0, "acs", &mi.ma.acs}, {FiltPath, "path", &mi.ma.path}, {0, "tag", &mi.ma.echo_tag}, {0, "desc", &mi.ma.descript}, {0, "description", &mi.ma.descript}, {FiltOrigin, "origin", &mi.ma.origin}, #ifdef MAX_TRACKER {FiltOwner, "owner", NULL}, #endif {FiltMenuname,"menuname", NULL}, {FiltOverride,"override", NULL}, {FiltStyle, "style", NULL}, {FiltRenum, "renum", NULL}, {FiltBarricade,"barricade", NULL}, {0, "app", NULL}, {0, "application", NULL}, {0, "attachpath", &mi.ma.attachpath}, {0, NULL, NULL} }; if (strchr(name, '.')) BadDivisionName(); if (do_marea) { /* Make sure that area file is open */ MsgAreaWrite(NULL, FALSE); memset(&mi, 0, sizeof mi); mi.marea=TRUE; mi.ma.division=division; mi.ma.primary=prm.address[0]; mi.ma.seenby=prm.address[!!prm.address[0].point && prm.address[1].zone]; HeapNew(&mi.h, MAX_MSG_HEAP); strcpy(fullname, prefix); strcat(fullname, name); HeapAdd(&mi.h, &mi.ma.name, fullname); #ifdef MAX_TRACKER *toNewOwner=0; #endif } while (fgets(line, PATHLEN, ctlfile)) if (VerbParse(&mi, do_marea ? verbs : NULL, line)) break; if (do_marea) { MsgAreaWrite(&mi, FALSE); for (ol=mi.ol; ol; ol=ol->next) free(ol); HeapDelete(&mi.h); } return 0; }
void ThreadBoundThreadContextManager::DestroyAllContexts() { #if ENABLE_BACKGROUND_JOB_PROCESSOR JsUtil::BackgroundJobProcessor * jobProcessor = NULL; #endif { AutoCriticalSection lock(ThreadContext::GetCriticalSection()); ThreadContextTLSEntry * currentEntry = ThreadContextTLSEntry::GetEntryForCurrentThread(); if (currentEntry == NULL) { // We need a current thread entry so that we can use it to release any thread contexts // we find below. try { AUTO_NESTED_HANDLED_EXCEPTION_TYPE(ExceptionType_OutOfMemory); currentEntry = ThreadContextTLSEntry::CreateEntryForCurrentThread(); entries.Prepend(currentEntry); } catch (Js::OutOfMemoryException) { return; } } else { // We need to clear out the current thread entry so that we can use it to release any // thread contexts we find below. ThreadContext * threadContext = static_cast<ThreadContext *>(currentEntry->GetThreadContext()); if (threadContext != NULL) { if (threadContext->IsThreadBound()) { ShutdownThreadContext(threadContext); ThreadContextTLSEntry::ClearThreadContext(currentEntry, false); } else { ThreadContextTLSEntry::ClearThreadContext(currentEntry, true); } } } EntryList::Iterator iter(&entries); while (iter.Next()) { ThreadContextTLSEntry * entry = iter.Data(); ThreadContext * threadContext = static_cast<ThreadContext *>(entry->GetThreadContext()); if (threadContext != nullptr) { // Found a thread context. Remove it from the containing entry. ThreadContextTLSEntry::ClearThreadContext(entry, true); // Now set it to our thread's entry. ThreadContextTLSEntry::SetThreadContext(currentEntry, threadContext); // Clear it out. ShutdownThreadContext(threadContext); // Now clear it out of our entry. ThreadContextTLSEntry::ClearThreadContext(currentEntry, false); } } // We can only clean up our own TLS entry, so we're going to go ahead and do that here. entries.Remove(currentEntry); ThreadContextTLSEntry::CleanupThread(); #if ENABLE_BACKGROUND_JOB_PROCESSOR if (s_sharedJobProcessor != NULL) { jobProcessor = s_sharedJobProcessor; s_sharedJobProcessor = NULL; jobProcessor->Close(); } #endif } #if ENABLE_BACKGROUND_JOB_PROCESSOR if (jobProcessor != NULL) { HeapDelete(jobProcessor); } #endif }