Dev server refactoring, part 1 (mainly IncrementalGraph) (#22010)

* `IncrementalGraph(.client).File` packs its fields in a specific way to
save space, but it makes the struct hard to use and error-prone (e.g.,
untagged unions with tags stored in a separate `flags` struct). This PR
changes `File` to have a human-readable layout, but adds methods to
convert it to and from `File.Packed`, a packed version with the same
space efficiency as before.
* Reduce the need to pass the dev allocator to functions (e.g.,
`deinit`) by storing it as a struct field via the new `DevAllocator`
type. This type has no overhead in release builds, or when
`AllocationScope` is disabled.
* Use owned pointers in `PackedMap`.
* Use `bun.ptr.Shared` for `PackedMap` instead of the old
`bun.ptr.RefPtr`.
* Add `bun.ptr.ScopedOwned`, which is like `bun.ptr.Owned`, but can
store an `AllocationScope`. No overhead in release builds or when
`AllocationScope` is disabled.
* Reduce redundant allocators in `BundleV2`.
* Add owned pointer conversions to `MutableString`.
* Make `AllocationScope` behave like a pointer, so it can be moved
without invalidating allocations. This eliminates the need for
self-references.
* Change memory cost algorithm so it doesn't rely on “dedupe bits”.
These bits used to take advantage of padding but there is now no padding
in `PackedMap`.
* Replace `VoidFieldTypes` with `useAllFields`; this eliminates the need
for `voidFieldTypesDiscardHelper`.

(For internal tracking: fixes STAB-1035, STAB-1036, STAB-1037,
STAB-1038, STAB-1039, STAB-1040, STAB-1041, STAB-1042, STAB-1043,
STAB-1044, STAB-1045)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
taylor.fish
2025-08-22 23:04:58 -07:00
committed by GitHub
parent 790e5d4a7e
commit 7717693c70
44 changed files with 1484 additions and 1305 deletions

View File

@@ -241,14 +241,24 @@ pub inline fn lenI(self: *MutableString) i32 {
}
pub fn toOwnedSlice(self: *MutableString) []u8 {
return self.list.toOwnedSlice(self.allocator) catch bun.outOfMemory(); // TODO
return bun.handleOom(self.list.toOwnedSlice(self.allocator));
}
pub fn toDynamicOwned(self: *MutableString) DynamicOwned([]u8) {
return .fromRawOwned(self.toOwnedSlice(), self.allocator);
}
/// `self.allocator` must be `bun.default_allocator`.
pub fn toDefaultOwned(self: *MutableString) Owned([]u8) {
bun.safety.alloc.assertEq(self.allocator, bun.default_allocator);
return .fromRawOwned(self.toOwnedSlice());
}
pub fn slice(self: *MutableString) []u8 {
return self.list.items;
}
/// Clear the existing value without freeing the memory or shrinking the capacity.
/// Take ownership of the existing value without discarding excess capacity.
pub fn move(self: *MutableString) []u8 {
const out = self.list.items;
self.list = .{};
@@ -258,18 +268,14 @@ pub fn move(self: *MutableString) []u8 {
/// Appends `0` if needed
pub fn sliceWithSentinel(self: *MutableString) [:0]u8 {
if (self.list.items.len > 0 and self.list.items[self.list.items.len - 1] != 0) {
self.list.append(
self.allocator,
0,
) catch unreachable;
bun.handleOom(self.list.append(self.allocator, 0));
}
return self.list.items[0 .. self.list.items.len - 1 :0];
}
pub fn toOwnedSliceLength(self: *MutableString, length: usize) string {
self.list.items.len = length;
return self.list.toOwnedSlice(self.allocator) catch bun.outOfMemory(); // TODO
return self.toOwnedSlice();
}
pub fn containsChar(self: *const MutableString, char: u8) bool {
@@ -463,3 +469,6 @@ const Allocator = std.mem.Allocator;
const bun = @import("bun");
const js_lexer = bun.js_lexer;
const strings = bun.strings;
const DynamicOwned = bun.ptr.DynamicOwned;
const Owned = bun.ptr.Owned;