authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-08 09:52:08-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-11-09 03:31:26-05:00
logd33c00cad024c15e4fae84317d24d816eaf3da3a
tree5835369c6364f687308b49a0282e19c33c0586cc
parent02a241f472bf0c5146ab73c105767178e4822a47

MappedFile: avoid allocating file space with inconsistent state


1 files changed, 12 insertions(+), 25 deletions(-)

src/link/MappedFile.zig+12-25
...@@ -486,6 +486,14 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct {...@@ -486,6 +486,14 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct {
486 break :free .{ free_ni, free_node };486 break :free .{ free_ni, free_node };
487 },487 },
488 };488 };
489 switch (opts.prev) {
490 .none => opts.parent.get(mf).first = free_ni,
491 else => |prev_ni| prev_ni.get(mf).next = free_ni,
492 }
493 switch (opts.next) {
494 .none => opts.parent.get(mf).last = free_ni,
495 else => |next_ni| next_ni.get(mf).prev = free_ni,
496 }
489 free_node.* = .{497 free_node.* = .{
490 .parent = opts.parent,498 .parent = opts.parent,
491 .prev = opts.prev,499 .prev = opts.prev,
...@@ -535,13 +543,10 @@ pub fn addOnlyChildNode(...@@ -535,13 +543,10 @@ pub fn addOnlyChildNode(
535 try mf.nodes.ensureUnusedCapacity(gpa, 1);543 try mf.nodes.ensureUnusedCapacity(gpa, 1);
536 const parent = parent_ni.get(mf);544 const parent = parent_ni.get(mf);
537 assert(parent.first == .none and parent.last == .none);545 assert(parent.first == .none and parent.last == .none);
538 const ni = try mf.addNode(gpa, .{546 return mf.addNode(gpa, .{
539 .parent = parent_ni,547 .parent = parent_ni,
540 .add_node = opts,548 .add_node = opts,
541 });549 });
542 parent.first = ni;
543 parent.last = ni;
544 return ni;
545}550}
546551
547pub fn addFirstChildNode(552pub fn addFirstChildNode(
...@@ -552,17 +557,11 @@ pub fn addFirstChildNode(...@@ -552,17 +557,11 @@ pub fn addFirstChildNode(
552) !Node.Index {557) !Node.Index {
553 try mf.nodes.ensureUnusedCapacity(gpa, 1);558 try mf.nodes.ensureUnusedCapacity(gpa, 1);
554 const parent = parent_ni.get(mf);559 const parent = parent_ni.get(mf);
555 const ni = try mf.addNode(gpa, .{560 return mf.addNode(gpa, .{
556 .parent = parent_ni,561 .parent = parent_ni,
557 .next = parent.first,562 .next = parent.first,
558 .add_node = opts,563 .add_node = opts,
559 });564 });
560 switch (parent.first) {
561 .none => parent.last = ni,
562 else => |first_ni| first_ni.get(mf).prev = ni,
563 }
564 parent.first = ni;
565 return ni;
566}565}
567566
568pub fn addLastChildNode(567pub fn addLastChildNode(
...@@ -573,7 +572,7 @@ pub fn addLastChildNode(...@@ -573,7 +572,7 @@ pub fn addLastChildNode(
573) !Node.Index {572) !Node.Index {
574 try mf.nodes.ensureUnusedCapacity(gpa, 1);573 try mf.nodes.ensureUnusedCapacity(gpa, 1);
575 const parent = parent_ni.get(mf);574 const parent = parent_ni.get(mf);
576 const ni = try mf.addNode(gpa, .{575 return mf.addNode(gpa, .{
577 .parent = parent_ni,576 .parent = parent_ni,
578 .prev = parent.last,577 .prev = parent.last,
579 .offset = offset: switch (parent.last) {578 .offset = offset: switch (parent.last) {
...@@ -585,12 +584,6 @@ pub fn addLastChildNode(...@@ -585,12 +584,6 @@ pub fn addLastChildNode(
585 },584 },
586 .add_node = opts,585 .add_node = opts,
587 });586 });
588 switch (parent.last) {
589 .none => parent.first = ni,
590 else => |last_ni| last_ni.get(mf).next = ni,
591 }
592 parent.last = ni;
593 return ni;
594}587}
595588
596pub fn addNodeAfter(589pub fn addNodeAfter(
...@@ -603,19 +596,13 @@ pub fn addNodeAfter(...@@ -603,19 +596,13 @@ pub fn addNodeAfter(
603 try mf.nodes.ensureUnusedCapacity(gpa, 1);596 try mf.nodes.ensureUnusedCapacity(gpa, 1);
604 const prev = prev_ni.get(mf);597 const prev = prev_ni.get(mf);
605 const prev_offset, const prev_size = prev.location().resolve(mf);598 const prev_offset, const prev_size = prev.location().resolve(mf);
606 const ni = try mf.addNode(gpa, .{599 return mf.addNode(gpa, .{
607 .parent = prev.parent,600 .parent = prev.parent,
608 .prev = prev_ni,601 .prev = prev_ni,
609 .next = prev.next,602 .next = prev.next,
610 .offset = prev_offset + prev_size,603 .offset = prev_offset + prev_size,
611 .add_node = opts,604 .add_node = opts,
612 });605 });
613 switch (prev.next) {
614 .none => prev.parent.get(mf).last = ni,
615 else => |next_ni| next_ni.get(mf).prev = ni,
616 }
617 prev.next = ni;
618 return ni;
619}606}
620607
621fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void {608fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void {