aboutsummaryrefslogtreecommitdiff
path: root/vm/vm_page.h
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2023-06-26 14:26:50 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-07-03 01:59:49 +0200
commit505ecd7b30fca1dc296205ff3c0dc3aff9d76e12 (patch)
treef19cb99981292863d2db5ae6a0ad43e559b3acac /vm/vm_page.h
parentd5464d531aaba049a3e734adb80fb0bfd28093a7 (diff)
downloadgnumach-505ecd7b30fca1dc296205ff3c0dc3aff9d76e12.tar.gz
gnumach-505ecd7b30fca1dc296205ff3c0dc3aff9d76e12.tar.bz2
gnumach-505ecd7b30fca1dc296205ff3c0dc3aff9d76e12.zip
Shrink struct vm_page size
struct vm_page is supposed to be a "small structure", but it takes up 96 bytes on x86_64 (to represent a 4k page). By utilizing bitfields and strategically reordering members to avoid excessive padding, it can be shrunk to 80 bytes. - page_lock and unlock_request only need to store a bitmask of VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE. Even though the special values VM_PROT_NO_CHANGE and VM_PROT_NOTIFY are defined, they are not used for the two struct vm_page members. - type and seg_index both need to store one of the four possible values in the range from 0 to 3. Two bits are sufficient for this. - order needs to store a number from 0 to VM_PAGE_NR_FREE_LISTS (which is 11), or a special value VM_PAGE_ORDER_UNLISTED. Four bits are sufficient for this. No functional change. Message-Id: <20230626112656.435622-2-bugaevc@gmail.com>
Diffstat (limited to 'vm/vm_page.h')
-rw-r--r--vm/vm_page.h18
1 files changed, 12 insertions, 6 deletions
diff --git a/vm/vm_page.h b/vm/vm_page.h
index d457f9a2..b2581d9e 100644
--- a/vm/vm_page.h
+++ b/vm/vm_page.h
@@ -79,9 +79,6 @@
struct vm_page {
struct list node; /* page queues or free list (P) */
- unsigned short type;
- unsigned short seg_index;
- unsigned short order;
void *priv;
/*
@@ -95,7 +92,6 @@ struct vm_page {
/* We use an empty struct as the delimiter. */
struct {} vm_page_header;
-#define VM_PAGE_HEADER_SIZE offsetof(struct vm_page, vm_page_header)
vm_object_t object; /* which object am I in (O,P) */
vm_offset_t offset; /* offset into that object (O,P) */
@@ -126,10 +122,20 @@ struct vm_page {
* without having data. (O)
* [See vm_object_overwrite] */
- vm_prot_t page_lock; /* Uses prohibited by data manager (O) */
- vm_prot_t unlock_request; /* Outstanding unlock request (O) */
+ vm_prot_t page_lock:3; /* Uses prohibited by data manager (O) */
+ vm_prot_t unlock_request:3; /* Outstanding unlock request (O) */
+
+ struct {} vm_page_footer;
+
+ unsigned short type:2;
+ unsigned short seg_index:2;
+ unsigned short order:4;
};
+#define VM_PAGE_BODY_SIZE \
+ (offsetof(struct vm_page, vm_page_footer) \
+ - offsetof(struct vm_page, vm_page_header))
+
/*
* For debugging, this macro can be defined to perform
* some useful check on a page structure.