Skip to content

linux arm64 64kb page size#176

Merged
dylan-conway merged 3 commits intomainfrom
dylan/webkit-linux-arm64-64kb-page-size
Mar 20, 2026
Merged

linux arm64 64kb page size#176
dylan-conway merged 3 commits intomainfrom
dylan/webkit-linux-arm64-64kb-page-size

Conversation

@dylan-conway
Copy link
Copy Markdown
Member

Summary

Support Linux ARM64 kernels with 64KB pages (RHEL aarch64, Oracle Linux, Ubuntu generic-64k) without disabling JIT or libpas. Previously these systems hit RELEASE_ASSERT in WTF::pageSize() at startup.

Upstream's USE_64KB_PAGE_BLOCK option disables JIT and switches to mimalloc — this patch keeps both enabled.

Changes

Three commits, the first two rebased from the reverted PR #165:

0e6a06612 — raise compile-time page ceilings

  • CeilingOnPageSize 16K → 64K for OS(LINUX) && CPU(ARM64)
  • libpas small page, small bitfit, granule: 16K → 64K
  • libpas medium page: 128K → 256K
  • JIT heap small page/granule: 16K → 64K; medium page/granule: 128K/16K → 256K/64K
  • PAS_EXPENDABLE_MEMORY_PAGE_SIZE: 16K → 64K

82cc18638 — derive PAS_MAX_OBJECTS_PER_PAGE from page size
Was hardcoded 2048, which assumed 16K pages. With 64K pages the utility heap has num_alloc_bits = 64K >> 3 = 8192, overflowing the baseline allocator's bit array when a thread hits pas_baseline_allocator_attach_directory on the slow path. This is the bug that caused
the #165 revert. Now derived: PAS_SMALL_PAGE_DEFAULT_SIZE >> PAS_INTERNAL_MIN_ALIGN_SHIFT.

d56ecd41 — bump JIT_MEDIUM_BITFIT_MIN_ALIGN_SHIFT 8 → 9
New bug found by static analysis. pas_page_granule_use_count is uint8_t with 255 reserved as the DECOMMITTED sentinel. Max objects per granule is granule_size >> min_align_shift + 1. At 64K >> 8 + 1 = 257 the counter overflows; at 64K >> 9 + 1 = 129 it's safe.
Crash-reproduced: buggy build SIGTRAPs after ~500-1000 JIT-compiled functions; fixed build passes.

Verified

  • Static constraint check: all 9 libpas heap configs (utility, bmalloc small/medium seg + small/medium/marge bitfit, jit small seg + small/medium bitfit) pass granule ≥ os_page, use_count < 255, num_alloc_bits ≤ PAS_MAX_OBJECTS_PER_PAGE, num_granules ≤ PAS_MAX_GRANULES for OS page sizes {4K, 16K, 64K}
  • aarch64 jsc (via release Dockerfile under qemu-user) passes stress test exercising baseline allocator slow path, JIT medium bitfit churn, scavenger decommit, concurrent JIT+GC
  • Negative test: jsc built at 0e6a06612 (both fixes absent) SIGTRAPs in phase 2

Trade-off

Changes are unconditional for Linux ARM64 — a single binary runs on 4K/16K/64K kernels. On 4K-page systems (most distros, AWS Graviton):

  • MarkedBlock::blockSize 16K → 64K (4× GC block overhead)
  • libpas small page 16K → 64K (4× min slab)
  • Large expendable memory VA 32MB → 512MB per block (VA only, not RSS)

CeilingOnPageSize is used in alignas() and constexpr — can't be runtime-selected without restructuring MarkedBlock.

Claude Bot and others added 3 commits March 17, 2026 20:09
Linux ARM64 kernels can be configured with 4KB, 16KB, or 64KB page
sizes. Previously, the default CeilingOnPageSize for Linux ARM64 was
16KB, which caused an immediate RELEASE_ASSERT crash on systems with
64KB pages (e.g., RHEL aarch64, Oracle Linux, Ubuntu generic-64k).

The existing USE(64KB_PAGE_BLOCK) workaround disables both JIT and
bmalloc/libpas, which is a significant performance regression.

This change raises CeilingOnPageSize to 64KB for all Linux ARM64
builds, and correspondingly updates libpas page/granule sizes to be
at least 64KB on Linux ARM64. This allows Bun and other WebKit
embedders to run on 64KB page kernels with full JIT and libpas
support.

Changes:
- WTF/PageBlock.h: Set CeilingOnPageSize=64KB for Linux ARM64
- libpas/pas_internal_config.h: Raise small page (16KB->64KB),
  small bitfit page (16KB->64KB), medium page (128KB->256KB),
  and granule size (16KB->64KB) for Linux ARM64
- libpas/jit_heap_config.h: Raise JIT small page/granule (16KB->64KB)
  and JIT medium page/granule (128KB->256KB / 16KB->64KB)
- libpas/pas_expendable_memory.h: Raise expendable memory page size
  (16KB->64KB) for Linux ARM64
- bmalloc/BPlatform.h: Add BUSE_PRECOMPUTED_CONSTANTS_VMPAGE64K

These changes propagate correctly through:
- ConfigSizeToProtect (via std::max(CeilingOnPageSize, 16*KB))
- OpcodeConfigSizeToProtect (same pattern)
- MarkedBlock::blockSize (via std::max(16*KB, CeilingOnPageSize))
- All libpas heap configs that use PAS_*_DEFAULT_SIZE constants
- mprotect/mmap calls that use runtime pageSize()

Co-Authored-By: Claude <noreply@anthropic.com>
The previous hardcoded 2048 assumed PAS_SMALL_PAGE_DEFAULT_SIZE=16KB.
With 64KB pages, num_alloc_bits = page_size >> min_align_shift can reach
8192 (utility heap, PAS_INTERNAL_MIN_ALIGN_SHIFT=3), causing
pas_baseline_allocator_attach_directory to PAS_ASSERT when a thread hits
the baseline allocator slow path.
…anule use-count under uint8_t DECOMMITTED sentinel
@dylan-conway dylan-conway merged commit b55703a into main Mar 20, 2026
2 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 20, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2791f1af-3d49-4c81-a620-45705406b76a

📥 Commits

Reviewing files that changed from the base of the PR and between 00e8255 and d56ecd4.

📒 Files selected for processing (5)
  • Source/WTF/wtf/PageBlock.h
  • Source/bmalloc/bmalloc/BPlatform.h
  • Source/bmalloc/libpas/src/libpas/jit_heap_config.h
  • Source/bmalloc/libpas/src/libpas/pas_expendable_memory.h
  • Source/bmalloc/libpas/src/libpas/pas_internal_config.h

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


Walkthrough

Updated compile-time page-size configurations for Linux ARM64 across WTF and bmalloc subsystems, changing default allocator page sizes from 16 KiB to 64 KiB. Modified PageBlock.h selection logic and added platform-specific constants in multiple configuration headers.

Changes

Cohort / File(s) Summary
Core Page Size Selection
Source/WTF/wtf/PageBlock.h
Modified CeilingOnPageSize compile-time conditional logic to set 64 KiB for Linux ARM64, removing prior 16 KiB default and special-case prevention mechanism. Updated accompanying comment.
Memory Allocation Feature Guards
Source/bmalloc/bmalloc/BPlatform.h
Added BUSE_PRECOMPUTED_CONSTANTS_VMPAGE64K macro guard definition, extending existing pattern for 4K and 16K precomputed constants.
JIT Heap Configuration
Source/bmalloc/libpas/src/libpas/jit_heap_config.h
Added ARM64+Linux-specific JIT heap sizing: small/granule sizes changed to 64K/64K, medium sizes set to 262144/65536, and bitfit alignment shift updated with new comment.
Expendable Memory Paging
Source/bmalloc/libpas/src/libpas/pas_expendable_memory.h
Updated PAS_EXPENDABLE_MEMORY_PAGE_SIZE macro to resolve to 64 KiB on ARM64 Linux, otherwise 16 KiB; affects page-indexing calculations.
Internal Allocator Configuration
Source/bmalloc/libpas/src/libpas/pas_internal_config.h
Added Linux-ARM64-specific shifts and granule defaults (small: 16, medium: 18, granule: 16); refactored PAS_MAX_OBJECTS_PER_PAGE from fixed 2048 to computed expression based on page size.

Possibly related PRs


Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can validate your CodeRabbit configuration file in your editor.

If your editor has YAML language server, you can enable auto-completion and validation by adding # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json at the top of your CodeRabbit configuration file.

@github-actions
Copy link
Copy Markdown

Preview Builds

Commit Release Date
d56ecd41 autobuild-preview-pr-176-d56ecd41 2026-03-20 23:04:33 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant