1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 20:16:03 +01:00

Merge pull request #13919 from xokdvium/smaller-bindings

libexpr: Slim down Bindings to 8 bytes (on 64 bit systems)
This commit is contained in:
Jörg Thalheim 2025-09-06 09:11:48 +02:00 committed by GitHub
commit dbc8d0ab64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 47 additions and 48 deletions

View file

@ -594,7 +594,7 @@ nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * b
context->last_err_code = NIX_OK; context->last_err_code = NIX_OK;
try { try {
auto & v = check_value_not_null(value); auto & v = check_value_not_null(value);
nix::Symbol s = bb->builder.state.symbols.create(name); nix::Symbol s = bb->builder.state.get().symbols.create(name);
bb->builder.insert(s, &v); bb->builder.insert(s, &v);
} }
NIXC_CATCH_ERRS NIXC_CATCH_ERRS

View file

@ -61,7 +61,7 @@ TEST_F(ValuePrintingTests, tAttrs)
Value vTwo; Value vTwo;
vTwo.mkInt(2); vTwo.mkInt(2);
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("one"), &vOne); builder.insert(state.symbols.create("one"), &vOne);
builder.insert(state.symbols.create("two"), &vTwo); builder.insert(state.symbols.create("two"), &vTwo);
@ -196,11 +196,11 @@ TEST_F(ValuePrintingTests, depthAttrs)
Value vTwo; Value vTwo;
vTwo.mkInt(2); vTwo.mkInt(2);
BindingsBuilder builderEmpty(state, state.allocBindings(0)); BindingsBuilder builderEmpty = state.buildBindings(0);
Value vAttrsEmpty; Value vAttrsEmpty;
vAttrsEmpty.mkAttrs(builderEmpty.finish()); vAttrsEmpty.mkAttrs(builderEmpty.finish());
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("one"), &vOne); builder.insert(state.symbols.create("one"), &vOne);
builder.insert(state.symbols.create("two"), &vTwo); builder.insert(state.symbols.create("two"), &vTwo);
builder.insert(state.symbols.create("nested"), &vAttrsEmpty); builder.insert(state.symbols.create("nested"), &vAttrsEmpty);
@ -208,7 +208,7 @@ TEST_F(ValuePrintingTests, depthAttrs)
Value vAttrs; Value vAttrs;
vAttrs.mkAttrs(builder.finish()); vAttrs.mkAttrs(builder.finish());
BindingsBuilder builder2(state, state.allocBindings(10)); BindingsBuilder builder2 = state.buildBindings(10);
builder2.insert(state.symbols.create("one"), &vOne); builder2.insert(state.symbols.create("one"), &vOne);
builder2.insert(state.symbols.create("two"), &vTwo); builder2.insert(state.symbols.create("two"), &vTwo);
builder2.insert(state.symbols.create("nested"), &vAttrs); builder2.insert(state.symbols.create("nested"), &vAttrs);
@ -233,14 +233,14 @@ TEST_F(ValuePrintingTests, depthList)
Value vTwo; Value vTwo;
vTwo.mkInt(2); vTwo.mkInt(2);
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("one"), &vOne); builder.insert(state.symbols.create("one"), &vOne);
builder.insert(state.symbols.create("two"), &vTwo); builder.insert(state.symbols.create("two"), &vTwo);
Value vAttrs; Value vAttrs;
vAttrs.mkAttrs(builder.finish()); vAttrs.mkAttrs(builder.finish());
BindingsBuilder builder2(state, state.allocBindings(10)); BindingsBuilder builder2 = state.buildBindings(10);
builder2.insert(state.symbols.create("one"), &vOne); builder2.insert(state.symbols.create("one"), &vOne);
builder2.insert(state.symbols.create("two"), &vTwo); builder2.insert(state.symbols.create("two"), &vTwo);
builder2.insert(state.symbols.create("nested"), &vAttrs); builder2.insert(state.symbols.create("nested"), &vAttrs);
@ -295,7 +295,7 @@ TEST_F(ValuePrintingTests, attrsTypeFirst)
Value vApple; Value vApple;
vApple.mkStringNoCopy("apple"); vApple.mkStringNoCopy("apple");
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("type"), &vType); builder.insert(state.symbols.create("type"), &vType);
builder.insert(state.symbols.create("apple"), &vApple); builder.insert(state.symbols.create("apple"), &vApple);
@ -374,7 +374,7 @@ TEST_F(ValuePrintingTests, ansiColorsAttrs)
Value vTwo; Value vTwo;
vTwo.mkInt(2); vTwo.mkInt(2);
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("one"), &vOne); builder.insert(state.symbols.create("one"), &vOne);
builder.insert(state.symbols.create("two"), &vTwo); builder.insert(state.symbols.create("two"), &vTwo);
@ -392,7 +392,7 @@ TEST_F(ValuePrintingTests, ansiColorsDerivation)
Value vDerivation; Value vDerivation;
vDerivation.mkStringNoCopy("derivation"); vDerivation.mkStringNoCopy("derivation");
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.s.type, &vDerivation); builder.insert(state.s.type, &vDerivation);
Value vAttrs; Value vAttrs;
@ -437,7 +437,7 @@ TEST_F(ValuePrintingTests, ansiColorsDerivationError)
Value vDerivation; Value vDerivation;
vDerivation.mkStringNoCopy("derivation"); vDerivation.mkStringNoCopy("derivation");
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.s.type, &vDerivation); builder.insert(state.s.type, &vDerivation);
builder.insert(state.s.drvPath, &vError); builder.insert(state.s.drvPath, &vError);
@ -553,12 +553,12 @@ TEST_F(ValuePrintingTests, ansiColorsBlackhole)
TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated) TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); BindingsBuilder emptyBuilder = state.buildBindings(1);
Value vEmpty; Value vEmpty;
vEmpty.mkAttrs(emptyBuilder.finish()); vEmpty.mkAttrs(emptyBuilder.finish());
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("a"), &vEmpty); builder.insert(state.symbols.create("a"), &vEmpty);
builder.insert(state.symbols.create("b"), &vEmpty); builder.insert(state.symbols.create("b"), &vEmpty);
@ -570,7 +570,7 @@ TEST_F(ValuePrintingTests, ansiColorsAttrsRepeated)
TEST_F(ValuePrintingTests, ansiColorsListRepeated) TEST_F(ValuePrintingTests, ansiColorsListRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); BindingsBuilder emptyBuilder = state.buildBindings(1);
Value vEmpty; Value vEmpty;
vEmpty.mkAttrs(emptyBuilder.finish()); vEmpty.mkAttrs(emptyBuilder.finish());
@ -586,7 +586,7 @@ TEST_F(ValuePrintingTests, ansiColorsListRepeated)
TEST_F(ValuePrintingTests, listRepeated) TEST_F(ValuePrintingTests, listRepeated)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1)); BindingsBuilder emptyBuilder = state.buildBindings(1);
Value vEmpty; Value vEmpty;
vEmpty.mkAttrs(emptyBuilder.finish()); vEmpty.mkAttrs(emptyBuilder.finish());
@ -609,7 +609,7 @@ TEST_F(ValuePrintingTests, ansiColorsAttrsElided)
Value vTwo; Value vTwo;
vTwo.mkInt(2); vTwo.mkInt(2);
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder = state.buildBindings(10);
builder.insert(state.symbols.create("one"), &vOne); builder.insert(state.symbols.create("one"), &vOne);
builder.insert(state.symbols.create("two"), &vTwo); builder.insert(state.symbols.create("two"), &vTwo);
@ -635,8 +635,6 @@ TEST_F(ValuePrintingTests, ansiColorsAttrsElided)
TEST_F(ValuePrintingTests, ansiColorsListElided) TEST_F(ValuePrintingTests, ansiColorsListElided)
{ {
BindingsBuilder emptyBuilder(state, state.allocBindings(1));
Value vOne; Value vOne;
vOne.mkInt(1); vOne.mkInt(1);

View file

@ -16,19 +16,19 @@ Bindings * EvalState::allocBindings(size_t capacity)
throw Error("attribute set of size %d is too big", capacity); throw Error("attribute set of size %d is too big", capacity);
nrAttrsets++; nrAttrsets++;
nrAttrsInAttrsets += capacity; nrAttrsInAttrsets += capacity;
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings((Bindings::size_t) capacity); return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings();
} }
Value & BindingsBuilder::alloc(Symbol name, PosIdx pos) Value & BindingsBuilder::alloc(Symbol name, PosIdx pos)
{ {
auto value = state.allocValue(); auto value = state.get().allocValue();
bindings->push_back(Attr(name, value, pos)); bindings->push_back(Attr(name, value, pos));
return *value; return *value;
} }
Value & BindingsBuilder::alloc(std::string_view name, PosIdx pos) Value & BindingsBuilder::alloc(std::string_view name, PosIdx pos)
{ {
return alloc(state.symbols.create(name), pos); return alloc(state.get().symbols.create(name), pos);
} }
void Bindings::sort() void Bindings::sort()

View file

@ -205,7 +205,7 @@ EvalState::EvalState(
, settings{settings} , settings{settings}
, symbols(StaticEvalSymbols::staticSymbolTable()) , symbols(StaticEvalSymbols::staticSymbolTable())
, repair(NoRepair) , repair(NoRepair)
, emptyBindings(0) , emptyBindings(Bindings())
, storeFS(makeMountedSourceAccessor({ , storeFS(makeMountedSourceAccessor({
{CanonPath::root, makeEmptySourceAccessor()}, {CanonPath::root, makeEmptySourceAccessor()},
/* In the pure eval case, we can simply require /* In the pure eval case, we can simply require
@ -1218,7 +1218,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
*vOverrides, *vOverrides,
[&]() { return vOverrides->determinePos(noPos); }, [&]() { return vOverrides->determinePos(noPos); },
"while evaluating the `__overrides` attribute"); "while evaluating the `__overrides` attribute");
bindings.grow(state.allocBindings(bindings.capacity() + vOverrides->attrs()->size())); bindings.grow(state.buildBindings(bindings.capacity() + vOverrides->attrs()->size()));
for (auto & i : *vOverrides->attrs()) { for (auto & i : *vOverrides->attrs()) {
AttrDefs::iterator j = attrs.find(i.name); AttrDefs::iterator j = attrs.find(i.name);
if (j != attrs.end()) { if (j != attrs.end()) {

View file

@ -5,6 +5,7 @@
#include "nix/expr/symbol-table.hh" #include "nix/expr/symbol-table.hh"
#include <algorithm> #include <algorithm>
#include <functional>
namespace nix { namespace nix {
@ -54,16 +55,14 @@ public:
PosIdx pos; PosIdx pos;
private: private:
size_t size_, capacity_; size_t size_ = 0;
Attr attrs[0]; Attr attrs[0];
Bindings(size_t capacity) Bindings() = default;
: size_(0) Bindings(const Bindings &) = delete;
, capacity_(capacity) Bindings(Bindings &&) = delete;
{ Bindings & operator=(const Bindings &) = delete;
} Bindings & operator=(Bindings &&) = delete;
Bindings(const Bindings & bindings) = delete;
public: public:
size_t size() const size_t size() const
@ -82,7 +81,6 @@ public:
void push_back(const Attr & attr) void push_back(const Attr & attr)
{ {
assert(size_ < capacity_);
attrs[size_++] = attr; attrs[size_++] = attr;
} }
@ -136,11 +134,6 @@ public:
void sort(); void sort();
size_t capacity() const
{
return capacity_;
}
/** /**
* Returns the attributes in lexicographically sorted order. * Returns the attributes in lexicographically sorted order.
*/ */
@ -165,22 +158,29 @@ public:
* order at the end. The only way to consume a BindingsBuilder is to * order at the end. The only way to consume a BindingsBuilder is to
* call finish(), which sorts the bindings. * call finish(), which sorts the bindings.
*/ */
class BindingsBuilder class BindingsBuilder final
{ {
Bindings * bindings;
public: public:
// needed by std::back_inserter // needed by std::back_inserter
using value_type = Attr; using value_type = Attr;
using size_type = Bindings::size_t;
EvalState & state; private:
Bindings * bindings;
Bindings::size_t capacity_;
BindingsBuilder(EvalState & state, Bindings * bindings) friend class EvalState;
BindingsBuilder(EvalState & state, Bindings * bindings, size_type capacity)
: bindings(bindings) : bindings(bindings)
, capacity_(capacity)
, state(state) , state(state)
{ {
} }
public:
std::reference_wrapper<EvalState> state;
void insert(Symbol name, Value * value, PosIdx pos = noPos) void insert(Symbol name, Value * value, PosIdx pos = noPos)
{ {
insert(Attr(name, value, pos)); insert(Attr(name, value, pos));
@ -193,6 +193,7 @@ public:
void push_back(const Attr & attr) void push_back(const Attr & attr)
{ {
assert(bindings->size() < capacity_);
bindings->push_back(attr); bindings->push_back(attr);
} }
@ -211,16 +212,16 @@ public:
return bindings; return bindings;
} }
size_t capacity() size_t capacity() const noexcept
{ {
return bindings->capacity(); return capacity_;
} }
void grow(Bindings * newBindings) void grow(BindingsBuilder newBindings)
{ {
for (auto & i : *bindings) for (auto & i : *bindings)
newBindings->push_back(i); newBindings.push_back(i);
bindings = newBindings; std::swap(*this, newBindings);
} }
friend struct ExprAttrs; friend struct ExprAttrs;

View file

@ -879,7 +879,7 @@ public:
BindingsBuilder buildBindings(size_t capacity) BindingsBuilder buildBindings(size_t capacity)
{ {
return BindingsBuilder(*this, allocBindings(capacity)); return BindingsBuilder(*this, allocBindings(capacity), capacity);
} }
ListBuilder buildList(size_t size) ListBuilder buildList(size_t size)