about summary refs log tree commit diff
path: root/src/libexpr/eval.hh
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2014-09-19T14·49+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2014-09-19T14·49+0200
commit5b58991a71d15123c010bbbd7f08530dbc31173f (patch)
tree3cec3413ee43ddd8b46b950022e0741a7c166fd7 /src/libexpr/eval.hh
parent0342eb170500f726f11269d26a1f34cded5d3676 (diff)
Store Attrs inside Bindings
This prevents a double allocation per attribute set.
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r--src/libexpr/eval.hh72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index af9452c753..3ac40ed34e 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -16,23 +16,59 @@ namespace nix {
 
 
 class EvalState;
-struct Attr;
 
 
-/* Sets are represented as a vector of attributes, sorted by symbol
-   (i.e. pointer to the attribute name in the symbol table). */
-#if HAVE_BOEHMGC
-typedef std::vector<Attr, gc_allocator<Attr> > BindingsBase;
-#else
-typedef std::vector<Attr> BindingsBase;
-#endif
+struct Attr
+{
+    Symbol name;
+    Value * value;
+    Pos * pos;
+    Attr(Symbol name, Value * value, Pos * pos = &noPos)
+        : name(name), value(value), pos(pos) { };
+    Attr() : pos(&noPos) { };
+    bool operator < (const Attr & a) const
+    {
+        return name < a.name;
+    }
+};
 
 
-class Bindings : public BindingsBase
+class Bindings
 {
 public:
+    typedef uint32_t size_t;
+
+private:
+    size_t size_, capacity;
+    Attr attrs[0];
+
+    Bindings(uint32_t capacity) : size_(0), capacity(capacity) { }
+
+public:
+    size_t size() { return size_; }
+
+    bool empty() { return !size_; }
+
+    typedef Attr * iterator;
+
+    void push_back(const Attr & attr)
+    {
+        assert(size_ < capacity);
+        attrs[size_++] = attr;
+    }
+
     iterator find(const Symbol & name);
+    iterator begin() { return &attrs[0]; }
+    iterator end() { return &attrs[size_]; }
+
+    Attr & operator[](size_t pos)
+    {
+        return attrs[pos];
+    }
+
     void sort();
+
+    friend class EvalState;
 };
 
 
@@ -58,21 +94,6 @@ struct Env
 };
 
 
-struct Attr
-{
-    Symbol name;
-    Value * value;
-    Pos * pos;
-    Attr(Symbol name, Value * value, Pos * pos = &noPos)
-        : name(name), value(value), pos(pos) { };
-    Attr() : pos(&noPos) { };
-    bool operator < (const Attr & a) const
-    {
-        return name < a.name;
-    }
-};
-
-
 void mkString(Value & v, const string & s, const PathSet & context = PathSet());
 
 void copyContext(const Value & v, PathSet & context);
@@ -245,6 +266,8 @@ public:
 
     Value * allocAttr(Value & vAttrs, const Symbol & name);
 
+    Bindings * allocBindings(Bindings::size_t capacity);
+
     void mkList(Value & v, unsigned int length);
     void mkAttrs(Value & v, unsigned int expected);
     void mkThunk_(Value & v, Expr * expr);
@@ -264,6 +287,7 @@ private:
     unsigned long nrValues;
     unsigned long nrListElems;
     unsigned long nrAttrsets;
+    unsigned long nrAttrsInAttrsets;
     unsigned long nrOpUpdates;
     unsigned long nrOpUpdateValuesCopied;
     unsigned long nrListConcats;