Code Analysis: wine heapallocate Function

Source: Internet
Author: User

Heapallocate ()



Wine-1.0 + ReactOS-3.8

4bsfreedom@gmail.com

Here is some analysis of heap functions. It is best to refer to wine source code when reading the code. You can download wine source code from www.winehq.org.
The source code of reactos is downloaded at www.reactos.org.

1 Check


Heapallocate-> rtlallocateheap
The heapallocate function calls the rtlallocateheap function. So let's look at the rtlallocateheap function.
This function is in DLLs/NTDLL/heap. C.
Let's first look at the code of this function:
Heap * heapptr = heap_getptr (HEAP );

Flags & = heap_generate_exceptions | heap_no_serialize | heap_zero_memory;
Flags | = heapptr-> flags;

Rounded_size = round_size (size );

When the function comes in, heap_getptr () is used to convert the heap handle into a pointer, which is actually a simple forced conversion:
336 /************************************** *********************************
337 * heap_getptr
338 * returns
339 * pointer to the heap
340 * NULL: Failure
341 */
342 static heap * heap_getptr (
343 handle Heap/* [in] handle to the heap */
(344 ){
345 heap * heapptr = (heap *) heap;
...
....
357 return heapptr;
358}
After getting the pointer to the heap, check flags. For the value of flags and its meaning, refer to Windows core programming (reference 1 ).
After checking flags, use the macro round_size () to perform an 8-byte alignment.
However
Then, check whether the size of the requested space has exceeded. If the requested space has exceeded and the heap_generate_exceptions flag is set, it will be transferred.
Run the rtlraisestatus () function. Otherwise, null is returned. (I am not very familiar with the overflow check method here. In reactos3.7, this overflow check has been removed,
But 3.8 is added again.) Obviously, rtlraisestatus () is a soft interrupt in the past, causing an exception.

If (! (Flags & heap_no_serialize) rtlentercriticalsection (& heapptr-> critsection );
If the heap_no_serialize flag is not set and the allocated space is continuous, it enters the critical section. To prevent continuous space from being truncated when it has not been allocated. Correspondingly, if you enter the critical section, the critical section will exit before the function ends.
If (! (Flags & heap_no_serialize) rtlleavecriticalsection (& heapptr-> critsection );
Here, rtlentercriticalsection and rtlleavecriticalsection are a pair of functions. For a simple understanding, you can use rtlentercriticalsection as a lock and use it as an rtlleavecriticalsection to unlock it.

2. Find a suitable free space heap_findfreeblock ()


2.1 find a suitable space from the free queue


Heapallocate-> rtlallocateheap-> heap_findfreeblock

/* Find a suitable free list, and in it find a block large enough */
Continue:
If (! (PARENA = heap_findfreeblock (heapptr, rounded_size, & subheap )))
Heap_findfreeblock ():
Free_list_entry * pentry = heap-> freelist + get_freelist_index (size + sizeof (arena_inuse ));
First
In the free_list_entry queue, locate a heap whose size is not smaller than the applied size. Function get_freelist_index ()
Size + sizeof (arena_inuse)-sizeof (arena_free) to compare with the heap_freelistsizes [] array to see
Select the heap queue of which granularity, and return the id I of the heap queue of this granularity, so that pentry points to the heap free queue of this granularity.

2.1.1 find the appropriate arena_free and subheap


Heapallocate-> rtlallocateheap-> heap_findfreeblock-> heap_findsubheap

PTR = & pentry-> arena. entry;
PTR is the pointer to the address of the connector (Entry member) pointing to this queue.
Arena_free * PARENA = list_entry (PTR, arena_free, entry );
In arena_free
In the queue, each element is an arena_free structure, and each arena_free structure contains the same Member-struct List entry
Concatenate them, and PTR points to n
An entry Member of the arena_free structure. If the value of the list_entry (PTR, arena_free, entry) macro reaches
N arena_free structures.

While (PTR = list_next (& heap-> freelist [0]. arena. Entry, PTR )))
Times
Returns the linked list of the arena_free structure. If the size of an arena_free structure is greater than the applied size, it is transferred to heap_findsubheap (
Heap, PARENA) locate the heap in which the arena_free structure that PARENA points to is included, and return the subheap pointer to this sub-heap.

2.1.2 heap_commit ()


Heap allocate-> r tlallocateheap-> heap_findfreeblock-> heap_commit
The Windows system memory must be commit before it can be used.

Void * PTR = (char *) (PARENA + 1) + data_size + sizeof (arena_free );
Converts the size of data_size + sizeof (arena_free)
[Data_size + sizeof (arena_free)-sizeof (arena_inuse)] + sizeof (arena_inuse) size. Square brackets enclose the size value of the new inuse.

Size_t size = (char *) PTR-(char *) subheap-> base;
New heap size

If (size> subheap-> size) size = subheap-> size;
This situation does not occur because of this. The previous check may be used to prevent unexpected damages.

If the size is smaller than the size of the memory that has been committed in subheap, the new commit area is successful. Otherwise, ntallocatevirualmemory () is called to commit the extra memory to complete the commit operation.

2.2 If no suitable block is found, try increasing the heap.


Heap allocate-> r tlallocateheap-> heap_findfreeblock-> heap_createsubheap
/* If no block was found, attempt to grow the heap */
Tune
Use heap_createsubheap () to create a new subheap. First, alignment the size and size, and the base is null.
Ntallocatevirtualmemory (..., mem_reserve,...) allocates a piece of memory to create a sub-heap. Note: mem_reserve mark
Log. You also need to perform the commit operation later.
Then, heap_initsubheap () is called to initialize the new subheap. If yes, the address of the new subheap is returned.

2.2.1 heap_initsubheap


Heap allocate-> r tlallocateheap-> heap_findfreeblock-> heap_createsubheap-> heap_initsubheap
This
Function to initialize the created heap. Here, the memory of the previous mem_reserve is changed to mem_commit to make the memory available. If the heap is not the first subheap
Converts it to subheap and attaches it to subheap_list. If it is the first subheap, It is initialized to a heap, including the initialization field, building the idle queue, and initializing the critical section.
.

Call heap_createfreeblock () to create the first idle block of the sub-heap.

2.2.2 heap_createfreeblock


Heapallocate
-> Rtlallocateheap-> heap_findfreeblock-> heap_createsubheap
-> Heap_initsubheap-> heap_createfreeblock
I have ignored debugging information. If you are particularly interested, please read it in detail.
Create an arena_free structure and initialize the content.
If (pend> (char *) (pfree + 1) mark_block_free (pfree + 1, pend-(char *) (pfree + 1 ));
This statement does this.
Next, check whether the size meets the requirements (normally the requested size is obtained). If the previous arena_free is not large enough, then, move the next arena_free in the freelist queue to the idle block, and remove the (next arena_free) structure from the idle queue.
Then, call the heap_inserfreeblock function to put the idle block in the idle queue of the new subheap.

Finally, adjust the size of the heap and idle queue to return the address of the new idle queue.

3 heap_shrinkblock

List_remove (& PARENA-> entry );
Remove the newly applied block (PARENA) from the idle queue and adjust the space difference from arena_free to arena_inuse.

3.1 heap_shrinkblock () Shrinkage


Heapallocate-> rtlallocateheap-> heap_findfreeblock-> heap_shrinkblock
Before
The heap_shrinkblock function draws one or two arena_free entries.
Heap_createfreeblock increases the applied space. Then/* Turn off prev_free flag in next block
*/.

Return to the rtlallocateheap function, and record the unused space size to the pinuse-> unused_bytes field. Then, the initial address of the applied inuse is returned to the caller.

Renference:

Windows core programming chapter 18th
Introduction to heap-related data structures

Viewtopic. php? F = 6 & t = 297 & St = 0 & Sk = T & SD = A & START = 0

Windows heap Management

Viewtopic. php? F = 6 & t = 352

 

PS: Your blog does not have dead. The main reason is that Longjing has put a lot of spare time into the Forum after the project is opened. Therefore, there is very little time to write.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.