Skip to content

Commit e3a1797

Browse files
chbaker0Chromium LUCI CQ
authored and
Chromium LUCI CQ
committed
Reland "Use #[global_allocator] to provide Rust allocator implementation"
This is a reland of commit cfa3bee Original was reverted due to a cronet gn2bp failure. The script filtered out GN rules in //build/rust/std, but this caused an exception when //build/rust/std:allocator was referenced later. Moving the rules to //build/rust/allocator sidesteps the issue. Original change's description: > Use #[global_allocator] to provide Rust allocator implementation > > The allocator shim hack we have been using no longer works with > upstream Rust. Replace it with a less-unsupported method: provide a > rust-lang/rust#123015, which still requires > us to provide a few symbol definitions. > > Bug: 408221149, 407024458 > Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5 > > 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 > Change-Id: If1808ca24b12dc80ead35a25521313a3d2e148d5 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6427855 > Reviewed-by: Alan Zhao <[email protected]> > Reviewed-by: Lei Zhang <[email protected]> > Reviewed-by: Łukasz Anforowicz <[email protected]> > Commit-Queue: Collin Baker <[email protected]> > Auto-Submit: Collin Baker <[email protected]> > Cr-Commit-Position: refs/heads/main@{#1442472} Bug: 408221149, 407024458 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 Change-Id: I36fef217297bfe64ae81519be24b8c653f6fdfa1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6432410 Reviewed-by: Mohannad Farrag <[email protected]> Reviewed-by: Łukasz Anforowicz <[email protected]> Auto-Submit: Collin Baker <[email protected]> Commit-Queue: Łukasz Anforowicz <[email protected]> Cr-Commit-Position: refs/heads/main@{#1442922}
1 parent ae04e2a commit e3a1797

15 files changed

+272
-111
lines changed

build/rust/allocator/BUILD.gn

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright 2025 The Chromium Authors
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file.
4+
5+
import("//build/buildflag_header.gni")
6+
import("//build/config/rust.gni")
7+
import("//build/rust/rust_static_library.gni")
8+
9+
rust_allocator_uses_partition_alloc = false
10+
if (build_with_chromium) {
11+
import("//base/allocator/partition_allocator/partition_alloc.gni")
12+
rust_allocator_uses_partition_alloc = use_partition_alloc_as_malloc
13+
}
14+
15+
buildflag_header("buildflags") {
16+
header = "buildflags.h"
17+
flags = [
18+
"RUST_ALLOCATOR_USES_PARTITION_ALLOC=$rust_allocator_uses_partition_alloc",
19+
]
20+
visibility = [ ":*" ]
21+
}
22+
23+
if (toolchain_has_rust) {
24+
# All targets which depend on Rust code but are not linked by rustc must
25+
# depend on this. Usually, this dependency will come from the rust_target() GN
26+
# template. However, cargo_crate() does *not* include this dependency so any
27+
# C++ targets which directly depend on a cargo_crate() must depend on this.
28+
rust_static_library("allocator") {
29+
sources = [ "lib.rs" ]
30+
crate_root = "lib.rs"
31+
cxx_bindings = [ "lib.rs" ]
32+
33+
deps = [
34+
":allocator_impls",
35+
":allocator_shim_definitions",
36+
]
37+
38+
no_chromium_prelude = true
39+
no_allocator_crate = true
40+
allow_unsafe = true
41+
}
42+
43+
static_library("allocator_impls") {
44+
public_deps = []
45+
if (rust_allocator_uses_partition_alloc) {
46+
public_deps += [ "//base/allocator/partition_allocator:partition_alloc" ]
47+
}
48+
49+
sources = [
50+
"allocator_impls.cc",
51+
"allocator_impls.h",
52+
]
53+
54+
deps = [
55+
":allocator_cpp_shared",
56+
":buildflags",
57+
58+
# TODO(crbug.com/408221149): remove the C++ -> Rust dependency for the
59+
# default allocator.
60+
"//build/rust/std",
61+
]
62+
63+
visibility = [ ":*" ]
64+
}
65+
66+
source_set("allocator_shim_definitions") {
67+
sources = [ "allocator_shim_definitions.cc" ]
68+
69+
deps = [ ":allocator_cpp_shared" ]
70+
71+
visibility = [ ":*" ]
72+
}
73+
74+
source_set("allocator_cpp_shared") {
75+
sources = [
76+
# `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been
77+
# copied from `//base`.
78+
# TODO(crbug.com/40279749): Avoid duplication / reuse code.
79+
"alias.cc",
80+
"alias.h",
81+
"compiler_specific.h",
82+
"immediate_crash.h",
83+
]
84+
85+
visibility = [
86+
":allocator_impls",
87+
":allocator_shim_definitions",
88+
]
89+
}
90+
}

build/rust/std/alias.cc renamed to build/rust/allocator/alias.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
//
88
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
99

10-
#include "build/rust/std/alias.h"
10+
#include "build/rust/allocator/alias.h"
1111

12-
#include "build/rust/std/compiler_specific.h"
12+
#include "build/rust/allocator/compiler_specific.h"
1313

1414
namespace build_rust_std {
1515
namespace debug {

build/rust/std/alias.h renamed to build/rust/allocator/alias.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
//
99
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
1010

11-
#ifndef BUILD_RUST_STD_ALIAS_H_
12-
#define BUILD_RUST_STD_ALIAS_H_
11+
#ifndef BUILD_RUST_ALLOCATOR_ALIAS_H_
12+
#define BUILD_RUST_ALLOCATOR_ALIAS_H_
1313

1414
#include <stddef.h>
1515

@@ -34,4 +34,4 @@ void Alias(const void* var);
3434
const int line_number = __LINE__; \
3535
build_rust_std::debug::Alias(&line_number)
3636

37-
#endif // BUILD_RUST_STD_ALIAS_H_
37+
#endif // BUILD_RUST_ALLOCATOR_ALIAS_H_

build/rust/std/remap_alloc.cc renamed to build/rust/allocator/allocator_impls.cc

+43-57
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#include "build/rust/allocator/allocator_impls.h"
6+
57
#ifdef UNSAFE_BUFFERS_BUILD
68
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
79
#pragma allow_unsafe_libc_calls
@@ -11,9 +13,9 @@
1113
#include <cstring>
1214

1315
#include "build/build_config.h"
14-
#include "build/rust/std/alias.h"
15-
#include "build/rust/std/buildflags.h"
16-
#include "build/rust/std/immediate_crash.h"
16+
#include "build/rust/allocator/alias.h"
17+
#include "build/rust/allocator/buildflags.h"
18+
#include "build/rust/allocator/immediate_crash.h"
1719

1820
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
1921
#include "partition_alloc/partition_alloc_constants.h" // nogncheck
@@ -22,6 +24,11 @@
2224
#include <cstdlib>
2325
#endif
2426

27+
// NOTE: this documentation is outdated.
28+
//
29+
// TODO(crbug.com/408221149): update this documentation, or replace it with docs
30+
// in the Rust allocator implementation.
31+
//
2532
// When linking a final binary, rustc has to pick between either:
2633
// * The default Rust allocator
2734
// * Any #[global_allocator] defined in *any rlib in its dependency tree*
@@ -87,57 +94,46 @@
8794
// enabling it breaks Win32 APIs like CreateProcess:
8895
// https://issues.chromium.org/u/1/issues/368070343#comment29
8996

90-
extern "C" {
91-
92-
#ifdef COMPONENT_BUILD
93-
#if BUILDFLAG(IS_WIN)
94-
#define REMAP_ALLOC_ATTRIBUTES __declspec(dllexport) __attribute__((weak))
95-
#else
96-
#define REMAP_ALLOC_ATTRIBUTES \
97-
__attribute__((visibility("default"))) __attribute__((weak))
98-
#endif
99-
#else
100-
#define REMAP_ALLOC_ATTRIBUTES __attribute__((weak))
101-
#endif // COMPONENT_BUILD
102-
10397
#if !BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) && BUILDFLAG(IS_WIN) && \
10498
defined(ADDRESS_SANITIZER)
10599
#define USE_WIN_ALIGNED_MALLOC 1
106100
#else
107101
#define USE_WIN_ALIGNED_MALLOC 0
108102
#endif
109103

110-
// This must exist as the stdlib depends on it to prove that we know the
111-
// alloc shims below are unstable. In the future we may be required to replace
112-
// them with a #[global_allocator] crate (see file comment above for more).
113-
//
114-
// Marked as weak as when Rust drives linking it includes this symbol itself,
115-
// and we don't want a collision due to C++ being in the same link target, where
116-
// C++ causes us to explicitly link in the stdlib and this symbol here.
117-
[[maybe_unused]]
118-
__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable;
104+
// The default allocator functions provided by the Rust standard library.
105+
extern "C" void* __rdl_alloc(size_t size, size_t align);
106+
extern "C" void __rdl_dealloc(void* p, size_t size, size_t align);
107+
extern "C" void* __rdl_realloc(void* p,
108+
size_t old_size,
109+
size_t align,
110+
size_t new_size);
111+
112+
extern "C" void* __rdl_alloc_zeroed(size_t size, size_t align);
113+
114+
namespace rust_allocator_internal {
119115

120-
REMAP_ALLOC_ATTRIBUTES void* __rust_alloc(size_t size, size_t align) {
116+
unsigned char* alloc(size_t size, size_t align) {
121117
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
122118
// PartitionAlloc will crash if given an alignment larger than this.
123119
if (align > partition_alloc::internal::kMaxSupportedAlignment) {
124120
return nullptr;
125121
}
126122

127123
if (align <= alignof(std::max_align_t)) {
128-
return allocator_shim::UncheckedAlloc(size);
124+
return static_cast<unsigned char*>(allocator_shim::UncheckedAlloc(size));
129125
} else {
130-
return allocator_shim::UncheckedAlignedAlloc(size, align);
126+
return static_cast<unsigned char*>(
127+
allocator_shim::UncheckedAlignedAlloc(size, align));
131128
}
132129
#elif USE_WIN_ALIGNED_MALLOC
133-
return _aligned_malloc(size, align);
130+
return static_cast<unsigned char*>(_aligned_malloc(size, align));
134131
#else
135-
extern void* __rdl_alloc(size_t size, size_t align);
136-
return __rdl_alloc(size, align);
132+
return static_cast<unsigned char*>(__rdl_alloc(size, align));
137133
#endif
138134
}
139135

140-
REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) {
136+
void dealloc(unsigned char* p, size_t size, size_t align) {
141137
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
142138
if (align <= alignof(std::max_align_t)) {
143139
allocator_shim::UncheckedFree(p);
@@ -147,54 +143,44 @@ REMAP_ALLOC_ATTRIBUTES void __rust_dealloc(void* p, size_t size, size_t align) {
147143
#elif USE_WIN_ALIGNED_MALLOC
148144
return _aligned_free(p);
149145
#else
150-
extern void __rdl_dealloc(void* p, size_t size, size_t align);
151146
__rdl_dealloc(p, size, align);
152147
#endif
153148
}
154149

155-
REMAP_ALLOC_ATTRIBUTES void* __rust_realloc(void* p,
156-
size_t old_size,
157-
size_t align,
158-
size_t new_size) {
150+
unsigned char* realloc(unsigned char* p,
151+
size_t old_size,
152+
size_t align,
153+
size_t new_size) {
159154
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC)
160155
if (align <= alignof(std::max_align_t)) {
161-
return allocator_shim::UncheckedRealloc(p, new_size);
156+
return static_cast<unsigned char*>(
157+
allocator_shim::UncheckedRealloc(p, new_size));
162158
} else {
163-
return allocator_shim::UncheckedAlignedRealloc(p, new_size, align);
159+
return static_cast<unsigned char*>(
160+
allocator_shim::UncheckedAlignedRealloc(p, new_size, align));
164161
}
165162
#elif USE_WIN_ALIGNED_MALLOC
166-
return _aligned_realloc(p, new_size, align);
163+
return static_cast<unsigned char*>(_aligned_realloc(p, new_size, align));
167164
#else
168-
extern void* __rdl_realloc(void* p, size_t old_size, size_t align,
169-
size_t new_size);
170-
return __rdl_realloc(p, old_size, align, new_size);
165+
return static_cast<unsigned char*>(
166+
__rdl_realloc(p, old_size, align, new_size));
171167
#endif
172168
}
173169

174-
REMAP_ALLOC_ATTRIBUTES void* __rust_alloc_zeroed(size_t size, size_t align) {
170+
unsigned char* alloc_zeroed(size_t size, size_t align) {
175171
#if BUILDFLAG(RUST_ALLOCATOR_USES_PARTITION_ALLOC) || USE_WIN_ALIGNED_MALLOC
176172
// TODO(danakj): When RUST_ALLOCATOR_USES_PARTITION_ALLOC is true, it's
177173
// possible that a partition_alloc::UncheckedAllocZeroed() call would perform
178174
// better than partition_alloc::UncheckedAlloc() + memset. But there is no
179175
// such API today. See b/342251590.
180-
void* p = __rust_alloc(size, align);
176+
unsigned char* p = alloc(size, align);
181177
if (p) {
182178
memset(p, 0, size);
183179
}
184180
return p;
185181
#else
186-
extern void* __rdl_alloc_zeroed(size_t size, size_t align);
187-
return __rdl_alloc_zeroed(size, align);
182+
return static_cast<unsigned char*>(__rdl_alloc_zeroed(size, align));
188183
#endif
189184
}
190185

191-
REMAP_ALLOC_ATTRIBUTES void __rust_alloc_error_handler(size_t size,
192-
size_t align) {
193-
NO_CODE_FOLDING();
194-
IMMEDIATE_CRASH();
195-
}
196-
197-
REMAP_ALLOC_ATTRIBUTES extern const unsigned char
198-
__rust_alloc_error_handler_should_panic = 0;
199-
200-
} // extern "C"
186+
} // namespace rust_allocator_internal
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2025 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
6+
#define BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
7+
8+
#include <cstddef>
9+
10+
#include "build/build_config.h"
11+
#include "build/rust/allocator/buildflags.h"
12+
13+
namespace rust_allocator_internal {
14+
15+
unsigned char* alloc(size_t size, size_t align);
16+
void dealloc(unsigned char* p, size_t size, size_t align);
17+
unsigned char* realloc(unsigned char* p,
18+
size_t old_size,
19+
size_t align,
20+
size_t new_size);
21+
unsigned char* alloc_zeroed(size_t size, size_t align);
22+
23+
} // namespace rust_allocator_internal
24+
25+
#endif // BUILD_RUST_ALLOCATOR_ALLOCATOR_IMPLS_H_
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2025 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <cstddef>
6+
7+
#include "build/rust/allocator/alias.h"
8+
#include "build/rust/allocator/immediate_crash.h"
9+
10+
extern "C" {
11+
12+
// As part of rustc's contract for using `#[global_allocator]` without
13+
// rustc-generated shims we must define this symbol, since we are opting in to
14+
// unstable functionality. See https://github.com./rust-lang/rust/issues/123015
15+
//
16+
// Mark it weak since rustc will generate it when it drives linking.
17+
[[maybe_unused]]
18+
__attribute__((weak)) unsigned char __rust_no_alloc_shim_is_unstable;
19+
20+
__attribute__((weak)) void __rust_alloc_error_handler(size_t size,
21+
size_t align) {
22+
NO_CODE_FOLDING();
23+
IMMEDIATE_CRASH();
24+
}
25+
26+
__attribute__((
27+
weak)) extern const unsigned char __rust_alloc_error_handler_should_panic =
28+
0;
29+
30+
} // extern "C"

build/rust/std/compiler_specific.h renamed to build/rust/allocator/compiler_specific.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
//
88
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
99

10-
#ifndef BUILD_RUST_STD_COMPILER_SPECIFIC_H_
11-
#define BUILD_RUST_STD_COMPILER_SPECIFIC_H_
10+
#ifndef BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_
11+
#define BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_
1212

1313
#include "build/build_config.h"
1414

@@ -35,4 +35,4 @@
3535
#define NOINLINE
3636
#endif
3737

38-
#endif // BUILD_RUST_STD_COMPILER_SPECIFIC_H_
38+
#endif // BUILD_RUST_ALLOCATOR_COMPILER_SPECIFIC_H_

build/rust/std/immediate_crash.h renamed to build/rust/allocator/immediate_crash.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// This file has been copied from //base/immediate_crash.h.
66
// TODO(crbug.com/40279749): Avoid code duplication / reuse code.
77

8-
#ifndef BUILD_RUST_STD_IMMEDIATE_CRASH_H_
9-
#define BUILD_RUST_STD_IMMEDIATE_CRASH_H_
8+
#ifndef BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_
9+
#define BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_
1010

1111
#include "build/build_config.h"
1212

@@ -168,4 +168,4 @@
168168

169169
#endif // defined(__clang__) || defined(COMPILER_GCC)
170170

171-
#endif // BUILD_RUST_STD_IMMEDIATE_CRASH_H_
171+
#endif // BUILD_RUST_ALLOCATOR_IMMEDIATE_CRASH_H_

0 commit comments

Comments
 (0)