diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 28914118de94..cde2e70b7352 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,12 +30,14 @@ jobs: target: x86_64-pc-windows-msvc code-target: win32-x64 pgo: clap-rs/clap@v4.5.36 + allocator: jemalloc - os: windows-latest target: i686-pc-windows-msvc pgo: clap-rs/clap@v4.5.36 - os: windows-latest target: aarch64-pc-windows-msvc code-target: win32-arm64 + allocator: jemalloc - os: ubuntu-latest target: x86_64-unknown-linux-gnu # Use a container with glibc 2.28 @@ -43,15 +45,18 @@ jobs: container: quay.io/pypa/manylinux_2_28_x86_64 code-target: linux-x64 pgo: clap-rs/clap@v4.5.36 + allocator: jemalloc - os: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu container: quay.io/pypa/manylinux_2_28_aarch64 code-target: linux-arm64 pgo: clap-rs/clap@v4.5.36 + allocator: jemalloc - os: ubuntu-latest target: arm-unknown-linux-gnueabihf zig_target: arm-unknown-linux-gnueabihf.2.28 code-target: linux-armhf + allocator: jemalloc - os: macos-14 target: x86_64-apple-darwin code-target: darwin-x64 @@ -67,6 +72,8 @@ jobs: env: RA_TARGET: ${{ matrix.target }} + ALLOCATOR: ${{ matrix.allocator && format('--allocator {0}', matrix.allocator) || '' }} + PGO: ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || '' }} steps: - name: Checkout repository @@ -102,11 +109,11 @@ jobs: - name: Dist (plain) if: ${{ !matrix.zig_target }} - run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}} + run: cargo xtask dist --client-patch-version ${{ github.run_number }} $PGO $ALLOCATOR - name: Dist (using zigbuild) if: ${{ matrix.zig_target }} - run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}} + run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig $PGO $ALLOCATOR - run: npm ci working-directory: editors/code diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs index 57a6a0eae1be..ed28d2478e2f 100644 --- a/xtask/src/dist.rs +++ b/xtask/src/dist.rs @@ -11,7 +11,7 @@ use zip::{DateTime, ZipWriter, write::SimpleFileOptions}; use crate::{ date_iso, - flags::{self, Malloc, PgoTrainingCrate}, + flags::{self, Allocator, PgoTrainingCrate}, project_root, util::detect_target, }; @@ -26,11 +26,14 @@ impl flags::Dist { let project_root = project_root(); let target = Target::get(&project_root, sh); - let allocator = self.allocator(); + let allocator = self.allocator.unwrap_or_default(); let dist = project_root.join("dist"); sh.remove_path(&dist)?; sh.create_dir(&dist)?; + // Profiling requires debug information. + let dev_rel = matches!(allocator, Allocator::Dhat); + if let Some(patch_version) = self.client_patch_version { let version = if stable { format!("{VERSION_STABLE}.{patch_version}") @@ -45,22 +48,12 @@ impl flags::Dist { allocator, self.zig, self.pgo, - // Profiling requires debug information. - self.enable_profiling, + dev_rel, )?; let release_tag = if stable { date_iso(sh)? } else { "nightly".to_owned() }; dist_client(sh, &version, &release_tag, &target)?; } else { - dist_server( - sh, - "0.0.0-standalone", - &target, - allocator, - self.zig, - self.pgo, - // Profiling requires debug information. - self.enable_profiling, - )?; + dist_server(sh, "0.0.0-standalone", &target, allocator, self.zig, self.pgo, dev_rel)?; } Ok(()) } @@ -100,7 +93,7 @@ fn dist_server( sh: &Shell, release: &str, target: &Target, - allocator: Malloc, + allocator: Allocator, zig: bool, pgo: Option, dev_rel: bool, diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index e72d8f22e4f0..48a316102bc8 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -4,9 +4,47 @@ use std::{fmt, str::FromStr}; use crate::install::{ClientOpt, ProcMacroServerOpt, ServerOpt}; +#[derive(Clone, Copy, Default, Debug)] +pub enum Allocator { + /// Use the system allocator. + #[default] + System, + /// Use the jemalloc allocator. + Jemalloc, + /// Use the mimalloc allocator. + Mimalloc, + /// Use DHAT for memory profiling. This is very slow! + Dhat, +} + +impl Allocator { + pub(crate) fn to_features(self) -> &'static [&'static str] { + match self { + Self::System => &[][..], + Self::Mimalloc => &["--features", "mimalloc"], + Self::Jemalloc => &["--features", "jemalloc"], + Self::Dhat => &["--features", "dhat"], + } + } +} + +impl FromStr for Allocator { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "system" => Ok(Self::System), + "jemalloc" => Ok(Self::Jemalloc), + "mimalloc" => Ok(Self::Mimalloc), + "dhat" => Ok(Self::Dhat), + _ => Err("Invalid option".to_owned()), + } + } +} + #[derive(Debug, Clone)] pub enum PgoTrainingCrate { - // Use RA's own sources for PGO training + // Use RA's own sources for PGO training. RustAnalyzer, // Download a Rust crate from `https://github.com/{0}` and use it for PGO training. GitHub(String), @@ -38,14 +76,8 @@ xflags::xflags! { /// Install only the language server. optional --server - /// Use mimalloc allocator for server. - optional --mimalloc - /// Use jemalloc allocator for server. - optional --jemalloc - // Enable memory profiling support. - // - // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. - optional --enable-profiling + /// Configure the allocator. + optional --allocator allocator: Allocator /// Install the proc-macro server. optional --proc-macro-server @@ -67,14 +99,8 @@ xflags::xflags! { } cmd dist { - /// Use mimalloc allocator for server - optional --mimalloc - /// Use jemalloc allocator for server - optional --jemalloc - // Enable memory profiling support. - // - // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. - optional --enable-profiling + /// Configure the allocator. + optional --allocator allocator: Allocator optional --client-patch-version version: String /// Use cargo-zigbuild optional --zig @@ -131,9 +157,7 @@ pub struct Install { pub client: bool, pub code_bin: Option, pub server: bool, - pub mimalloc: bool, - pub jemalloc: bool, - pub enable_profiling: bool, + pub allocator: Option, pub proc_macro_server: bool, pub dev_rel: bool, pub force_always_assert: bool, @@ -150,9 +174,7 @@ pub struct Release { #[derive(Debug)] pub struct Dist { - pub mimalloc: bool, - pub jemalloc: bool, - pub enable_profiling: bool, + pub allocator: Option, pub client_patch_version: Option, pub zig: bool, pub pgo: Option, @@ -285,43 +307,16 @@ impl AsRef for MeasurementType { } } -#[derive(Clone, Copy, Debug)] -pub(crate) enum Malloc { - System, - Mimalloc, - Jemalloc, - Dhat, -} - -impl Malloc { - pub(crate) fn to_features(self) -> &'static [&'static str] { - match self { - Malloc::System => &[][..], - Malloc::Mimalloc => &["--features", "mimalloc"], - Malloc::Jemalloc => &["--features", "jemalloc"], - Malloc::Dhat => &["--features", "dhat"], - } - } -} - impl Install { pub(crate) fn server(&self) -> Option { if (self.client || self.proc_macro_server) && !self.server { return None; } - let malloc = if self.mimalloc { - Malloc::Mimalloc - } else if self.jemalloc { - Malloc::Jemalloc - } else if self.enable_profiling { - Malloc::Dhat - } else { - Malloc::System - }; + let allocator = self.allocator; Some(ServerOpt { - malloc, + allocator: allocator.unwrap_or_default(), // Profiling requires debug information. - dev_rel: self.dev_rel || self.enable_profiling, + dev_rel: self.dev_rel || matches!(self.allocator, Some(Allocator::Dhat)), pgo: self.pgo.clone(), force_always_assert: self.force_always_assert, }) @@ -339,17 +334,3 @@ impl Install { Some(ClientOpt { code_bin: self.code_bin.clone() }) } } - -impl Dist { - pub(crate) fn allocator(&self) -> Malloc { - if self.mimalloc { - Malloc::Mimalloc - } else if self.jemalloc { - Malloc::Jemalloc - } else if self.enable_profiling { - Malloc::Dhat - } else { - Malloc::System - } - } -} diff --git a/xtask/src/install.rs b/xtask/src/install.rs index a803b4e943a6..6ebb58a53595 100644 --- a/xtask/src/install.rs +++ b/xtask/src/install.rs @@ -6,7 +6,7 @@ use anyhow::{Context, bail, format_err}; use xshell::{Shell, cmd}; use crate::{ - flags::{self, Malloc, PgoTrainingCrate}, + flags::{self, Allocator, PgoTrainingCrate}, util::detect_target, }; @@ -36,7 +36,7 @@ pub(crate) struct ClientOpt { const VS_CODES: &[&str] = &["code", "code-exploration", "code-insiders", "codium", "code-oss"]; pub(crate) struct ServerOpt { - pub(crate) malloc: Malloc, + pub(crate) allocator: Allocator, pub(crate) dev_rel: bool, pub(crate) pgo: Option, pub(crate) force_always_assert: bool, @@ -44,11 +44,11 @@ pub(crate) struct ServerOpt { impl ServerOpt { fn to_features(&self) -> Vec<&'static str> { - let malloc_features = self.malloc.to_features(); + let allocator_features = self.allocator.to_features(); let mut features = Vec::with_capacity( - malloc_features.len() + if self.force_always_assert { 2 } else { 0 }, + allocator_features.len() + if self.force_always_assert { 2 } else { 0 }, ); - features.extend(malloc_features); + features.extend(allocator_features); if self.force_always_assert { features.extend(["--features", "force-always-assert"]); }