Optimize memory layout

Compared to b69f3d2488, old windows specific fd, zipos and nsync memory ranges in libc/runtime/memtrack.internal.h were kept.
This commit is contained in:
Justine Tunney 2022-09-12 04:19:32 -07:00 committed by Gavin Hayes
parent 0740e68ea0
commit 555260d2e5
41 changed files with 381 additions and 345 deletions

View file

@ -31,8 +31,8 @@ uintptr_t __break;
*
* This can be used to allocate and deallocate memory. It won't
* conflict with malloc() and mmap(NULL, ...) allocations since
* APE binaries load the image at 0x400000 and does allocations
* starting at 0x100080000000. You should consult _end, or call
* APE binaries load the image at 0x440000 and does allocations
* starting at 0x100080040000. You should consult _end, or call
* sbrk(NULL), to figure out where the existing break is first.
*
* @return 0 on success or -1 w/ errno

View file

@ -1,45 +1,33 @@
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#include "libc/assert.h"
#include "libc/intrin/midpoint.h"
#include "libc/dce.h"
#include "libc/intrin/midpoint.h"
#include "libc/intrin/nopl.internal.h"
#include "libc/macros.internal.h"
#include "libc/thread/tls.h"
#include "libc/nt/version.h"
#include "libc/runtime/stack.h"
#include "libc/sysv/consts/ss.h"
#include "libc/thread/tls.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define kAutomapStart _kMem(0x100080000000, 0x000010000000)
#define kAutomapSize \
_kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \
0x000040000000 - 0x000010000000 - _kMmi(0x000080000000))
#define kMemtrackStart \
(ROUNDDOWN(_kMem(0x200000000000 - _kMmi(0x800000000000), \
0x000040000000 - _kMmi(0x000080000000)), \
FRAMESIZE * 8) - \
0x8000 * 8 /* so frame aligned after adding 0x7fff8000 */)
#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000))
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000)
#define kFixedmapSize \
_kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000)
#define kMemtrackFdsStart _kMemVista(0x6fe000040000, 0x5e000040000)
#define kMemtrackFdsSize \
#define kAutomapStart 0x100080040000
#define kAutomapSize (kMemtrackStart - kAutomapStart)
#define kMemtrackStart 0x1fe7fffc0000
#define kMemtrackSize (0x1ffffffc0000 - kMemtrackStart)
#define kFixedmapStart 0x300000040000
#define kFixedmapSize (0x400000040000 - kFixedmapStart)
#define kMemtrackFdsStart _kMemVista(0x6fe000040000, 0x5e000040000)
#define kMemtrackFdsSize \
(_kMemVista(0x6feffffc0000, 0x5effffc0000) - kMemtrackFdsStart)
#define kMemtrackZiposStart _kMemVista(0x6fd000040000, 0x5d000040000)
#define kMemtrackZiposSize \
#define kMemtrackZiposSize \
(_kMemVista(0x6fdffffc0000, 0x5dffffc0000) - kMemtrackZiposStart)
#define kMemtrackNsyncStart _kMemVista(0x6fc000040000, 0x5c000040000)
#define kMemtrackNsyncSize \
#define kMemtrackNsyncSize \
(_kMemVista(0x6fcffffc0000, 0x5cffffc0000 - kMemtrackNsyncStart)
#define _kMmi(VSPACE) \
ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \
FRAMESIZE)
#define _kMem(NORMAL, WIN7) \
(!IsWindows() || IsAtLeastWindows10() ? NORMAL : WIN7)
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
#define _kMemVista(NORMAL, WINVISTA) \
(!IsWindows() || IsAtleastWindows8p1() ? NORMAL : WINVISTA)
@ -93,23 +81,38 @@ forceinline pureconst bool IsLegalSize(size_t n) {
}
forceinline pureconst bool IsAutoFrame(int x) {
return (kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16);
return (int)(kAutomapStart >> 16) <= x &&
x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
}
forceinline pureconst bool IsMemtrackFrame(int x) {
return (kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16);
return (int)(kAutomapStart >> 16) <= x &&
x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
}
forceinline pureconst bool IsArenaFrame(int x) {
return 0x5000 <= x && x < 0x7ffe;
forceinline pureconst bool IsGfdsFrame(int x) {
return (int)(kMemtrackFdsStart >> 16) <= x &&
x <= (int)((kMemtrackFdsStart + kMemtrackFdsSize - 1) >> 16);
}
forceinline pureconst bool IsZiposFrame(int x) {
return (int)(kMemtrackZiposStart >> 16) <= x &&
x <= (int)((kMemtrackZiposStart + kMemtrackZiposSize - 1) >> 16);
}
forceinline pureconst bool IsNsyncFrame(int x) {
return (int)(kMemtrackNsyncStart >> 16) <= x &&
x <= (int)((kMemtrackNsyncStart + kMemtrackNsyncSize - 1) >> 16);
}
forceinline pureconst bool IsShadowFrame(int x) {
return 0x7fff <= x && x < 0x10008000;
}
forceinline pureconst bool IsArenaFrame(int x) {
return 0x5004 <= x && x <= 0x7ffb;
}
forceinline pureconst bool IsKernelFrame(int x) {
intptr_t stack = GetStaticStackAddr(0);
return (int)(stack >> 16) <= x &&
@ -128,15 +131,12 @@ forceinline pureconst bool IsStackFrame(int x) {
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsSigAltStackFrame(int x) {
intptr_t stack = GetStackAddr();
return (int)(stack >> 16) <= x &&
x <= (int)((stack + (SIGSTKSZ - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsOldStackFrame(int x) {
intptr_t old = ROUNDDOWN(__oldstack, STACKSIZE);
return (old >> 16) <= x && x <= ((old + (STACKSIZE - FRAMESIZE)) >> 16);
/* openbsd uses 4mb stack by default */
/* freebsd uses 512mb stack by default */
/* most systems use 8mb stack by default */
intptr_t old = ROUNDDOWN(__oldstack, GetStackSize());
return (old >> 16) <= x && x <= ((old + (GetStackSize() - FRAMESIZE)) >> 16);
}
forceinline pureconst bool IsFixedFrame(int x) {

View file

@ -3,8 +3,8 @@
00000000-0000001f 2048kb null
00000020-0000003f 2048kb loader
00000040-00004fff 1276mb image
00005000-00007ffd 768mb arena
00000040-00004ffb 1276mb image
00005004-00007ffb 768mb arena
00007ffe-00007ffe 64kb free
# address sanitizer shadow memory
@ -264,10 +264,10 @@
0fd00000-0fdfffff 64gb asan
0fe00000-0fefffff 64gb asan
0ff00000-0fffffff 64gb asan
10000000-10007fff 2048mb asan
10000000-10008003 2048mb asan
# memory dedicated to mmap(NULL, ...) automation, e.g. malloc()
10008000-100fffff 62gb automap
10008004-100fffff 62gb automap
10100000-101fffff 64gb automap
10200000-102fffff 64gb automap
10300000-103fffff 64gb automap
@ -521,13 +521,13 @@
1fb00000-1fbfffff 64gb automap
1fc00000-1fcfffff 64gb automap
1fd00000-1fdfffff 64gb automap
1fe00000-1fe7ffff 32gb automap
1fe00000-1fe7fffb 32gb automap
1fe7fffc-1fefffff 32gb _mmi
1ff00000-1ffffffb 64gb _mmi
1ffffffc-1fffffff 256kb free
1ffffffc-20000003 256kb free
20000000-200fffff 64gb free
20000004-200fffff 64gb free
20100000-201fffff 64gb free
20200000-202fffff 64gb free
20300000-203fffff 64gb free
@ -782,10 +782,10 @@
2fc00000-2fcfffff 64gb free
2fd00000-2fdfffff 64gb free
2fe00000-2fefffff 64gb free
2ff00000-2fffffff 64gb free
2ff00000-30000003 64gb free
# memory recommended for application MAP_FIXED usage
30000000-300fffff 64gb fixedmap
30000004-300fffff 64gb fixedmap
30100000-301fffff 64gb fixedmap
30200000-302fffff 64gb fixedmap
30300000-303fffff 64gb fixedmap
@ -1040,9 +1040,9 @@
3fc00000-3fcfffff 64gb fixedmap
3fd00000-3fdfffff 64gb fixedmap
3fe00000-3fefffff 64gb fixedmap
3ff00000-3fffffff 64gb fixedmap
3ff00000-40000003 64gb fixedmap
40000000-400fffff 64gb free
40000004-400fffff 64gb free
40100000-401fffff 64gb free
40200000-402fffff 64gb free
40300000-403fffff 64gb free
@ -1808,14 +1808,14 @@
6f900000-6f9fffff 64gb free
6fa00000-6fafffff 64gb free
6fb00000-6fbfffff 64gb free
6fc00004-6fcfffff 64gb nsync
6fd00000-6fdfffff 64gb zipos
6fe00004-6feffffc 64gb g_fds
6ff00000-6ffffffd 64gb free
6ffffffe-6fffffff 128kb winargs
6fc00004-6fcffffb 64gb nsync
6fd00004-6fdffffb 64gb zipos
6fe00004-6feffffb 64gb g_fds
6ff00004-70000003 64gb free
70000000-70000001 128kb stack
70000002-700fffff 64gb free
70000004-70000004 64kb stack
70000005-70000006 128kb winargs
70000005-700fffff 64gb free
70100000-701fffff 64gb free
70200000-702fffff 64gb free
70300000-703fffff 64gb free

View file

@ -107,18 +107,14 @@ extern char ape_stack_align[] __attribute__((__weak__));
* problematic, since MODE=tiny doesn't use any of the runtime codes
* which want the stack to be cheaply knowable, e.g. ftrace, kprintf
*/
#define GetStaticStackAddr(ADDEND) \
({ \
intptr_t vAddr; \
if (!IsWindows() || IsAtLeastWindows10()) { \
__asm__(".weak\tape_stack_vaddr\n\t" \
"movabs\t%1+ape_stack_vaddr,%0" \
: "=r"(vAddr) \
: "i"(ADDEND)); \
} else { \
vAddr = 0x100000000 - GetStackSize(); \
} \
vAddr; \
#define GetStaticStackAddr(ADDEND) \
({ \
intptr_t vAddr; \
__asm__(".weak\tape_stack_vaddr\n\t" \
"movabs\t%1+ape_stack_vaddr,%0" \
: "=r"(vAddr) \
: "i"(ADDEND)); \
vAddr; \
})
/**

View file

@ -166,8 +166,8 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
char outflagsbuf[128];
const char16_t *env16;
int i, prot, count, version;
size_t allocsize, stacksize;
intptr_t stackaddr, allocaddr;
size_t allocsize, argsize, stacksize;
version = NtGetPeb()->OSMajorVersion;
__oldstack = (intptr_t)__builtin_frame_address(0);
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
@ -190,15 +190,14 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
rc);
}
}
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
_mmi.p = _mmi.s;
_mmi.n = ARRAYLEN(_mmi.s);
argsize = ROUNDUP(sizeof(struct WinArgs), FRAMESIZE);
stackaddr = GetStaticStackAddr(0);
stacksize = GetStackSize();
allocsize = argsize + stacksize;
allocaddr = stackaddr - argsize;
NTTRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize,
allocaddr);
allocaddr = stackaddr;
allocsize = stacksize + sizeof(struct WinArgs);
NTTRACE("WinMainNew() mapping %'zu byte stack at %p", allocsize, allocaddr);
MapViewOfFileEx(
(_mmi.p[0].h =
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
@ -209,12 +208,12 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite, &oldprot);
}
_mmi.p[0].x = allocaddr >> 16;
_mmi.p[0].y = (allocaddr >> 16) + ((allocsize >> 16) - 1);
_mmi.p[0].y = (allocaddr >> 16) + ((allocsize - 1) >> 16);
_mmi.p[0].prot = prot;
_mmi.p[0].flags = 0x00000026; // stack+anonymous
_mmi.p[0].size = allocsize;
_mmi.i = 1;
wa = (struct WinArgs *)allocaddr;
wa = (struct WinArgs *)(allocaddr + stacksize);
NTTRACE("WinMainNew() loading arg block");
count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv,
ARRAYLEN(wa->argv));