Skip to content

Commit c4f736e

Browse files
committed
[RTL] Add and populate LastEntryInSegment. CORE-14588
1 parent dd83bcd commit c4f736e

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

sdk/lib/rtl/heap.c

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,10 +702,12 @@ RtlpFindAndCommitPages(PHEAP Heap,
702702
if(UcrDescriptor->Address == Segment->LastValidEntry)
703703
{
704704
FirstEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
705+
Segment->LastEntryInSegment = FirstEntry;
705706
}
706707
else
707708
{
708709
FirstEntry->Flags = 0;
710+
Segment->LastEntryInSegment = Segment->FirstEntry;
709711
/* Update field of next entry */
710712
ASSERT((FirstEntry + FirstEntry->Size)->PreviousSize == 0);
711713
(FirstEntry + FirstEntry->Size)->PreviousSize = FirstEntry->Size;
@@ -720,6 +722,7 @@ RtlpFindAndCommitPages(PHEAP Heap,
720722
else
721723
{
722724
FirstEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
725+
Segment->LastEntryInSegment = FirstEntry;
723726
}
724727

725728
/* We're done */
@@ -841,6 +844,7 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
841844
FreeEntry->Flags = HEAP_ENTRY_LAST_ENTRY;
842845
FreeEntry->Size = (USHORT)PrecedingSize;
843846
Heap->TotalFreeSize += PrecedingSize;
847+
Segment->LastEntryInSegment = FreeEntry;
844848

845849
/* Insert it into the free list */
846850
RtlpInsertFreeBlockHelper(Heap, FreeEntry, PrecedingSize, FALSE);
@@ -849,6 +853,13 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
849853
{
850854
/* Adjust preceding in use entry */
851855
PrecedingInUseEntry->Flags |= HEAP_ENTRY_LAST_ENTRY;
856+
Segment->LastEntryInSegment = PrecedingInUseEntry;
857+
}
858+
else if ((ULONG_PTR)Segment->LastEntryInSegment >= DecommitBase &&
859+
(ULONG_PTR)Segment->LastEntryInSegment < DecommitBase + DecommitSize)
860+
{
861+
/* Invalidate last entry */
862+
Segment->LastEntryInSegment = Segment->FirstEntry;
852863
}
853864

854865
/* Now the next one */
@@ -933,6 +944,9 @@ RtlpInitializeHeapSegment(IN OUT PHEAP Heap,
933944
RtlpInsertFreeBlock(Heap, (PHEAP_FREE_ENTRY) HeapEntry, (SegmentCommit >> HEAP_ENTRY_SHIFT) - Segment->Entry.Size);
934945
}
935946

947+
/* Always point to a valid entry */
948+
Segment->LastEntryInSegment = Segment->FirstEntry;
949+
936950
/* Initialise the Heap Segment UnCommitted Range information */
937951
Segment->NumberOfUnCommittedPages = (ULONG)((SegmentReserve - SegmentCommit) >> PAGE_SHIFT);
938952
Segment->NumberOfUnCommittedRanges = 0;
@@ -984,6 +998,7 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
984998
BOOLEAN Remove)
985999
{
9861000
PHEAP_FREE_ENTRY CurrentEntry, NextEntry;
1001+
UCHAR SegmentOffset;
9871002

9881003
/* Get the previous entry */
9891004
CurrentEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry - FreeEntry->PreviousSize);
@@ -1022,6 +1037,12 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
10221037
{
10231038
((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
10241039
}
1040+
else
1041+
{
1042+
SegmentOffset = FreeEntry->SegmentOffset;
1043+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
1044+
Heap->Segments[SegmentOffset]->LastEntryInSegment = FreeEntry;
1045+
}
10251046
}
10261047

10271048
/* Check the next block if it exists */
@@ -1057,6 +1078,12 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
10571078
{
10581079
((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
10591080
}
1081+
else
1082+
{
1083+
SegmentOffset = FreeEntry->SegmentOffset;
1084+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
1085+
Heap->Segments[SegmentOffset]->LastEntryInSegment = FreeEntry;
1086+
}
10601087
}
10611088
}
10621089
return FreeEntry;
@@ -1637,6 +1664,7 @@ RtlpSplitEntry(PHEAP Heap,
16371664
UCHAR FreeFlags, EntryFlags = HEAP_ENTRY_BUSY;
16381665
PHEAP_ENTRY InUseEntry;
16391666
SIZE_T FreeSize;
1667+
UCHAR SegmentOffset;
16401668

16411669
/* Add extra flags in case of settable user value feature is requested,
16421670
or there is a tag (small or normal) or there is a request to
@@ -1748,6 +1776,12 @@ RtlpSplitEntry(PHEAP Heap,
17481776

17491777
/* Reset flags of the free entry */
17501778
FreeFlags = 0;
1779+
if (SplitBlock->Flags & HEAP_ENTRY_LAST_ENTRY)
1780+
{
1781+
SegmentOffset = SplitBlock->SegmentOffset;
1782+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
1783+
Heap->Segments[SegmentOffset]->LastEntryInSegment = SplitBlock;
1784+
}
17511785
}
17521786
}
17531787

@@ -2311,6 +2345,7 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
23112345
PHEAP_FREE_ENTRY FreeEntry, UnusedEntry, FollowingEntry;
23122346
SIZE_T FreeSize, PrevSize, TailPart, AddedSize = 0;
23132347
PHEAP_ENTRY_EXTRA OldExtra, NewExtra;
2348+
UCHAR SegmentOffset;
23142349

23152350
/* We can't grow beyond specified threshold */
23162351
if (Index > Heap->VirtualMemoryThreshold)
@@ -2407,9 +2442,17 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
24072442
InUseEntry->Flags |= RememberFlags & HEAP_ENTRY_LAST_ENTRY;
24082443

24092444
/* Either update previous size of the next entry or mark it as a last
2410-
entry in the segment*/
2445+
entry in the segment */
24112446
if (!(RememberFlags & HEAP_ENTRY_LAST_ENTRY))
2447+
{
24122448
(InUseEntry + InUseEntry->Size)->PreviousSize = InUseEntry->Size;
2449+
}
2450+
else
2451+
{
2452+
SegmentOffset = InUseEntry->SegmentOffset;
2453+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
2454+
Heap->Segments[SegmentOffset]->LastEntryInSegment = InUseEntry;
2455+
}
24132456
}
24142457
else
24152458
{
@@ -2422,6 +2465,10 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
24222465
/* Update the following block or set the last entry in the segment */
24232466
if (RememberFlags & HEAP_ENTRY_LAST_ENTRY)
24242467
{
2468+
SegmentOffset = UnusedEntry->SegmentOffset;
2469+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
2470+
Heap->Segments[SegmentOffset]->LastEntryInSegment = UnusedEntry;
2471+
24252472
/* Set flags and size */
24262473
UnusedEntry->Flags = RememberFlags;
24272474
UnusedEntry->Size = (USHORT)FreeSize;
@@ -2468,7 +2515,15 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
24682515
UnusedEntry->Size = (USHORT)FreeSize;
24692516

24702517
if (!(RememberFlags & HEAP_ENTRY_LAST_ENTRY))
2518+
{
24712519
((PHEAP_ENTRY)UnusedEntry + FreeSize)->PreviousSize = (USHORT)FreeSize;
2520+
}
2521+
else
2522+
{
2523+
SegmentOffset = UnusedEntry->SegmentOffset;
2524+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
2525+
Heap->Segments[SegmentOffset]->LastEntryInSegment = UnusedEntry;
2526+
}
24722527

24732528
/* Insert it back and update total size */
24742529
RtlpInsertFreeBlockHelper(Heap, UnusedEntry, FreeSize, FALSE);
@@ -2578,6 +2633,7 @@ RtlReAllocateHeap(HANDLE HeapPtr,
25782633
SIZE_T RemainderBytes, ExtraSize;
25792634
PHEAP_VIRTUAL_ALLOC_ENTRY VirtualAllocBlock;
25802635
EXCEPTION_RECORD ExceptionRecord;
2636+
UCHAR SegmentOffset;
25812637

25822638
/* Return success in case of a null pointer */
25832639
if (!Ptr)
@@ -2787,6 +2843,10 @@ RtlReAllocateHeap(HANDLE HeapPtr,
27872843
/* Is that the last entry */
27882844
if (FreeFlags & HEAP_ENTRY_LAST_ENTRY)
27892845
{
2846+
SegmentOffset = SplitBlock->SegmentOffset;
2847+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
2848+
Heap->Segments[SegmentOffset]->LastEntryInSegment = SplitBlock;
2849+
27902850
/* Set its size and insert it to the list */
27912851
SplitBlock->Size = (USHORT)FreeSize;
27922852
RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, FALSE);
@@ -2834,6 +2894,12 @@ RtlReAllocateHeap(HANDLE HeapPtr,
28342894
/* Update previous size of the next entry */
28352895
((PHEAP_FREE_ENTRY)((PHEAP_ENTRY)SplitBlock + FreeSize))->PreviousSize = (USHORT)FreeSize;
28362896
}
2897+
else
2898+
{
2899+
SegmentOffset = SplitBlock->SegmentOffset;
2900+
ASSERT(SegmentOffset < HEAP_SEGMENTS);
2901+
Heap->Segments[SegmentOffset]->LastEntryInSegment = SplitBlock;
2902+
}
28372903

28382904
/* Insert the new one back and update total size */
28392905
RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, FALSE);

sdk/lib/rtl/heap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ typedef struct _HEAP_LIST_LOOKUP
217217
ULONG NumberOfUnCommittedRanges; \
218218
USHORT SegmentAllocatorBackTraceIndex; \
219219
USHORT Reserved; \
220-
LIST_ENTRY UCRSegmentList
220+
LIST_ENTRY UCRSegmentList; \
221+
PVOID LastEntryInSegment //FIXME: non-Vista
221222

222223
typedef struct _HEAP
223224
{

0 commit comments

Comments
 (0)