@@ -702,10 +702,12 @@ RtlpFindAndCommitPages(PHEAP Heap,
702
702
if (UcrDescriptor -> Address == Segment -> LastValidEntry )
703
703
{
704
704
FirstEntry -> Flags = HEAP_ENTRY_LAST_ENTRY ;
705
+ Segment -> LastEntryInSegment = FirstEntry ;
705
706
}
706
707
else
707
708
{
708
709
FirstEntry -> Flags = 0 ;
710
+ Segment -> LastEntryInSegment = Segment -> FirstEntry ;
709
711
/* Update field of next entry */
710
712
ASSERT ((FirstEntry + FirstEntry -> Size )-> PreviousSize == 0 );
711
713
(FirstEntry + FirstEntry -> Size )-> PreviousSize = FirstEntry -> Size ;
@@ -720,6 +722,7 @@ RtlpFindAndCommitPages(PHEAP Heap,
720
722
else
721
723
{
722
724
FirstEntry -> Flags = HEAP_ENTRY_LAST_ENTRY ;
725
+ Segment -> LastEntryInSegment = FirstEntry ;
723
726
}
724
727
725
728
/* We're done */
@@ -841,6 +844,7 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
841
844
FreeEntry -> Flags = HEAP_ENTRY_LAST_ENTRY ;
842
845
FreeEntry -> Size = (USHORT )PrecedingSize ;
843
846
Heap -> TotalFreeSize += PrecedingSize ;
847
+ Segment -> LastEntryInSegment = FreeEntry ;
844
848
845
849
/* Insert it into the free list */
846
850
RtlpInsertFreeBlockHelper (Heap , FreeEntry , PrecedingSize , FALSE);
@@ -849,6 +853,13 @@ RtlpDeCommitFreeBlock(PHEAP Heap,
849
853
{
850
854
/* Adjust preceding in use entry */
851
855
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 ;
852
863
}
853
864
854
865
/* Now the next one */
@@ -933,6 +944,9 @@ RtlpInitializeHeapSegment(IN OUT PHEAP Heap,
933
944
RtlpInsertFreeBlock (Heap , (PHEAP_FREE_ENTRY ) HeapEntry , (SegmentCommit >> HEAP_ENTRY_SHIFT ) - Segment -> Entry .Size );
934
945
}
935
946
947
+ /* Always point to a valid entry */
948
+ Segment -> LastEntryInSegment = Segment -> FirstEntry ;
949
+
936
950
/* Initialise the Heap Segment UnCommitted Range information */
937
951
Segment -> NumberOfUnCommittedPages = (ULONG )((SegmentReserve - SegmentCommit ) >> PAGE_SHIFT );
938
952
Segment -> NumberOfUnCommittedRanges = 0 ;
@@ -984,6 +998,7 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
984
998
BOOLEAN Remove )
985
999
{
986
1000
PHEAP_FREE_ENTRY CurrentEntry , NextEntry ;
1001
+ UCHAR SegmentOffset ;
987
1002
988
1003
/* Get the previous entry */
989
1004
CurrentEntry = (PHEAP_FREE_ENTRY )((PHEAP_ENTRY )FreeEntry - FreeEntry -> PreviousSize );
@@ -1022,6 +1037,12 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
1022
1037
{
1023
1038
((PHEAP_ENTRY )FreeEntry + * FreeSize )-> PreviousSize = (USHORT )(* FreeSize );
1024
1039
}
1040
+ else
1041
+ {
1042
+ SegmentOffset = FreeEntry -> SegmentOffset ;
1043
+ ASSERT (SegmentOffset < HEAP_SEGMENTS );
1044
+ Heap -> Segments [SegmentOffset ]-> LastEntryInSegment = FreeEntry ;
1045
+ }
1025
1046
}
1026
1047
1027
1048
/* Check the next block if it exists */
@@ -1057,6 +1078,12 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
1057
1078
{
1058
1079
((PHEAP_ENTRY )FreeEntry + * FreeSize )-> PreviousSize = (USHORT )(* FreeSize );
1059
1080
}
1081
+ else
1082
+ {
1083
+ SegmentOffset = FreeEntry -> SegmentOffset ;
1084
+ ASSERT (SegmentOffset < HEAP_SEGMENTS );
1085
+ Heap -> Segments [SegmentOffset ]-> LastEntryInSegment = FreeEntry ;
1086
+ }
1060
1087
}
1061
1088
}
1062
1089
return FreeEntry ;
@@ -1637,6 +1664,7 @@ RtlpSplitEntry(PHEAP Heap,
1637
1664
UCHAR FreeFlags , EntryFlags = HEAP_ENTRY_BUSY ;
1638
1665
PHEAP_ENTRY InUseEntry ;
1639
1666
SIZE_T FreeSize ;
1667
+ UCHAR SegmentOffset ;
1640
1668
1641
1669
/* Add extra flags in case of settable user value feature is requested,
1642
1670
or there is a tag (small or normal) or there is a request to
@@ -1748,6 +1776,12 @@ RtlpSplitEntry(PHEAP Heap,
1748
1776
1749
1777
/* Reset flags of the free entry */
1750
1778
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
+ }
1751
1785
}
1752
1786
}
1753
1787
@@ -2311,6 +2345,7 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
2311
2345
PHEAP_FREE_ENTRY FreeEntry , UnusedEntry , FollowingEntry ;
2312
2346
SIZE_T FreeSize , PrevSize , TailPart , AddedSize = 0 ;
2313
2347
PHEAP_ENTRY_EXTRA OldExtra , NewExtra ;
2348
+ UCHAR SegmentOffset ;
2314
2349
2315
2350
/* We can't grow beyond specified threshold */
2316
2351
if (Index > Heap -> VirtualMemoryThreshold )
@@ -2407,9 +2442,17 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
2407
2442
InUseEntry -> Flags |= RememberFlags & HEAP_ENTRY_LAST_ENTRY ;
2408
2443
2409
2444
/* Either update previous size of the next entry or mark it as a last
2410
- entry in the segment*/
2445
+ entry in the segment */
2411
2446
if (!(RememberFlags & HEAP_ENTRY_LAST_ENTRY ))
2447
+ {
2412
2448
(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
+ }
2413
2456
}
2414
2457
else
2415
2458
{
@@ -2422,6 +2465,10 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
2422
2465
/* Update the following block or set the last entry in the segment */
2423
2466
if (RememberFlags & HEAP_ENTRY_LAST_ENTRY )
2424
2467
{
2468
+ SegmentOffset = UnusedEntry -> SegmentOffset ;
2469
+ ASSERT (SegmentOffset < HEAP_SEGMENTS );
2470
+ Heap -> Segments [SegmentOffset ]-> LastEntryInSegment = UnusedEntry ;
2471
+
2425
2472
/* Set flags and size */
2426
2473
UnusedEntry -> Flags = RememberFlags ;
2427
2474
UnusedEntry -> Size = (USHORT )FreeSize ;
@@ -2468,7 +2515,15 @@ RtlpGrowBlockInPlace (IN PHEAP Heap,
2468
2515
UnusedEntry -> Size = (USHORT )FreeSize ;
2469
2516
2470
2517
if (!(RememberFlags & HEAP_ENTRY_LAST_ENTRY ))
2518
+ {
2471
2519
((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
+ }
2472
2527
2473
2528
/* Insert it back and update total size */
2474
2529
RtlpInsertFreeBlockHelper (Heap , UnusedEntry , FreeSize , FALSE);
@@ -2578,6 +2633,7 @@ RtlReAllocateHeap(HANDLE HeapPtr,
2578
2633
SIZE_T RemainderBytes , ExtraSize ;
2579
2634
PHEAP_VIRTUAL_ALLOC_ENTRY VirtualAllocBlock ;
2580
2635
EXCEPTION_RECORD ExceptionRecord ;
2636
+ UCHAR SegmentOffset ;
2581
2637
2582
2638
/* Return success in case of a null pointer */
2583
2639
if (!Ptr )
@@ -2787,6 +2843,10 @@ RtlReAllocateHeap(HANDLE HeapPtr,
2787
2843
/* Is that the last entry */
2788
2844
if (FreeFlags & HEAP_ENTRY_LAST_ENTRY )
2789
2845
{
2846
+ SegmentOffset = SplitBlock -> SegmentOffset ;
2847
+ ASSERT (SegmentOffset < HEAP_SEGMENTS );
2848
+ Heap -> Segments [SegmentOffset ]-> LastEntryInSegment = SplitBlock ;
2849
+
2790
2850
/* Set its size and insert it to the list */
2791
2851
SplitBlock -> Size = (USHORT )FreeSize ;
2792
2852
RtlpInsertFreeBlockHelper (Heap , SplitBlock , FreeSize , FALSE);
@@ -2834,6 +2894,12 @@ RtlReAllocateHeap(HANDLE HeapPtr,
2834
2894
/* Update previous size of the next entry */
2835
2895
((PHEAP_FREE_ENTRY )((PHEAP_ENTRY )SplitBlock + FreeSize ))-> PreviousSize = (USHORT )FreeSize ;
2836
2896
}
2897
+ else
2898
+ {
2899
+ SegmentOffset = SplitBlock -> SegmentOffset ;
2900
+ ASSERT (SegmentOffset < HEAP_SEGMENTS );
2901
+ Heap -> Segments [SegmentOffset ]-> LastEntryInSegment = SplitBlock ;
2902
+ }
2837
2903
2838
2904
/* Insert the new one back and update total size */
2839
2905
RtlpInsertFreeBlockHelper (Heap , SplitBlock , FreeSize , FALSE);
0 commit comments