Search code examples
windowsmemoryx86-64memory-alignmentvirtual-address-space

Behind Windows x64's 44-bit virtual memory address limit


http://www.alex-ionescu.com/?p=50.

I read the above post. The author explains why Windows x64 supports only 44-bit virtual memory address with singly linked list example.

struct {  // 8-byte header
        ULONGLONG Depth:16;
        ULONGLONG Sequence:9;
        ULONGLONG NextEntry:39;
} Header8;

The first sacrifice to make was to reduce the space for the sequence number to 9 bits instead of 16 bits, reducing the maximum sequence number the list could achieve. This still only left 39 bits for the pointer — a mediocre improvement over 32 bits. By forcing the structure to be 16-byte aligned when allocated, 4 more bits could be won, since the bottom bits could now always be assumed to be 0.


Oh, I can't understand.

What "By forcing the structure to be 16-byte aligned when allocated, 4 more bits could be won, since the bottom bits could now always be assumed to be 0." means?


Solution

  • For a 2^N-byte aligned pointer, its address is always divisible by 2^N - which means that lower N bits are always zero. You can store additional information in them:

    encode ptr payload = ptr | payload
    decode_ptr data = data & ~mask
    decode_payload data = data & mask
    

    where mask is (1 << N) - 1 - i.e. a number with low N bits set.

    This trick is often used to save space in low-level code (payload can be GC flags, type tag, etc.)

    In effect you're not storing a pointer, but a number from which a pointer can be extracted. Of course, care should be taken to not dereference the number as a pointer without decoding.