Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -1241,6 +1241,14 @@ if (Name == ".init" || Name == ".fini") return; + // .bss contents are by default sorted by symbol size for better packing. + // According to Android Go project (a project to make Android work better + // on memory and CPU-constrained devices), it is found that this + // heuristics also achieves better memory write locality, which reduces + // number of dirty pages at runtime. + if (Name == ".bss") + Sec->sort([](InputSectionBase *S) { return S->getSize(); }); + // Sort input sections by priority using the list provided // by --symbol-ordering-file. if (!Order.empty()) Index: lld/test/ELF/bss-sort.s =================================================================== --- /dev/null +++ lld/test/ELF/bss-sort.s @@ -0,0 +1,19 @@ +// REQUIRES: x86 +// RUN: echo ".globl s4; .size arr, 4; .bss; s4: .zero 4" | \ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t1.o +// RUN: echo ".globl s8; .size arr, 8; .bss; s8: .zero 8" | \ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t2.o +// RUN: echo ".globl s1; .size arr, 1; .bss; s1: .zero 1" | \ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %t3.o + +// RUN: ld.lld -o %t.exe %t1.o %t2.o %t3.o +// RUN: llvm-readelf -s %t.exe | FileCheck %s + +// Test that symbols in .bss are sorted by size. +// CHECK: 0000000000201001 0 NOTYPE GLOBAL DEFAULT 2 s4 +// CHECK: 0000000000201005 0 NOTYPE GLOBAL DEFAULT 2 s8 +// CHECK: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 2 s1 + +.global _start +_start: + nop Index: lld/test/ELF/common.s =================================================================== --- lld/test/ELF/common.s +++ lld/test/ELF/common.s @@ -18,7 +18,7 @@ // CHECK-NEXT: AddressAlignment: 16 // CHECK: Name: sym1 -// CHECK-NEXT: Value: 0x201000 +// CHECK-NEXT: Value: 0x201014 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -26,7 +26,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym2 -// CHECK-NEXT: Value: 0x201008 +// CHECK-NEXT: Value: 0x20101C // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -34,7 +34,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym3 -// CHECK-NEXT: Value: 0x201010 +// CHECK-NEXT: Value: 0x201000 // CHECK-NEXT: Size: 2 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -42,7 +42,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym4 -// CHECK-NEXT: Value: 0x201020 +// CHECK-NEXT: Value: 0x201010 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object