void CodeGenNumberThreadAllocator::Integrate() { AutoCriticalSection autocs(&cs); PageAllocator * leafPageAllocator = this->recycler->GetRecyclerLeafPageAllocator(); leafPageAllocator->IntegrateSegments(pendingIntegrationNumberSegment, pendingIntegrationNumberSegmentCount, pendingIntegrationNumberSegmentPageCount); PageAllocator * recyclerPageAllocator = this->recycler->GetRecyclerPageAllocator(); recyclerPageAllocator->IntegrateSegments(pendingIntegrationChunkSegment, pendingIntegrationChunkSegmentCount, pendingIntegrationChunkSegmentPageCount); pendingIntegrationNumberSegmentCount = 0; pendingIntegrationChunkSegmentCount = 0; pendingIntegrationNumberSegmentPageCount = 0; pendingIntegrationChunkSegmentPageCount = 0; #ifdef TRACK_ALLOC TrackAllocData oldAllocData = recycler->nextAllocData; recycler->nextAllocData.Clear(); #endif while (!pendingIntegrationNumberBlock.Empty()) { TRACK_ALLOC_INFO(recycler, Js::JavascriptNumber, Recycler, 0, (size_t)-1); BlockRecord& record = pendingIntegrationNumberBlock.Head(); if (!recycler->IntegrateBlock<LeafBit>(record.blockAddress, record.segment, GetNumberAllocSize(), sizeof(Js::JavascriptNumber))) { Js::Throw::OutOfMemory(); } pendingIntegrationNumberBlock.RemoveHead(&NoThrowHeapAllocator::Instance); } while (!pendingIntegrationChunkBlock.Empty()) { // REVIEW: the above number block integration can be moved into this loop TRACK_ALLOC_INFO(recycler, CodeGenNumberChunk, Recycler, 0, (size_t)-1); BlockRecord& record = pendingIntegrationChunkBlock.Head(); if (!recycler->IntegrateBlock<NoBit>(record.blockAddress, record.segment, GetChunkAllocSize(), sizeof(CodeGenNumberChunk))) { Js::Throw::OutOfMemory(); } pendingIntegrationChunkBlock.RemoveHead(&NoThrowHeapAllocator::Instance); } #ifdef TRACK_ALLOC Assert(recycler->nextAllocData.IsEmpty()); recycler->nextAllocData = oldAllocData; #endif }
void XProcNumberPageSegmentManager::Integrate() { AutoCriticalSection autoCS(&cs); auto temp = this->segmentsList; auto prev = &this->segmentsList; while (temp) { if (temp->pageSegment == 0) { auto leafPageAllocator = recycler->GetRecyclerLeafPageAllocator(); DListBase<PageSegment> segmentList; temp->pageSegment = (intptr_t)leafPageAllocator->AllocPageSegment(segmentList, leafPageAllocator, (void*)temp->pageAddress, XProcNumberPageSegmentImpl::PageCount, temp->committedEnd / AutoSystemInfo::PageSize); leafPageAllocator->IntegrateSegments(segmentList, 1, XProcNumberPageSegmentImpl::PageCount); this->integratedSegmentCount++; } unsigned int minIntegrateSize = XProcNumberPageSegmentImpl::BlockSize; for (; temp->pageAddress + temp->blockIntegratedSize + minIntegrateSize < (unsigned int)temp->allocEndAddress; temp->blockIntegratedSize += minIntegrateSize) { TRACK_ALLOC_INFO(recycler, Js::JavascriptNumber, Recycler, 0, (size_t)-1); if (!recycler->IntegrateBlock<LeafBit>((char*)temp->pageAddress + temp->blockIntegratedSize, (PageSegment*)temp->pageSegment, XProcNumberPageSegmentImpl::GetSizeCat(), sizeof(Js::JavascriptNumber))) { Js::Throw::OutOfMemory(); } } *prev = (XProcNumberPageSegmentImpl*)temp->nextSegment; midl_user_free(temp); temp = *prev; } }
void DynamicTypeHandler::AdjustSlots( DynamicObject *const object, const PropertyIndex newInlineSlotCapacity, const int newAuxSlotCapacity) { Assert(object); // Allocate new aux slot array Recycler *const recycler = object->GetRecycler(); TRACK_ALLOC_INFO(recycler, Var, Recycler, 0, newAuxSlotCapacity); Var *const newAuxSlots = reinterpret_cast<Var *>(recycler->AllocZero(newAuxSlotCapacity * sizeof(Var))); DynamicTypeHandler *const oldTypeHandler = object->GetTypeHandler(); const PropertyIndex oldInlineSlotCapacity = oldTypeHandler->GetInlineSlotCapacity(); if(oldInlineSlotCapacity == newInlineSlotCapacity) { const int oldAuxSlotCapacity = oldTypeHandler->GetSlotCapacity() - oldInlineSlotCapacity; Assert(oldAuxSlotCapacity < newAuxSlotCapacity); if(oldAuxSlotCapacity > 0) { // Copy aux slots to the new array Var *const oldAuxSlots = object->auxSlots; Assert(oldAuxSlots); int i = 0; do { newAuxSlots[i] = oldAuxSlots[i]; } while(++i < oldAuxSlotCapacity); #ifdef EXPLICIT_FREE_SLOTS recycler->ExplicitFreeNonLeaf(oldAuxSlots, oldAuxSlotCapacity * sizeof(Var)); #endif } object->auxSlots = newAuxSlots; return; } // An object header-inlined type handler is transitioning into one that is not. Some inline slots need to move, and // there are no old aux slots that need to be copied. Assert(oldTypeHandler->IsObjectHeaderInlinedTypeHandler()); Assert(oldInlineSlotCapacity > newInlineSlotCapacity); Assert(oldInlineSlotCapacity - newInlineSlotCapacity == DynamicTypeHandler::GetObjectHeaderInlinableSlotCapacity()); Assert(newAuxSlotCapacity >= DynamicTypeHandler::GetObjectHeaderInlinableSlotCapacity()); // Move the last few inline slots into the aux slots if(PHASE_TRACE1(Js::ObjectHeaderInliningPhase)) { Output::Print(_u("ObjectHeaderInlining: Moving inlined properties to aux slots.\n")); Output::Flush(); } Var *const oldInlineSlots = reinterpret_cast<Var *>( reinterpret_cast<uintptr_t>(object) + DynamicTypeHandler::GetOffsetOfObjectHeaderInlineSlots()); Assert(DynamicTypeHandler::GetObjectHeaderInlinableSlotCapacity() == 2); newAuxSlots[0] = oldInlineSlots[oldInlineSlotCapacity - 2]; newAuxSlots[1] = oldInlineSlots[oldInlineSlotCapacity - 1]; if(newInlineSlotCapacity > 0) { // Move the remaining inline slots such that none are object header-inlined. Copy backwards, as the two buffers may // overlap, with the new inline slot array starting beyond the start of the old inline slot array. if(PHASE_TRACE1(Js::ObjectHeaderInliningPhase)) { Output::Print(_u("ObjectHeaderInlining: Moving inlined properties out of the object header.\n")); Output::Flush(); } Var *const newInlineSlots = reinterpret_cast<Var *>(object + 1); PropertyIndex i = newInlineSlotCapacity; do { --i; newInlineSlots[i] = oldInlineSlots[i]; } while(i > 0); } object->auxSlots = newAuxSlots; object->objectArray = nullptr; }