Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1From e3a1797dbab3eaa1c808d53215b32c8759d27ac7 Mon Sep 17 00:00:00 2001 2From: Collin Baker <collinbaker@chromium.org> 3Date: Fri, 4 Apr 2025 14:08:18 -0700 4Subject: [PATCH] Reland "Use #[global_allocator] to provide Rust allocator 5 implementation" 6MIME-Version: 1.0 7Content-Type: text/plain; charset=UTF-8 8Content-Transfer-Encoding: 8bit 9 10This is a reland of commit cfa3beef52625e03ba6ce2b2ac98e1b89dde5cdb 11 12Original was reverted due to a cronet gn2bp failure. The script 13filtered out GN rules in //build/rust/std, but this caused an exception 14when //build/rust/std:allocator was referenced later. 15 16Moving the rules to //build/rust/allocator sidesteps the issue. 17 18Original change's description: 19> Use #[global_allocator] to provide Rust allocator implementation 20> 21> The allocator shim hack we have been using no longer works with 22> upstream Rust. Replace it with a less-unsupported method: provide a 23> https://github.com/rust-lang/rust/issues/123015, which still requires 24> us to provide a few symbol definitions. 25> 26> Bug: 408221149, 407024458 27> Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5 28> 29> Cq-Include-Trybots: luci.chromium.try:android-rust-arm32-rel,android-rust-arm64-dbg,android-rust-arm64-rel,linux-rust-x64-dbg,linux-rust-x64-rel,mac-rust-x64-dbg,win-rust-x64-dbg,win-rust-x64-rel 30> Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5 31> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6427855 32> Reviewed-by: Alan Zhao <ayzhao@google.com> 33> Reviewed-by: Lei Zhang <thestig@chromium.org> 34> Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org> 35> Commit-Queue: Collin Baker <collinbaker@chromium.org> 36> Auto-Submit: Collin Baker <collinbaker@chromium.org> 37> Cr-Commit-Position: refs/heads/main@{#1442472} 38 39Bug: 408221149, 407024458 40Cq-Include-Trybots: luci.chromium.try:android-rust-arm32-rel,android-rust-arm64-dbg,android-rust-arm64-rel,linux-rust-x64-dbg,linux-rust-x64-rel,mac-rust-x64-dbg,win-rust-x64-dbg,win-rust-x64-rel 41Change-Id: I36fef217297bfe64ae81519be24b8c653f6fdfa1 42Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6432410 43Reviewed-by: Mohannad Farrag <aymanm@google.com> 44Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org> 45Auto-Submit: Collin Baker <collinbaker@chromium.org> 46Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org> 47Cr-Commit-Position: refs/heads/main@{#1442922} 48--- 49 build/rust/allocator/BUILD.gn | 90 ++++++++++++++++ 50 build/rust/{std => allocator}/alias.cc | 4 +- 51 build/rust/{std => allocator}/alias.h | 6 +- 52 .../allocator_impls.cc} | 100 ++++++++---------- 53 build/rust/allocator/allocator_impls.h | 25 +++++ 54 .../allocator/allocator_shim_definitions.cc | 30 ++++++ 55 .../{std => allocator}/compiler_specific.h | 6 +- 56 .../rust/{std => allocator}/immediate_crash.h | 6 +- 57 build/rust/allocator/lib.rs | 48 +++++++++ 58 build/rust/cargo_crate.gni | 9 ++ 59 build/rust/rust_macro.gni | 3 + 60 build/rust/rust_target.gni | 4 + 61 build/rust/std/BUILD.gn | 41 ------- 62 components/cronet/android/dependencies.txt | 1 + 63 third_party/breakpad/BUILD.gn | 10 +- 64 15 files changed, 272 insertions(+), 111 deletions(-) 65 create mode 100644 build/rust/allocator/BUILD.gn 66 rename build/rust/{std => allocator}/alias.cc (87%) 67 rename build/rust/{std => allocator}/alias.h (91%) 68 rename build/rust/{std/remap_alloc.cc => allocator/allocator_impls.cc} (67%) 69 create mode 100644 build/rust/allocator/allocator_impls.h 70 create mode 100644 build/rust/allocator/allocator_shim_definitions.cc 71 rename build/rust/{std => allocator}/compiler_specific.h (87%) 72 rename build/rust/{std => allocator}/immediate_crash.h (97%) 73 create mode 100644 build/rust/allocator/lib.rs 74 75diff --git a/build/rust/allocator/BUILD.gn b/build/rust/allocator/BUILD.gn 76new file mode 100644 77index 00000000000000..06aa47f097c9c4 78--- /dev/null 79+++ b/build/rust/allocator/BUILD.gn 80@@ -0,0 +1,90 @@ 81+# Copyright 2025 The Chromium Authors 82+# Use of this source code is governed by a BSD-style license that can be 83+# found in the LICENSE file. 84+ 85+import("//build/buildflag_header.gni") 86+import("//build/config/rust.gni") 87+import("//build/rust/rust_static_library.gni") 88+ 89+rust_allocator_uses_partition_alloc = false 90+if (build_with_chromium) { 91+ import("//base/allocator/partition_allocator/partition_alloc.gni") 92+ rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc 93+} 94+ 95+buildflag_header("buildflags") { 96+ header = "buildflags.h" 97+ flags = [ 98+ "RUST_ALLOCATOR_USES_PARTITION_ALLOC=$rust_allocator_uses_partition_alloc", 99+ ] 100+ visibility = [ ":*" ] 101+} 102+ 103+if (toolchain_has_rust) { 104+ # All targets which depend on Rust code but are not linked by rustc must 105+ # depend on this. Usually, this dependency will come from the rust_target() GN 106+ # template. However, cargo_crate() does *not* include this dependency so any 107+ # C++ targets which directly depend on a cargo_crate() must depend on this. 108+ rust_static_library("allocator") { 109+ sources = [ "lib.rs" ] 110+ crate_root = "lib.rs" 111+ cxx_bindings = [ "lib.rs" ] 112+ 113+ deps = [ 114+ ":allocator_impls", 115+ ":allocator_shim_definitions", 116+ ] 117+ 118+ no_chromium_prelude = true 119+ no_allocator_crate = true 120+ allow_unsafe = true 121+ } 122+ 123+ static_library("allocator_impls") { 124+ public_deps = [] 125+ if (rust_allocator_uses_partition_alloc) { 126+ public_deps += [ "//base/allocator/partition_allocator:partition_alloc" ] 127+ } 128+ 129+ sources = [ 130+ "allocator_impls.cc", 131+ "allocator_impls.h", 132+ ] 133+ 134+ deps = [ 135+ ":allocator_cpp_shared", 136+ ":buildflags", 137+ 138+ # TODO(crbug.com/408221149): remove the C++ -> Rust dependency for the 139+ # default allocator. 140+ "//build/rust/std", 141+ ] 142+ 143+ visibility = [ ":*" ] 144+ } 145+ 146+ source_set("allocator_shim_definitions") { 147+ sources = [ "allocator_shim_definitions.cc" ] 148+ 149+ deps = [ ":allocator_cpp_shared" ] 150+ 151+ visibility = [ ":*" ] 152+ } 153+ 154+ source_set("allocator_cpp_shared") { 155+ sources = [ 156+ # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been 157+ # copied from `//base`. 158+ # TODO(crbug.com/40279749): Avoid duplication / reuse code. 159+ "alias.cc", 160+ "alias.h", 161+ "compiler_specific.h", 162+ "immediate_crash.h", 163+ ] 164+ 165+ visibility = [ 166+ ":allocator_impls", 167+ ":allocator_shim_definitions", 168+ ] 169+ } 170+} 171diff --git a/build/rust/std/alias.cc b/build/rust/allocator/alias.cc 172similarity index 87% 173rename from build/rust/std/alias.cc 174rename to build/rust/allocator/alias.cc 175index 42febac3ed1fc5..ca20986f8ed496 100644 176--- a/build/rust/std/alias.cc 177+++ b/build/rust/allocator/alias.cc 178@@ -7,9 +7,9 @@ 179 // 180 // TODO(crbug.com/40279749): Avoid code duplication / reuse code. 181 182-#include "build/rust/std/alias.h" 183+#include "build/rust/allocator/alias.h" 184 185-#include "build/rust/std/compiler_specific.h" 186+#include "build/rust/allocator/compiler_specific.h" 187 188 namespace build_rust_std { 189 namespace debug { 190diff --git a/build/rust/std/alias.h b/build/rust/allocator/alias.h 191similarity index 91% 192rename from build/rust/std/alias.h 193rename to build/rust/allocator/alias.h 194index 0eaba6766148fa..80995ecfb045e3 100644 195--- a/build/rust/std/alias.h 196+++ b/build/rust/allocator/alias.h 197@@ -8,8 +8,8 @@ 198 // 199 // TODO(crbug.com/40279749): Avoid code duplication / reuse code. 200 201-#ifndef BUILD_RUST_STD_ALIAS_H_ 202-#define BUILD_RUST_STD_ALIAS_H_ 203+#ifndef BUILD_RUST_ALLOCATOR_ALIAS_H_ 204+#define BUILD_RUST_ALLOCATOR_ALIAS_H_ 205 206 #include <stddef.h> 207 208@@ -34,4 +34,4 @@ void Alias(const void* var); 209 const int line_number = __LINE__; \ 210 build_rust_std::debug::Alias(&line_number) 211 212-#endif // BUILD_RUST_STD_ALIAS_H_ 213+#endif // BUILD_RUST_ALLOCATOR_ALIAS_H_ 214diff --git a/build/rust/std/remap_alloc.cc b/build/rust/allocator/allocator_impls.cc 215similarity index 67% 216rename from build/rust/std/remap_alloc.cc 217rename to build/rust/allocator/allocator_impls.cc 218index a443b11ec513df..1fde98f23cd124 100644 219--- a/build/rust/std/remap_alloc.cc 220+++ b/build/rust/allocator/allocator_impls.cc 221@@ -2,6 +2,8 @@ 222 // Use of this source code is governed by a BSD-style license that can be 223 // found in the LICENSE file. 224 225+#include "build/rust/allocator/allocator_impls.h" 226+ 227 #ifdef UNSAFE_BUFFERS_BUILD 228 // TODO(crbug.com/390223051): Remove C-library calls to fix the errors. 229 #pragma allow_unsafe_libc_calls 230@@ -11,9 +13,9 @@ 231 #include <cstring> 232 233 #include "build/build_config.h" 234-#include "build/rust/std/alias.h" 235-#include "build/rust/std/buildflags.h" 236-#include "build/rust/std/immediate_crash.h" 237+#include "build/rust/allocator/alias.h" 238+#include "build/rust/allocator/buildflags.h" 239+#include "build/rust/allocator/immediate_crash.h" 240 241 #if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) 242 #include "partition_alloc/partition_alloc_constants.h" // nogncheck 243@@ -22,6 +24,11 @@ 244 #include <cstdlib> 245 #endif 246 247+// NOTE: this documentation is outdated. 248+// 249+// TODO(crbug.com/408221149): update this documentation, or replace it with docs 250+// in the Rust allocator implementation. 251+// 252 // When linking a final binary, rustc has to pick between either: 253 // * The default Rust allocator 254 // * Any #[global_allocator] defined in *any rlib in its dependency tree* 255@@ -87,19 +94,6 @@ 256 // enabling it breaks Win32 APIs like CreateProcess: 257 // https://issues.chromium.org/u/1/issues/368070343#comment29 258 259-extern "C" { 260- 261-#ifdef COMPONENT_BUILD 262-#if BUILDFLAG(IS_WIN) 263-#define REMAP_ALLOC_ATTRIBUTES __declspec(dllexport) __attribute__((weak)) 264-#else 265-#define REMAP_ALLOC_ATTRIBUTES \ 266- __attribute__((visibility("default"))) __attribute__((weak)) 267-#endif 268-#else 269-#define REMAP_ALLOC_ATTRIBUTES __attribute__((weak)) 270-#endif // COMPONENT_BUILD 271- 272 #if !BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) && BUILDFLAG(IS_WIN) && \ 273 defined(ADDRESS_SANITIZER) 274 #define USE_WIN_ALIGNED_MALLOC 1 275@@ -107,17 +101,19 @@ extern "C" { 276 #define USE_WIN_ALIGNED_MALLOC 0 277 #endif 278 279-// This must exist as the stdlib depends on it to prove that we know the 280-// alloc shims below are unstable. In the future we may be required to replace 281-// them with a #[global_allocator] crate (see file comment above for more). 282-// 283-// Marked as weak as when Rust drives linking it includes this symbol itself, 284-// and we don't want a collision due to C++ being in the same link target, where 285-// C++ causes us to explicitly link in the stdlib and this symbol here. 286-[[maybe_unused]] 287-__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable; 288+// The default allocator functions provided by the Rust standard library. 289+extern "C" void* __rdl_alloc(size_t size, size_t align); 290+extern "C" void __rdl_dealloc(void* p, size_t size, size_t align); 291+extern "C" void* __rdl_realloc(void* p, 292+ size_t old_size, 293+ size_t align, 294+ size_t new_size); 295+ 296+extern "C" void* __rdl_alloc_zeroed(size_t size, size_t align); 297+ 298+namespace rust_allocator_internal { 299 300-REMAP_ALLOC_ATTRIBUTES void* __rust_alloc(size_t size, size_t align) { 301+unsigned char* alloc(size_t size, size_t align) { 302 #if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) 303 // PartitionAlloc will crash if given an alignment larger than this. 304 if (align > partition_alloc::internal::kMaxSupportedAlignment) { 305@@ -125,19 +121,19 @@ REMAP_ALLOC_ATTRIBUTES void* __rust_alloc(size_t size, size_t align) { 306 } 307 308 if (align <= alignof(std::max_align_t)) { 309- return allocator_shim::UncheckedAlloc(size); 310+ return static_cast<unsigned char*>(allocator_shim::UncheckedAlloc(size)); 311 } else { 312- return allocator_shim::UncheckedAlignedAlloc(size, align); 313+ return static_cast<unsigned char*>( 314+ allocator_shim::UncheckedAlignedAlloc(size, align)); 315 } 316 #elif USE_WIN_ALIGNED_MALLOC 317- return _aligned_malloc(size, align); 318+ return static_cast<unsigned char*>(_aligned_malloc(size, align)); 319 #else 320- extern void* __rdl_alloc(size_t size, size_t align); 321- return __rdl_alloc(size, align); 322+ return static_cast<unsigned char*>(__rdl_alloc(size, align)); 323 #endif 324 } 325 326-REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) { 327+void dealloc(unsigned char* p, size_t size, size_t align) { 328 #if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) 329 if (align <= alignof(std::max_align_t)) { 330 allocator_shim::UncheckedFree(p); 331@@ -147,54 +143,44 @@ REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) { 332 #elif USE_WIN_ALIGNED_MALLOC 333 return _aligned_free(p); 334 #else 335- extern void __rdl_dealloc(void* p, size_t size, size_t align); 336 __rdl_dealloc(p, size, align); 337 #endif 338 } 339 340-REMAP_ALLOC_ATTRIBUTES void* __rust_realloc(void* p, 341- size_t old_size, 342- size_t align, 343- size_t new_size) { 344+unsigned char* realloc(unsigned char* p, 345+ size_t old_size, 346+ size_t align, 347+ size_t new_size) { 348 #if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) 349 if (align <= alignof(std::max_align_t)) { 350- return allocator_shim::UncheckedRealloc(p, new_size); 351+ return static_cast<unsigned char*>( 352+ allocator_shim::UncheckedRealloc(p, new_size)); 353 } else { 354- return allocator_shim::UncheckedAlignedRealloc(p, new_size, align); 355+ return static_cast<unsigned char*>( 356+ allocator_shim::UncheckedAlignedRealloc(p, new_size, align)); 357 } 358 #elif USE_WIN_ALIGNED_MALLOC 359- return _aligned_realloc(p, new_size, align); 360+ return static_cast<unsigned char*>(_aligned_realloc(p, new_size, align)); 361 #else 362- extern void* __rdl_realloc(void* p, size_t old_size, size_t align, 363- size_t new_size); 364- return __rdl_realloc(p, old_size, align, new_size); 365+ return static_cast<unsigned char*>( 366+ __rdl_realloc(p, old_size, align, new_size)); 367 #endif 368 } 369 370-REMAP_ALLOC_ATTRIBUTES void* __rust_alloc_zeroed(size_t size, size_t align) { 371+unsigned char* alloc_zeroed(size_t size, size_t align) { 372 #if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) || USE_WIN_ALIGNED_MALLOC 373 // TODO(danakj): When RUST_ALLOCATOR_USES_PARTITION_ALLOC is true, it's 374 // possible that a partition_alloc::UncheckedAllocZeroed() call would perform 375 // better than partition_alloc::UncheckedAlloc() + memset. But there is no 376 // such API today. See b/342251590. 377- void* p = __rust_alloc(size, align); 378+ unsigned char* p = alloc(size, align); 379 if (p) { 380 memset(p, 0, size); 381 } 382 return p; 383 #else 384- extern void* __rdl_alloc_zeroed(size_t size, size_t align); 385- return __rdl_alloc_zeroed(size, align); 386+ return static_cast<unsigned char*>(__rdl_alloc_zeroed(size, align)); 387 #endif 388 } 389 390-REMAP_ALLOC_ATTRIBUTES void __rust_alloc_error_handler(size_t size, 391- size_t align) { 392- NO_CODE_FOLDING(); 393- IMMEDIATE_CRASH(); 394-} 395- 396-REMAP_ALLOC_ATTRIBUTES extern const unsigned char 397- __rust_alloc_error_handler_should_panic = 0; 398- 399-} // extern "C" 400+} // namespace rust_allocator_internal 401diff --git a/build/rust/allocator/allocator_impls.h b/build/rust/allocator/allocator_impls.h 402new file mode 100644 403index 00000000000000..afb335412faf9c 404--- /dev/null 405+++ b/build/rust/allocator/allocator_impls.h 406@@ -0,0 +1,25 @@ 407+// Copyright 2025 The Chromium Authors 408+// Use of this source code is governed by a BSD-style license that can be 409+// found in the LICENSE file. 410+ 411+#ifndef BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_ 412+#define BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_ 413+ 414+#include <cstddef> 415+ 416+#include "build/build_config.h" 417+#include "build/rust/allocator/buildflags.h" 418+ 419+namespace rust_allocator_internal { 420+ 421+unsigned char* alloc(size_t size, size_t align); 422+void dealloc(unsigned char* p, size_t size, size_t align); 423+unsigned char* realloc(unsigned char* p, 424+ size_t old_size, 425+ size_t align, 426+ size_t new_size); 427+unsigned char* alloc_zeroed(size_t size, size_t align); 428+ 429+} // namespace rust_allocator_internal 430+ 431+#endif // BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_ 432diff --git a/build/rust/allocator/allocator_shim_definitions.cc b/build/rust/allocator/allocator_shim_definitions.cc 433new file mode 100644 434index 00000000000000..a4d1bd77b7016e 435--- /dev/null 436+++ b/build/rust/allocator/allocator_shim_definitions.cc 437@@ -0,0 +1,30 @@ 438+// Copyright 2025 The Chromium Authors 439+// Use of this source code is governed by a BSD-style license that can be 440+// found in the LICENSE file. 441+ 442+#include <cstddef> 443+ 444+#include "build/rust/allocator/alias.h" 445+#include "build/rust/allocator/immediate_crash.h" 446+ 447+extern "C" { 448+ 449+// As part of rustc's contract for using `#[global_allocator]` without 450+// rustc-generated shims we must define this symbol, since we are opting in to 451+// unstable functionality. See https://github.com/rust-lang/rust/issues/123015 452+// 453+// Mark it weak since rustc will generate it when it drives linking. 454+[[maybe_unused]] 455+__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable; 456+ 457+__attribute__((weak)) void __rust_alloc_error_handler(size_t size, 458+ size_t align) { 459+ NO_CODE_FOLDING(); 460+ IMMEDIATE_CRASH(); 461+} 462+ 463+__attribute__(( 464+ weak)) extern const unsigned char __rust_alloc_error_handler_should_panic = 465+ 0; 466+ 467+} // extern "C" 468diff --git a/build/rust/std/compiler_specific.h b/build/rust/allocator/compiler_specific.h 469similarity index 87% 470rename from build/rust/std/compiler_specific.h 471rename to build/rust/allocator/compiler_specific.h 472index ea79a7a8dc2842..f9079679a3e9af 100644 473--- a/build/rust/std/compiler_specific.h 474+++ b/build/rust/allocator/compiler_specific.h 475@@ -7,8 +7,8 @@ 476 // 477 // TODO(crbug.com/40279749): Avoid code duplication / reuse code. 478 479-#ifndef BUILD_RUST_STD_COMPILER_SPECIFIC_H_ 480-#define BUILD_RUST_STD_COMPILER_SPECIFIC_H_ 481+#ifndef BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_ 482+#define BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_ 483 484 #include "build/build_config.h" 485 486@@ -35,4 +35,4 @@ 487 #define NOINLINE 488 #endif 489 490-#endif // BUILD_RUST_STD_COMPILER_SPECIFIC_H_ 491+#endif // BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_ 492diff --git a/build/rust/std/immediate_crash.h b/build/rust/allocator/immediate_crash.h 493similarity index 97% 494rename from build/rust/std/immediate_crash.h 495rename to build/rust/allocator/immediate_crash.h 496index e4fd5a09d9379f..9cbf9fd65f3e09 100644 497--- a/build/rust/std/immediate_crash.h 498+++ b/build/rust/allocator/immediate_crash.h 499@@ -5,8 +5,8 @@ 500 // This file has been copied from //base/immediate_crash.h. 501 // TODO(crbug.com/40279749): Avoid code duplication / reuse code. 502 503-#ifndef BUILD_RUST_STD_IMMEDIATE_CRASH_H_ 504-#define BUILD_RUST_STD_IMMEDIATE_CRASH_H_ 505+#ifndef BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_ 506+#define BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_ 507 508 #include "build/build_config.h" 509 510@@ -168,4 +168,4 @@ 511 512 #endif // defined(__clang__) || defined(COMPILER_GCC) 513 514-#endif // BUILD_RUST_STD_IMMEDIATE_CRASH_H_ 515+#endif // BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_ 516diff --git a/build/rust/allocator/lib.rs b/build/rust/allocator/lib.rs 517new file mode 100644 518index 00000000000000..7f4a0fc2456942 519--- /dev/null 520+++ b/build/rust/allocator/lib.rs 521@@ -0,0 +1,48 @@ 522+// Copyright 2025 The Chromium Authors 523+// Use of this source code is governed by a BSD-style license that can be 524+// found in the LICENSE file. 525+ 526+//! Define the allocator that Rust code in Chrome should use. 527+//! 528+//! Any final artifact that depends on this crate, even transitively, will use 529+//! the allocator defined here. Currently this is a thin wrapper around 530+//! allocator_impls.cc's functions; see the documentation there. 531+ 532+use std::alloc::{GlobalAlloc, Layout}; 533+ 534+struct Allocator; 535+ 536+unsafe impl GlobalAlloc for Allocator { 537+ unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 538+ unsafe { ffi::alloc(layout.size(), layout.align()) } 539+ } 540+ 541+ unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { 542+ unsafe { 543+ ffi::dealloc(ptr, layout.size(), layout.align()); 544+ } 545+ } 546+ 547+ unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 548+ unsafe { ffi::alloc_zeroed(layout.size(), layout.align()) } 549+ } 550+ 551+ unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { 552+ unsafe { ffi::realloc(ptr, layout.size(), layout.align(), new_size) } 553+ } 554+} 555+ 556+#[global_allocator] 557+static GLOBAL: Allocator = Allocator; 558+ 559+#[cxx::bridge(namespace = "rust_allocator_internal")] 560+mod ffi { 561+ extern "C++" { 562+ include!("build/rust/allocator/allocator_impls.h"); 563+ 564+ unsafe fn alloc(size: usize, align: usize) -> *mut u8; 565+ unsafe fn dealloc(p: *mut u8, size: usize, align: usize); 566+ unsafe fn realloc(p: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; 567+ unsafe fn alloc_zeroed(size: usize, align: usize) -> *mut u8; 568+ } 569+} 570diff --git a/build/rust/cargo_crate.gni b/build/rust/cargo_crate.gni 571index 6d11c538bf4d5a..d9912722b4ecdb 100644 572--- a/build/rust/cargo_crate.gni 573+++ b/build/rust/cargo_crate.gni 574@@ -259,6 +259,12 @@ template("cargo_crate") { 575 # Don't import the `chromium` crate into third-party code. 576 no_chromium_prelude = true 577 578+ # Don't depend on the chrome-specific #[global_allocator] crate from 579+ # third-party code. This avoids some dependency cycle issues. The allocator 580+ # crate will still be used if it exists anywhere in the dependency graph for 581+ # a given linked artifact. 582+ no_allocator_crate = true 583+ 584 rustc_metadata = _rustc_metadata 585 586 # TODO(crbug.com/40259764): don't default to true. This requires changes to 587@@ -483,6 +489,9 @@ template("cargo_crate") { 588 # Don't import the `chromium` crate into third-party code. 589 no_chromium_prelude = true 590 591+ # Build scripts do not need to link to chrome's allocator. 592+ no_allocator_crate = true 593+ 594 # The ${_build_script_name}_output target looks for the exe in this 595 # location. Due to how the Windows component build works, this has to 596 # be $root_out_dir for all EXEs. In component build, C++ links to the 597diff --git a/build/rust/rust_macro.gni b/build/rust/rust_macro.gni 598index bcbb30ed441115..41d857632ccdc9 100644 599--- a/build/rust/rust_macro.gni 600+++ b/build/rust/rust_macro.gni 601@@ -16,6 +16,9 @@ template("rust_macro") { 602 forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 603 proc_macro_configs = invoker.configs 604 target_type = "rust_proc_macro" 605+ 606+ # Macros are loaded by rustc and shouldn't use chrome's allocation routines. 607+ no_allocator_crate = true 608 } 609 } 610 611diff --git a/build/rust/rust_target.gni b/build/rust/rust_target.gni 612index 1a2f96337d4361..1003a7b678352d 100644 613--- a/build/rust/rust_target.gni 614+++ b/build/rust/rust_target.gni 615@@ -339,6 +339,10 @@ template("rust_target") { 616 _rust_deps += [ "//build/rust/std" ] 617 } 618 619+ if (!defined(invoker.no_allocator_crate) || !invoker.no_allocator_crate) { 620+ _rust_deps += [ "//build/rust/allocator" ] 621+ } 622+ 623 if (_build_unit_tests) { 624 _unit_test_target = "${_target_name}_unittests" 625 if (defined(invoker.unit_test_target)) { 626diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn 627index 6b996aa1fe3865..25db126076b2fa 100644 628--- a/build/rust/std/BUILD.gn 629+++ b/build/rust/std/BUILD.gn 630@@ -15,51 +15,12 @@ 631 # allocator functions to PartitionAlloc when `use_partition_alloc_as_malloc` is 632 # true, so that Rust and C++ use the same allocator backend. 633 634-import("//build/buildflag_header.gni") 635 import("//build/config/compiler/compiler.gni") 636 import("//build/config/coverage/coverage.gni") 637 import("//build/config/rust.gni") 638 import("//build/config/sanitizers/sanitizers.gni") 639 640-rust_allocator_uses_partition_alloc = false 641-if (build_with_chromium) { 642- import("//base/allocator/partition_allocator/partition_alloc.gni") 643- rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc 644-} 645- 646-buildflag_header("buildflags") { 647- header = "buildflags.h" 648- flags = [ 649- "RUST_ALLOCATOR_USES_PARTITION_ALLOC=$rust_allocator_uses_partition_alloc", 650- ] 651- visibility = [ ":*" ] 652-} 653- 654 if (toolchain_has_rust) { 655- # If clang performs the link step, we need to provide the allocator symbols 656- # that are normally injected by rustc during linking. 657- # 658- # We also "happen to" use this to redirect allocations to PartitionAlloc, 659- # though that would be better done through a #[global_allocator] crate (see 660- # above). 661- source_set("remap_alloc") { 662- public_deps = [] 663- if (rust_allocator_uses_partition_alloc) { 664- public_deps += [ "//base/allocator/partition_allocator:partition_alloc" ] 665- } 666- deps = [ ":buildflags" ] 667- sources = [ 668- # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been 669- # copied from `//base`. 670- # TODO(crbug.com/40279749): Avoid duplication / reuse code. 671- "alias.cc", 672- "alias.h", 673- "compiler_specific.h", 674- "immediate_crash.h", 675- "remap_alloc.cc", 676- ] 677- } 678- 679 # List of Rust stdlib rlibs which are present in the official Rust toolchain 680 # we are using from the Android team. This is usually a version or two behind 681 # nightly. Generally this matches the toolchain we build ourselves, but if 682@@ -269,8 +230,6 @@ if (toolchain_has_rust) { 683 foreach(libname, stdlib_files + skip_stdlib_files) { 684 deps += [ "rules:$libname" ] 685 } 686- 687- public_deps = [ ":remap_alloc" ] 688 } 689 } else { 690 action("find_stdlib") { 691diff --git a/components/cronet/android/dependencies.txt b/components/cronet/android/dependencies.txt 692index bf56bc45ed41f7..c0e41ef7c6766a 100644 693--- a/components/cronet/android/dependencies.txt 694+++ b/components/cronet/android/dependencies.txt 695@@ -14,6 +14,7 @@ 696 //build/config 697 //build/config/compiler 698 //build/rust 699+//build/rust/allocator 700 //build/rust/chromium_prelude 701 //build/rust/std 702 //build/rust/std/rules 703diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn 704index 2f4e1ab0156609..e140ecbedcc9a0 100644 705--- a/third_party/breakpad/BUILD.gn 706+++ b/third_party/breakpad/BUILD.gn 707@@ -495,7 +495,10 @@ if (is_mac) { 708 defines = [ "HAVE_MACH_O_NLIST_H" ] 709 710 # Rust demangle support. 711- deps = [ "//third_party/rust/rustc_demangle_capi/v0_1:lib" ] 712+ deps = [ 713+ "//build/rust/allocator", 714+ "//third_party/rust/rustc_demangle_capi/v0_1:lib", 715+ ] 716 defines += [ "HAVE_RUSTC_DEMANGLE" ] 717 include_dirs += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include" ] 718 sources += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include/rustc_demangle.h" ] 719@@ -743,7 +746,10 @@ if (is_linux || is_chromeos || is_android) { 720 include_dirs = [ "breakpad/src" ] 721 722 # Rust demangle support. 723- deps = [ "//third_party/rust/rustc_demangle_capi/v0_1:lib" ] 724+ deps = [ 725+ "//build/rust/allocator", 726+ "//third_party/rust/rustc_demangle_capi/v0_1:lib", 727+ ] 728 defines += [ "HAVE_RUSTC_DEMANGLE" ] 729 include_dirs += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include" ] 730 sources += [ "//third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/include/rustc_demangle.h" ]