Revamp serialization to make it easier.
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 28 Oct 2003 20:55:12 +0000 (12:55 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 28 Oct 2003 20:55:12 +0000 (12:55 -0800)
--HG--
extra : convert_revision : c57a538d7cf606dbdf5fa244f92da46bd830e335

15 files changed:
arch/alpha/alpha_memory.cc
arch/alpha/alpha_memory.hh
cpu/exec_context.cc
cpu/exec_context.hh
cpu/simple_cpu/simple_cpu.cc
cpu/simple_cpu/simple_cpu.hh
dev/alpha_access.h
dev/alpha_console.cc
dev/alpha_console.hh
dev/console.cc
dev/console.hh
sim/eventq.cc
sim/eventq.hh
sim/serialize.cc
sim/serialize.hh

index 83dd5accf48404160e16db51a300768d3b0b2709..82dd2afa5a4b5008670eb24c15c8726424f83e4f 100644 (file)
@@ -192,13 +192,13 @@ AlphaTlb::flushAddr(Addr vaddr, uint8_t asn)
 
 
 void
-AlphaTlb::serialize()
+AlphaTlb::serialize(ostream &os)
 {
-    nameOut();
-
-    paramOut("size", size);
-    paramOut("nlu", nlu);
+    SERIALIZE_MEMBER(size);
+    SERIALIZE_MEMBER(nlu);
 
+    // should just add serialize/unserialize methods to AlphaPTE
+#if 0
     stringstream buf;
     for (int i = 0; i < size; i++) {
         buf.str("");
@@ -237,19 +237,18 @@ AlphaTlb::serialize()
         ccprintf(buf, "pte%02d.asn", i);
         paramOut(buf.str(), table[i].asn);
     }
+#endif
 }
 
 void
-AlphaTlb::unserialize(IniFile &db, const string &category, ConfigNode *node)
+AlphaTlb::unserialize(IniFile &db, const string &section)
 {
+    UNSERIALIZE_MEMBER(size);
+    UNSERIALIZE_MEMBER(nlu);
+
+#if 0
     string data;
     stringstream buf;
-
-    db.findDefault(category,"size",data);
-    to_number(data,size);
-    db.findDefault(category,"nlu",data);
-    to_number(data,nlu);
-
     for (int i = 0; i < size; i++) {
         buf.str("");
         ccprintf(buf, "pte%02d.valid", i);
@@ -296,6 +295,7 @@ AlphaTlb::unserialize(IniFile &db, const string &category, ConfigNode *node)
         db.findDefault(category, buf.str(), data);
         to_number(data, table[i].asn);
     }
+#endif
 }
 
 
index 9b7306bfd5a7630fa740480f9e7d7aeab3e1f5bd..c94ee26c3e1dba133ad56c589d7f0bb74aa153d0 100644 (file)
@@ -73,9 +73,8 @@ class AlphaTlb : public SimObject
     static void checkCacheability(MemReqPtr req);
 
     // Checkpointing
-    virtual void serialize();
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node);
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(IniFile &db, const std::string &section);
 
 };
 
index a4670f2914178b63d75b45a3a076fbd5ca4d7c65..8cfd0a0ea45a6369e875468d92a06afc4026b754 100644 (file)
@@ -97,6 +97,22 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
 }
 
 
+void
+ExecContext::serialize(ostream &os)
+{
+    SERIALIZE_ARRAY(regs.intRegFile, NumIntRegs);
+    SERIALIZE_ARRAY(regs.floatRegFile.q, NumFloatRegs);
+}
+
+
+void
+ExecContext::unserialize(IniFile &db, const std::string &section)
+{
+    UNSERIALIZE_ARRAY(regs.intRegFile, NumIntRegs);
+    UNSERIALIZE_ARRAY(regs.floatRegFile.q, NumFloatRegs);
+}
+
+
 void
 ExecContext::setStatus(Status new_status)
 {
index f2afaa33479c241c0a560105065ed083f6f35e7c..285154ed06379cd0fda581069c7d5e87add1fccd 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "sim/host.hh"
 #include "mem/mem_req.hh"
+#include "sim/serialize.hh"
 
 // forward declaration: see functional_memory.hh
 class FunctionalMemory;
@@ -140,6 +141,9 @@ class ExecContext
 
     void regStats(const std::string &name);
 
+    void serialize(std::ostream &os);
+    void unserialize(IniFile &db, const std::string &section);
+
 #ifdef FULL_SYSTEM
     bool validInstAddr(Addr addr) { return true; }
     bool validDataAddr(Addr addr) { return true; }
index 3d0818672d1777fb766eae5c339e3a12a44eedb7..83e9e1fa2b443402ee929944eedaa81bba5497eb 100644 (file)
@@ -240,34 +240,13 @@ SimpleCPU::regStats()
 }
 
 void
-SimpleCPU::serialize()
+SimpleCPU::serialize(ostream &os)
 {
-    nameOut();
-
-#ifdef FULL_SYSTEM
-#if 0
-    // do we need this anymore?? egh
-    childOut("itb", xc->itb);
-    childOut("dtb", xc->dtb);
-    childOut("physmem", physmem);
-#endif
-#endif
-
-    for (int i = 0; i < NumIntRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "R%02d", i);
-        paramOut(buf.str(), xc->regs.intRegFile[i]);
-    }
-    for (int i = 0; i < NumFloatRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "F%02d", i);
-        paramOut(buf.str(), xc->regs.floatRegFile.q[i]);
-    }
-    // CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs);
+    xc->serialize(os);
 }
 
 void
-SimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node)
+SimpleCPU::unserialize(IniFile &db, const string &category)
 {
     string data;
 
index 9e2c7fd06337333f50c69fd1f864cb30990f8bb3..fa7386106ef357bae291cd7b102a2b9c9cdd3100 100644 (file)
@@ -259,9 +259,8 @@ class SimpleCPU : public BaseCPU
 
     void processCacheCompletion();
 
-    virtual void serialize();
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node);
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(IniFile &db, const std::string &section);
 
     template <class T>
     Fault read(Addr addr, T& data, unsigned flags);
index ef33633e5d720f5bc943eefa07c2c407c1079cbe..4bba39c4fff9483df6b82b108aa4ce7294646c64 100644 (file)
@@ -41,6 +41,11 @@ typedef uint64 UINT64;
 #else
 typedef uint32_t UINT32;
 typedef uint64_t UINT64;
+
+#include <ostream>
+#include <string>
+class IniFile;
+
 #endif
 
 // This structure hacked up from simos
@@ -74,6 +79,11 @@ struct AlphaAccess
     UINT64     bootStrapImpure;        // 70:
     UINT32     bootStrapCPU;           // 78:
     UINT32     align2;                 // 7C: Dummy placeholder for alignment
+
+#ifndef CONSOLE
+    void serialize(std::ostream &os);
+    void unserialize(IniFile &db, const std::string &section);
+#endif
 };
 
 #endif // __ALPHA_ACCESS_H__
index cd03b3656985f4deb5fa7f48102730705a286193..00dab4bad766a8fbb2c823523ec9d630eb6d0dc9 100644 (file)
@@ -166,70 +166,59 @@ AlphaConsole::write(MemReqPtr req, const uint8_t *data)
 }
 
 void
-AlphaConsole::serialize()
+AlphaAccess::serialize(ostream &os)
 {
-    nameOut();
-    // assumes full AlphaAccess size
-    // might have unnecessary fields here
-    paramOut("last_offset",alphaAccess->last_offset);
-    paramOut("version",alphaAccess->version);
-    paramOut("numCPUs",alphaAccess->numCPUs);
-    paramOut("mem_size",alphaAccess->mem_size);
-    paramOut("cpuClock",alphaAccess->cpuClock);
-    paramOut("intrClockFrequency",alphaAccess->intrClockFrequency);
-    paramOut("kernStart",alphaAccess->kernStart);
-    paramOut("kernEnd",alphaAccess->kernEnd);
-    paramOut("entryPoint",alphaAccess->entryPoint);
-    paramOut("diskUnit",alphaAccess->diskUnit);
-    paramOut("diskCount",alphaAccess->diskCount);
-    paramOut("diskPAddr",alphaAccess->diskPAddr);
-    paramOut("diskBlock",alphaAccess->diskBlock);
-    paramOut("diskOperation",alphaAccess->diskOperation);
-    paramOut("outputChar",alphaAccess->outputChar);
-    paramOut("bootStrapImpure",alphaAccess->bootStrapImpure);
-    paramOut("bootStrapCPU",alphaAccess->bootStrapCPU);
+    SERIALIZE_MEMBER(last_offset);
+    SERIALIZE_MEMBER(version);
+    SERIALIZE_MEMBER(numCPUs);
+    SERIALIZE_MEMBER(mem_size);
+    SERIALIZE_MEMBER(cpuClock);
+    SERIALIZE_MEMBER(intrClockFrequency);
+    SERIALIZE_MEMBER(kernStart);
+    SERIALIZE_MEMBER(kernEnd);
+    SERIALIZE_MEMBER(entryPoint);
+    SERIALIZE_MEMBER(diskUnit);
+    SERIALIZE_MEMBER(diskCount);
+    SERIALIZE_MEMBER(diskPAddr);
+    SERIALIZE_MEMBER(diskBlock);
+    SERIALIZE_MEMBER(diskOperation);
+    SERIALIZE_MEMBER(outputChar);
+    SERIALIZE_MEMBER(bootStrapImpure);
+    SERIALIZE_MEMBER(bootStrapCPU);
 }
 
 void
-AlphaConsole::unserialize(IniFile &db, const std::string &category,
-                          ConfigNode *node)
+AlphaAccess::unserialize(IniFile &db, const std::string &section)
 {
-    string data;
-    db.findDefault(category,"last_offset",data);
-    to_number(data,alphaAccess->last_offset);
-    db.findDefault(category,"version",data);
-    to_number(data,alphaAccess->version);
-    db.findDefault(category,"numCPUs",data);
-    to_number(data,alphaAccess->numCPUs);
-    db.findDefault(category,"mem_size",data);
-    to_number(data,alphaAccess->mem_size);
-    db.findDefault(category,"cpuClock",data);
-    to_number(data,alphaAccess->cpuClock);
-    db.findDefault(category,"intrClockFrequency",data);
-    to_number(data,alphaAccess->intrClockFrequency);
-    db.findDefault(category,"kernStart",data);
-    to_number(data,alphaAccess->kernStart);
-    db.findDefault(category,"kernEnd",data);
-    to_number(data,alphaAccess->kernEnd);
-    db.findDefault(category,"entryPoint",data);
-    to_number(data,alphaAccess->entryPoint);
-    db.findDefault(category,"diskUnit",data);
-    to_number(data,alphaAccess->diskUnit);
-    db.findDefault(category,"diskCount",data);
-    to_number(data,alphaAccess->diskCount);
-    db.findDefault(category,"diskPAddr",data);
-    to_number(data,alphaAccess->diskPAddr);
-    db.findDefault(category,"diskBlock",data);
-    to_number(data,alphaAccess->diskBlock);
-    db.findDefault(category,"diskOperation",data);
-    to_number(data,alphaAccess->diskOperation);
-    db.findDefault(category,"outputChar",data);
-    to_number(data,alphaAccess->outputChar);
-    db.findDefault(category,"bootStrapImpure",data);
-    to_number(data,alphaAccess->bootStrapImpure);
-    db.findDefault(category,"bootStrapCPU",data);
-    to_number(data,alphaAccess->bootStrapCPU);
+    UNSERIALIZE_MEMBER(last_offset);
+    UNSERIALIZE_MEMBER(version);
+    UNSERIALIZE_MEMBER(numCPUs);
+    UNSERIALIZE_MEMBER(mem_size);
+    UNSERIALIZE_MEMBER(cpuClock);
+    UNSERIALIZE_MEMBER(intrClockFrequency);
+    UNSERIALIZE_MEMBER(kernStart);
+    UNSERIALIZE_MEMBER(kernEnd);
+    UNSERIALIZE_MEMBER(entryPoint);
+    UNSERIALIZE_MEMBER(diskUnit);
+    UNSERIALIZE_MEMBER(diskCount);
+    UNSERIALIZE_MEMBER(diskPAddr);
+    UNSERIALIZE_MEMBER(diskBlock);
+    UNSERIALIZE_MEMBER(diskOperation);
+    UNSERIALIZE_MEMBER(outputChar);
+    UNSERIALIZE_MEMBER(bootStrapImpure);
+    UNSERIALIZE_MEMBER(bootStrapCPU);
+}
 
+void
+AlphaConsole::serialize(ostream &os)
+{
+    alphaAccess->serialize(os);
+}
+
+void
+AlphaConsole::unserialize(IniFile &db, const std::string &section)
+{
+    alphaAccess->unserialize(db, section);
 }
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole)
index 608e6ac00da180b574e74884185732487ea36f76..caa571cecbca190b4c98222718b956083528d440 100644 (file)
@@ -100,9 +100,8 @@ class AlphaConsole : public MmapDevice
     /**
      * standard serialization routines for checkpointing
      */
-    virtual void serialize();
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node);
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(IniFile &db, const std::string &section);
 };
 
 #endif // __ALPHA_CONSOLE_HH__
index 168907417bb4bf0c83d77f02a5afab324234e15c..a84f4a66614408ce59b7cd043bc99b90dfda560f 100644 (file)
@@ -314,14 +314,13 @@ SimConsole::setInt(int bits)
 
 
 void
-SimConsole::serialize()
+SimConsole::serialize(ostream &os)
 {
     panic("Unimplemented");
 }
 
 void
-SimConsole::unserialize(IniFile &db, const std::string &category,
-                        ConfigNode *node)
+SimConsole::unserialize(IniFile &db, const std::string &section)
 {
     panic("Unimplemented");
 }
index b88cab3ef7dfe1e65f73fd57d8221321e2b05ef8..5d9ea53029583385da6a901fd0c5dad76fd85ffb 100644 (file)
@@ -128,9 +128,8 @@ class SimConsole : public SimObject
     void initInt(IntrControl *i);
     void setInt(int bits);
 
-    virtual void serialize();
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node);
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(IniFile &db, const std::string &section);
 };
 
 class ConsoleListener : public SimObject
index 6ffce4c0e00c7c646453baa63db8f86397da1ee3..da9e85eeb6924d77d038e2ea1e7c163c9305ac2d 100644 (file)
@@ -134,7 +134,7 @@ EventQueue::nameChildren()
 }
 
 void
-EventQueue::serialize()
+EventQueue::serialize(ostream &os)
 {
     string objects = "";
 
@@ -142,12 +142,12 @@ EventQueue::serialize()
     while (event) {
         objects += event->name();
         objects += " ";
-        event->serialize();
+        event->serialize(os);
 
         event = event->next;
     }
-    nameOut("Serialized");
-    paramOut("objects",objects);
+    nameOut(os, "Serialized");
+    SERIALIZE_MEMBER(objects);
 }
 
 void
index df8e00bd87f7ccbf4003b32168961232c3e1e172..cd86512e4daab422cb44c31d803e7c79de0a112c 100644 (file)
@@ -246,7 +246,7 @@ class EventQueue : public Serializeable
     Tick nextEventTime() { return empty() ? curTick : head->when(); }
 
     virtual void nameChildren();
-    virtual void serialize();
+    virtual void serialize(std::ostream &os);
 };
 
 
index c90f1694e8d38c70c73b5e4730a49d4085ae8d8f..936812795b5057f4494944ce90c0e6ca924d28aa 100644 (file)
@@ -34,6 +34,7 @@
 #include <vector>
 
 #include "base/misc.hh"
+#include "base/str.hh"
 
 #include "sim/eventq.hh"
 #include "sim/param.hh"
@@ -48,7 +49,7 @@ using namespace std;
 Serializer *Serializeable::serializer = NULL;
 
 Serializeable::Serializeable(const string &n)
-    : proxy(this), objName(n), serialized(false)
+    : objName(n), serialized(false)
 { }
 
 Serializeable::~Serializeable()
@@ -63,30 +64,131 @@ Serializeable::mark()
     serialized = true;
 }
 
-ostream &
-Serializeable::out() const
+void
+Serializeable::nameOut(ostream &os)
+{
+    os << "\n[" << name() << "]\n";
+}
+
+void
+Serializeable::nameOut(ostream &os, const string &_name)
+{
+    os << "\n[" << _name << "]\n";
+}
+
+template <class T> bool parseParam(const std::string &str, T &data);
+template <class T> void showParam(const std::ostream &os, T &data);
+
+template <class T>
+void
+paramOut(ostream &os, const std::string &name, const T& param)
 {
-    return serializer->out();
+    os << name << "=";
+    showParam(os, param);
+    os << "\n";
 }
 
+
+template <class T>
 void
-Serializeable::nameOut()
+paramIn(IniFile &db, const std::string &section,
+        const std::string &name, T& param)
 {
-    out() << "\n[" << name() << "]\n";
+    std::string str;
+    if (!db.find(section, name, str) || !parseParam(str, param)) {
+        fatal("Can't unserialize '%s:%s'\n", section, name);
+    }
 }
 
+
+template <class T>
 void
-Serializeable::nameOut(const string &_name)
+arrayParamOut(ostream &os, const std::string &name,
+              const T *param, int size)
 {
-    out() << "\n[" << _name << "]\n";
+    os << name << "=";
+    if (size > 0)
+        showParam(os, param[0]);
+    for (int i = 1; i < size; ++i) {
+        os << " ";
+        showParam(os, param[i]);
+    }
+    os << "\n";
 }
 
-template<> void
-Serializeable::paramOut(const string &name, const uint64_t& param)
+
+template <class T>
+void
+arrayParamIn(IniFile &db, const std::string &section,
+             const std::string &name, T *param, int size)
 {
-    out() << name << "=0x" << hex << param << dec << "\n";
+    std::string str;
+    if (!db.find(section, name, str)) {
+        fatal("Can't unserialize '%s:%s'\n", section, name);
+    }
+
+    // code below stolen from VectorParam<T>::parse().
+    // it would be nice to unify these somehow...
+
+    vector<string> tokens;
+
+    tokenize(tokens, str, ' ');
+
+    // Need this if we were doing a vector
+    // value.resize(tokens.size());
+
+    if (tokens.size() != size) {
+        fatal("Array size mismatch on %s:%s'\n", section, name);
+    }
+
+    for (int i = 0; i < tokens.size(); i++) {
+        // need to parse into local variable to handle vector<bool>,
+        // for which operator[] returns a special reference class
+        // that's not the same as 'bool&', (since it's a packed
+        // vector)
+        T scalar_value;
+        if (!parseParam(tokens[i], scalar_value)) {
+            string err("could not parse \"");
+
+            err += str;
+            err += "\"";
+
+            fatal(err);
+        }
+
+        // assign parsed value to vector
+        param[i] = scalar_value;
+    }
 }
 
+
+#define INSTANTIATE_PARAM_TEMPLATES(type)                      \
+template void                                          \
+paramOut(ostream &os, const std::string &name, const type &param);     \
+template void                                          \
+paramIn(IniFile &db, const std::string &section,               \
+        const std::string &name, type & param);                        \
+template void                                          \
+arrayParamOut(ostream &os, const std::string &name,            \
+              const type *param, int size);                    \
+template void                                          \
+arrayParamIn(IniFile &db, const std::string &section,          \
+             const std::string &name, type *param, int size);
+
+
+INSTANTIATE_PARAM_TEMPLATES(int8_t)
+INSTANTIATE_PARAM_TEMPLATES(uint8_t)
+INSTANTIATE_PARAM_TEMPLATES(int16_t)
+INSTANTIATE_PARAM_TEMPLATES(uint16_t)
+INSTANTIATE_PARAM_TEMPLATES(int32_t)
+INSTANTIATE_PARAM_TEMPLATES(uint32_t)
+INSTANTIATE_PARAM_TEMPLATES(int64_t)
+INSTANTIATE_PARAM_TEMPLATES(uint64_t)
+INSTANTIATE_PARAM_TEMPLATES(string)
+
+
+#if 0
+// unneeded?
 void
 Serializeable::childOut(const string &name, Serializeable *child)
 {
@@ -96,6 +198,7 @@ Serializeable::childOut(const string &name, Serializeable *child)
 
     out() << name << "=" << child->name() << "\n";
 }
+#endif
 
 void
 Serializeable::setName(const string &name)
@@ -174,11 +277,12 @@ Serializer::serialize(const string &f)
 
     add_objects();
     while (!objects.empty()) {
-        Serializeable *serial = objects.front();
-        DPRINTF(Serialize, "Serializing %s\n", serial->name());
-        serial->serialize();
+        Serializeable *obj = objects.front();
+        DPRINTF(Serialize, "Serializing %s\n", obj->name());
+        obj->nameOut(out());
+        obj->serialize(out());
         objects.pop_front();
-        list.push_back(serial);
+        list.push_back(obj);
     }
 
     while (!list.empty()) {
@@ -203,7 +307,7 @@ class SerializeEvent : public Event
     ~SerializeEvent();
 
     virtual void process();
-    virtual void serialize();
+    virtual void serialize(std::ostream &os);
 };
 
 SerializeEvent::SerializeEvent(EventQueue *q, Tick when, const string &f)
@@ -226,7 +330,7 @@ SerializeEvent::process()
 }
 
 void
-SerializeEvent::serialize()
+SerializeEvent::serialize(ostream &os)
 {
     panic("Cannot serialize the SerializeEvent");
 }
index ffcbbcdc20203055708b7355d9a21febaefd069a..5ebbfaba5e026a0bb60cf3eeeb45779e91769a19 100644 (file)
 
 #include <list>
 #include <iostream>
+#include <map>
 
 #include "sim/host.hh"
 #include "sim/configfile.hh"
 
 class IniFile;
 
+template <class T>
+void paramOut(std::ostream &os, const std::string &name, const T& param);
+
+template <class T>
+void paramIn(IniFile &db, const std::string &section,
+             const std::string &name, T& param);
+
+template <class T>
+void arrayParamOut(std::ostream &os, const std::string &name,
+                   const T *param, int size);
+
+template <class T>
+void arrayParamIn(IniFile &db, const std::string &section,
+                  const std::string &name, T *param, int size);
+
+//
+// These macros are streamlined to use in serialize/unserialize
+// functions.  It's assumed that serialize() has a parameter 'os' for
+// the ostream, and unserialize() has parameters 'db' and 'section'.
+#define SERIALIZE_MEMBER(member)       paramOut(os, #member, member)
+
+#define UNSERIALIZE_MEMBER(member)     paramIn(db, section, #member, member)
+
+#define SERIALIZE_ARRAY(member, size)  \
+        arrayParamOut(os, #member, member, size)
+
+#define UNSERIALIZE_ARRAY(member, size)        \
+        arrayParamIn(db, section, #member, member, size)
+
 /*
  * Basic support for object serialization.
  */
 class Serializeable
 {
   public:
-    // To allow other classes to do some of the serialization work.
-    class Proxy {
-      private:
-        Serializeable *obj;
-
-        // Make it so only Serializables can construct one of these.
-        Proxy(Serializeable *o) : obj(o) {};
-
-        friend class Serializeable;
-
-      public:
-        template <class T>
-        void paramOut(const std::string &name, const T& param) const {
-            obj->paramOut(name, param);
-        };
-    };
 
     friend class Serializer;
-    friend class Proxy;
-
-  private:
-    Proxy proxy;
 
   protected:
-    const Proxy &getProxy() { return(proxy); };
-
     // object name: should be unique
     std::string objName;
 
@@ -81,13 +89,8 @@ class Serializeable
     static Serializer *serializer;
 
     void mark();
-    void nameOut();
-    void nameOut(const std::string &_name);
-    void childOut(const std::string &name, Serializeable *child);
-    template <class T>
-    void paramOut(const std::string &name, const T& param);
-
-    std::ostream &out() const;
+    void nameOut(std::ostream& os);
+    void nameOut(std::ostream& os, const std::string &_name);
 
   public:
     Serializeable(const std::string &n);
@@ -99,12 +102,8 @@ class Serializeable
     const std::string &name() const { return objName; }
 
     virtual void nameChildren() {}
-    virtual void serialize() {}
-    virtual void unserialize(IniFile &db, const std::string &category,
-                             ConfigNode *node = NULL)
-    {
-        std::cout << name() << " is being unserialized" << std::endl;
-    }
+    virtual void serialize(std::ostream& os) {}
+    virtual void unserialize(IniFile &db, const std::string &section) {}
 };
 
 class Serializer
@@ -131,17 +130,6 @@ class Serializer
     const std::string &filename() const { return file; }
 };
 
-template <class T>
-inline void
-Serializeable::paramOut(const std::string &name, const T& param)
-{
-    out() << name << "=" << param << "\n";
-}
-
-template <> void
-Serializeable::paramOut(const std::string &name, const uint64_t& param);
-
-
 //
 // A SerializeableBuilder serves as an evaluation context for a set of
 // parameters that describe a specific instance of a Serializeable.  This