merge from head

--HG--
extra : convert_revision : 21f7afe2719c00744c0981212c1ee6e442238e01
This commit is contained in:
Steve Reinhardt 2007-08-03 03:51:30 -04:00
commit 3afc625975
23 changed files with 252 additions and 140 deletions

View file

@ -134,6 +134,9 @@ if len(bm) == 2:
drive_sys = makeSparcSystem(drive_mem_mode, bm[1])
drive_sys.cpu = DriveCPUClass(cpu_id=0)
drive_sys.cpu.connectMemPorts(drive_sys.membus)
if options.kernel is not None:
drive_sys.kernel = binary(options.kernel)
root = makeDualRoot(test_sys, drive_sys, options.etherdump)
elif len(bm) == 1:
root = Root(system=test_sys)

View file

@ -64,7 +64,7 @@ if args:
process = LiveProcess()
process.executable = options.cmd
process.cmd = options.cmd + " " + options.options
process.cmd = [options.cmd] + options.options.split()
if options.input != "":
process.input = options.input

View file

@ -57,7 +57,7 @@ class ThreadInfo
* thread_info struct. So we can get the address by masking off
* the lower 14 bits.
*/
current = tc->readIntReg(TheISA::StackPointerReg) & ~0x3fff;
current = tc->readIntReg(TheISA::StackPointerReg) & ~ULL(0x3fff);
return VPtr<thread_info>(tc, current);
}

View file

@ -73,7 +73,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
base = NUM_INTREGS;
//In -this- special case, we don't use an index.
if (machInst.sib.index == INTREG_RSP)
if (index == INTREG_RSP)
index = NUM_INTREGS;
} else {
if (machInst.addrSize == 2) {
@ -82,11 +82,9 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
scale = 0;
base = machInst.modRM.rm | (machInst.rex.b << 3);
if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
base = NUM_INTREGS;
//Since we need to use a different encoding of this
//instruction anyway, just ignore the base in those cases
// if (machInst.mode.submode == SixtyFourBitMode)
// base = NUM_INTREGS+7;
base = NUM_INTREGS;
}
}
}

View file

@ -167,7 +167,7 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
filename = argv[0];
//We want 16 byte alignment
Addr alignmentMask = ~mask(4);
uint64_t align = 16;
// load object file into target memory
objFile->loadSections(initVirtMem);
@ -285,47 +285,35 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
//Figure out how big the initial stack needs to be
// The unaccounted for 0 at the top of the stack
int mysterious_size = intSize;
// A sentry NULL void pointer at the top of the stack.
int sentry_size = intSize;
//This is the name of the file which is present on the initial stack
//It's purpose is to let the user space linker examine the original file.
int file_name_size = filename.size();
int file_name_size = filename.size() + 1;
string platform = "x86_64";
int aux_data_size = platform.size() + 1;
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size();
env_data_size += envp[i].size() + 1;
}
int arg_data_size = 0;
for (int i = 0; i < argv.size(); ++i) {
arg_data_size += argv[i].size();
arg_data_size += argv[i].size() + 1;
}
//The auxiliary vector data needs to be padded so it's size is a multiple
//of the alignment mask.
int aux_padding =
((aux_data_size + ~alignmentMask) & alignmentMask) - aux_data_size;
//The info_block needs to be padded so it's size is a multiple of the
//alignment mask. Also, it appears that there needs to be at least some
//padding, so if the size is already a multiple, we need to increase it
//anyway.
int info_block_size =
(mysterious_size +
file_name_size +
env_data_size +
arg_data_size +
~alignmentMask) & alignmentMask;
int base_info_block_size =
sentry_size + file_name_size + env_data_size + arg_data_size;
int info_block_padding =
info_block_size -
mysterious_size -
file_name_size -
env_data_size -
arg_data_size;
int info_block_size = roundUp(base_info_block_size, align);
int info_block_padding = info_block_size - base_info_block_size;
//Each auxilliary vector is two 8 byte words
int aux_array_size = intSize * 2 * (auxv.size() + 1);
@ -335,17 +323,27 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
int argc_size = intSize;
int space_needed =
info_block_size +
aux_data_size +
aux_padding +
//Figure out the size of the contents of the actual initial frame
int frame_size =
aux_array_size +
envp_array_size +
argv_array_size +
argc_size;
//There needs to be padding after the auxiliary vector data so that the
//very bottom of the stack is aligned properly.
int partial_size = frame_size + aux_data_size;
int aligned_partial_size = roundUp(partial_size, align);
int aux_padding = aligned_partial_size - partial_size;
int space_needed =
info_block_size +
aux_data_size +
aux_padding +
frame_size;
stack_min = stack_base - space_needed;
stack_min &= alignmentMask;
stack_min = roundDown(stack_min, align);
stack_size = stack_base - stack_min;
// map memory
@ -353,11 +351,11 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
roundUp(stack_size, pageSize));
// map out initial stack contents
Addr mysterious_base = stack_base - mysterious_size;
Addr file_name_base = mysterious_base - file_name_size;
Addr sentry_base = stack_base - sentry_size;
Addr file_name_base = sentry_base - file_name_size;
Addr env_data_base = file_name_base - env_data_size;
Addr arg_data_base = env_data_base - arg_data_size;
Addr aux_data_base = arg_data_base - aux_data_size - info_block_padding;
Addr aux_data_base = arg_data_base - info_block_padding - aux_data_size;
Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding;
Addr envp_array_base = auxv_array_base - envp_array_size;
Addr argv_array_base = envp_array_base - argv_array_size;
@ -380,10 +378,10 @@ X86LiveProcess::argsInit(int intSize, int pageSize)
uint64_t argc = argv.size();
uint64_t guestArgc = TheISA::htog(argc);
//Write out the mysterious 0
uint64_t mysterious_zero = 0;
initVirtMem->writeBlob(mysterious_base,
(uint8_t*)&mysterious_zero, mysterious_size);
//Write out the sentry void *
uint64_t sentry_NULL = 0;
initVirtMem->writeBlob(sentry_base,
(uint8_t*)&sentry_NULL, sentry_size);
//Write the file name
initVirtMem->writeString(file_name_base, filename.c_str());

View file

@ -87,7 +87,7 @@ OutputDirectory::resolve(const string &name)
}
ostream *
OutputDirectory::create(const string &name)
OutputDirectory::create(const string &name, bool binary)
{
if (name == "cerr" || name == "stderr")
return &cerr;
@ -95,7 +95,8 @@ OutputDirectory::create(const string &name)
if (name == "cout" || name == "stdout")
return &cout;
ofstream *file = new ofstream(resolve(name).c_str(), ios::trunc);
ofstream *file = new ofstream(resolve(name).c_str(),
ios::trunc | binary ? ios::binary : (ios::openmode)0);
if (!file->is_open())
panic("Cannot open file %s", name);

View file

@ -51,7 +51,7 @@ class OutputDirectory
const std::string &directory();
std::string resolve(const std::string &name);
std::ostream *create(const std::string &name);
std::ostream *create(const std::string &name, bool binary = false);
std::ostream *find(const std::string &name);
static bool isFile(const std::ostream *os);

View file

@ -53,7 +53,6 @@ SwigSource('m5.internal', 'swig/core.i')
SwigSource('m5.internal', 'swig/debug.i')
SwigSource('m5.internal', 'swig/event.i')
SwigSource('m5.internal', 'swig/random.i')
SwigSource('m5.internal', 'swig/sim_object.i')
SwigSource('m5.internal', 'swig/stats.i')
SwigSource('m5.internal', 'swig/trace.i')
PySource('m5.internal', 'm5/internal/__init__.py')

View file

@ -274,17 +274,29 @@ class Generate(object):
print >>out
for obj in ordered_objs:
code = 'class %s ' % obj.cxx_class
if str(obj) != 'SimObject':
code += ': public %s ' % obj.__bases__[0]
code += '{};'
if obj.swig_objdecls:
for decl in obj.swig_objdecls:
print >>out, decl
continue
code = ''
base = obj.get_base()
code += '// stop swig from creating/wrapping default ctor/dtor\n'
code += '%%nodefault %s;\n' % obj.cxx_class
code += 'class %s ' % obj.cxx_class
if base:
code += ': public %s' % base
code += ' {};\n'
klass = obj.cxx_class;
if hasattr(obj, 'cxx_namespace'):
code = 'namespace %s { %s }' % (obj.cxx_namespace, code)
new_code = 'namespace %s {\n' % obj.cxx_namespace
new_code += code
new_code += '}\n'
code = new_code
klass = '%s::%s' % (obj.cxx_namespace, klass)
print >>out, '%%ignore %s;' % klass
print >>out, code
for obj in ordered_objs:

View file

@ -128,6 +128,7 @@ class MetaSimObject(type):
'cxx_class' : types.StringType,
'cxx_type' : types.StringType,
'cxx_predecls' : types.ListType,
'swig_objdecls' : types.ListType,
'swig_predecls' : types.ListType,
'type' : types.StringType }
# Attributes that can be set any time
@ -225,6 +226,9 @@ class MetaSimObject(type):
cls._value_dict['swig_predecls'] = \
cls._value_dict['cxx_predecls']
if 'swig_objdecls' not in cls._value_dict:
cls._value_dict['swig_objdecls'] = []
# Now process the _value_dict items. They could be defining
# new (or overriding existing) parameters or ports, setting
# class keywords (e.g., 'abstract'), or setting parameter
@ -345,12 +349,13 @@ class MetaSimObject(type):
def __str__(cls):
return cls.__name__
def cxx_decl(cls):
if str(cls) != 'SimObject':
base = cls.__bases__[0].type
else:
base = None
def get_base(cls):
if str(cls) == 'SimObject':
return None
return cls.__bases__[0].type
def cxx_decl(cls):
code = "#ifndef __PARAMS__%s\n" % cls
code += "#define __PARAMS__%s\n\n" % cls
@ -380,6 +385,7 @@ class MetaSimObject(type):
code += "\n".join(predecls2)
code += "\n\n";
base = cls.get_base()
if base:
code += '#include "params/%s.hh"\n\n' % base
@ -408,11 +414,7 @@ class MetaSimObject(type):
return code
def cxx_type_decl(cls):
if str(cls) != 'SimObject':
base = cls.__bases__[0]
else:
base = None
base = cls.get_base()
code = ''
if base:
@ -427,17 +429,14 @@ class MetaSimObject(type):
return code
def swig_decl(cls):
base = cls.get_base()
code = '%%module %s\n' % cls
code += '%{\n'
code += '#include "params/%s.hh"\n' % cls
code += '%}\n\n'
if str(cls) != 'SimObject':
base = cls.__bases__[0]
else:
base = None
# The 'dict' attribute restricts us to the params declared in
# the object itself, not including inherited params (which
# will also be inherited from the base class's param struct
@ -483,6 +482,7 @@ class SimObject(object):
abstract = True
name = Param.String("Object name")
swig_objdecls = [ '%include "python/swig/sim_object.i"' ]
# Initialize new instance. For objects with SimObject-valued
# children, we need to recursively clone the classes represented
@ -792,7 +792,6 @@ class SimObject(object):
# necessary to construct it. Does *not* recursively create
# children.
def getCCObject(self):
import internal
params = self.getCCParams()
if not self._ccObject:
self._ccObject = -1 # flag to catch cycles in recursion
@ -840,24 +839,19 @@ class SimObject(object):
if not isinstance(self, m5.objects.System):
return None
system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject)
return system_ptr.getMemoryMode()
return self._ccObject.getMemoryMode()
def changeTiming(self, mode):
import internal
if isinstance(self, m5.objects.System):
# i don't know if there's a better way to do this - calling
# setMemoryMode directly from self._ccObject results in calling
# SimObject::setMemoryMode, not the System::setMemoryMode
system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject)
system_ptr.setMemoryMode(mode)
self._ccObject.setMemoryMode(mode)
for child in self._children.itervalues():
child.changeTiming(mode)
def takeOverFrom(self, old_cpu):
import internal
cpu_ptr = internal.sim_object.convertToBaseCPUPtr(old_cpu._ccObject)
self._ccObject.takeOverFrom(cpu_ptr)
self._ccObject.takeOverFrom(old_cpu._ccObject)
# generate output file for 'dot' to display as a pretty graph.
# this code is currently broken.

View file

@ -81,11 +81,6 @@ try:
except ImportError:
running_m5 = False
if running_m5:
from event import *
from simulate import *
from main import options
if running_m5:
import defines
build_env.update(defines.m5_build_env)
@ -93,6 +88,11 @@ else:
import __scons
build_env.update(__scons.m5_build_env)
if running_m5:
from event import *
from simulate import *
from main import options
import SimObject
import params
import objects

View file

@ -30,6 +30,5 @@ import core
import debug
import event
import random
import sim_object
import stats
import trace

View file

@ -26,9 +26,15 @@
#
# Authors: Nathan Binkert
import code, optparse, os, socket, sys
from datetime import datetime
import code
import datetime
import optparse
import os
import socket
import sys
from attrdict import attrdict
import defines
import traceflags
__all__ = [ 'options', 'arguments', 'main' ]
@ -116,6 +122,8 @@ def bool_option(name, default, help):
# Help options
add_option('-A', "--authors", action="store_true", default=False,
help="Show author information")
add_option('-B', "--build-info", action="store_true", default=False,
help="Show build information")
add_option('-C', "--copyright", action="store_true", default=False,
help="Show full copyright information")
add_option('-R', "--readme", action="store_true", default=False,
@ -195,6 +203,22 @@ def main():
parse_args()
done = False
if options.build_info:
done = True
print 'Build information:'
print
print 'compiled %s' % internal.core.cvar.compileDate;
print 'started %s' % datetime.datetime.now().ctime()
print 'executing on %s' % socket.gethostname()
print 'build options:'
keys = defines.m5_build_env.keys()
keys.sort()
for key in keys:
val = defines.m5_build_env[key]
print ' %s = %s' % (key, val)
print
if options.copyright:
done = True
print info.LICENSE
@ -242,7 +266,7 @@ def main():
print brief_copyright
print
print "M5 compiled %s" % internal.core.cvar.compileDate;
print "M5 started %s" % datetime.now().ctime()
print "M5 started %s" % datetime.datetime.now().ctime()
print "M5 executing on %s" % socket.gethostname()
print "command line:",
for argv in sys.argv:

View file

@ -1025,13 +1025,13 @@ class PortRef(object):
# Call C++ to create corresponding port connection between C++ objects
def ccConnect(self):
import internal
from m5.objects.params import connectPorts
if self.ccConnected: # already done this
return
peer = self.peer
internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name,
self.index, peer.simobj.getCCObject(), peer.name, peer.index)
connectPorts(self.simobj.getCCObject(), self.name, self.index,
peer.simobj.getCCObject(), peer.name, peer.index)
self.ccConnected = True
peer.ccConnected = True

View file

@ -36,6 +36,7 @@ import internal
from main import options
import SimObject
import ticks
import objects
# The final hook to generate .ini files. Called from the user script
# once the config is built.
@ -58,10 +59,10 @@ def instantiate(root):
root.connectPorts()
# Do a second pass to finish initializing the sim objects
internal.sim_object.initAll()
internal.core.initAll()
# Do a third pass to initialize statistics
internal.sim_object.regAllStats()
internal.core.regAllStats()
# Check to make sure that the stats package is properly initialized
internal.stats.check()
@ -135,32 +136,32 @@ def checkpoint(root, dir):
raise TypeError, "Checkpoint must be called on a root object."
doDrain(root)
print "Writing checkpoint"
internal.sim_object.serializeAll(dir)
internal.core.serializeAll(dir)
resume(root)
def restoreCheckpoint(root, dir):
print "Restoring from checkpoint"
internal.sim_object.unserializeAll(dir)
internal.core.unserializeAll(dir)
need_resume.append(root)
def changeToAtomic(system):
if not isinstance(system, (objects.Root, objects.System)):
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
(type(system), objects.Root, objects.System)
if system.getMemoryMode() != internal.sim_object.SimObject.Atomic:
if system.getMemoryMode() != objects.params.SimObject.Atomic:
doDrain(system)
print "Changing memory mode to atomic"
system.changeTiming(internal.sim_object.SimObject.Atomic)
system.changeTiming(objects.params.SimObject.Atomic)
def changeToTiming(system):
if not isinstance(system, (objects.Root, objects.System)):
raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \
(type(system), objects.Root, objects.System)
if system.getMemoryMode() != internal.sim_object.SimObject.Timing:
if system.getMemoryMode() != objects.params.SimObject.Timing:
doDrain(system)
print "Changing memory mode to timing"
system.changeTiming(internal.sim_object.SimObject.Timing)
system.changeTiming(objects.params.SimObject.Timing)
def switchCpus(cpuList):
print "switching cpus"

View file

@ -58,6 +58,12 @@ void setClockFrequency(Tick ticksPerSecond);
%immutable curTick;
Tick curTick;
void serializeAll(const std::string &cpt_dir);
void unserializeAll(const std::string &cpt_dir);
void initAll();
void regAllStats();
%wrapper %{
// fix up module name to reflect the fact that it's inside the m5 package
#undef SWIG_name

View file

@ -47,26 +47,6 @@ void loadIniFile(PyObject *_resolveFunc);
int connectPorts(SimObject *o1, const std::string &name1, int i1,
SimObject *o2, const std::string &name2, int i2);
inline BaseCPU *
convertToBaseCPUPtr(SimObject *obj)
{
BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);
if (ptr == NULL)
warn("Casting to BaseCPU pointer failed");
return ptr;
}
inline System *
convertToSystemPtr(SimObject *obj)
{
System *ptr = dynamic_cast<System *>(obj);
if (ptr == NULL)
warn("Casting to System pointer failed");
return ptr;
}
inline void
initAll()
{

View file

@ -31,7 +31,6 @@
%module sim_object
%{
#include "enums/MemoryMode.hh"
#include "python/swig/pyobject.hh"
%}
@ -57,31 +56,10 @@ class SimObject {
SimObject(const std::string &_name);
};
class System {
private:
System();
public:
Enums::MemoryMode getMemoryMode();
void setMemoryMode(Enums::MemoryMode mode);
};
int connectPorts(SimObject *o1, const std::string &name1, int i1,
SimObject *o2, const std::string &name2, int i2);
BaseCPU *convertToBaseCPUPtr(SimObject *obj);
System *convertToSystemPtr(SimObject *obj);
void serializeAll(const std::string &cpt_dir);
void unserializeAll(const std::string &cpt_dir);
void initAll();
void regAllStats();
%wrapper %{
// fix up module name to reflect the fact that it's inside the m5 package
#undef SWIG_name
#define SWIG_name "m5.internal._sim_object"
// Convert a pointer to the Python object that SWIG wraps around a
// C++ SimObject pointer back to the actual C++ pointer.
SimObject *

43
src/python/swig/system.i Normal file
View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Nathan Binkert
*/
%module sim_object
%include "enums/MemoryMode.hh"
class System : public SimObject
{
private:
System();
public:
Enums::MemoryMode getMemoryMode();
void setMemoryMode(Enums::MemoryMode mode);
};

View file

@ -36,6 +36,8 @@ class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing']
class System(SimObject):
type = 'System'
swig_objdecls = [ '%include "python/swig/system.i"' ]
physmem = Param.PhysicalMemory(Parent.any, "phsyical memory")
mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in")
if build_env['FULL_SYSTEM']:

View file

@ -178,6 +178,22 @@ paramOut(ostream &os, const std::string &name, const T &param)
os << "\n";
}
template <class T>
void
arrayParamOut(ostream &os, const std::string &name,
const std::vector<T> &param)
{
int size = param.size();
os << name << "=";
if (size > 0)
showParam(os, param[0]);
for (int i = 1; i < size; ++i) {
os << " ";
showParam(os, param[i]);
}
os << "\n";
}
template <class T>
void
@ -251,6 +267,49 @@ arrayParamIn(Checkpoint *cp, const std::string &section,
}
}
template <class T>
void
arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, std::vector<T> &param)
{
std::string str;
if (!cp->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());
param.resize(tokens.size());
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;
}
}
void
objParamIn(Checkpoint *cp, const std::string &section,
@ -273,7 +332,13 @@ arrayParamOut(ostream &os, const std::string &name, \
type const *param, int size); \
template void \
arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, type *param, int size);
const std::string &name, type *param, int size); \
template void \
arrayParamOut(ostream &os, const std::string &name, \
const std::vector<type> &param); \
template void \
arrayParamIn(Checkpoint *cp, const std::string &section, \
const std::string &name, std::vector<type> &param);
INSTANTIATE_PARAM_TEMPLATES(signed char)
INSTANTIATE_PARAM_TEMPLATES(unsigned char)
@ -358,7 +423,6 @@ Serializable::unserializeAll(const std::string &cpt_dir)
dir);
Checkpoint *cp = new Checkpoint(dir, section);
unserializeGlobals(cp);
SimObject::unserializeAll(cp);
}

View file

@ -39,6 +39,7 @@
#include <list>
#include <vector>
#include <iostream>
#include <map>
@ -60,10 +61,18 @@ template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
const T *param, int size);
template <class T>
void arrayParamOut(std::ostream &os, const std::string &name,
const std::vector<T> &param);
template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, T *param, int size);
template <class T>
void arrayParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, std::vector<T> &param);
void
objParamIn(Checkpoint *cp, const std::string &section,
const std::string &name, SimObject * &param);

View file

@ -72,7 +72,8 @@ System::System(Params *p)
#if FULL_SYSTEM
kernelSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable;
if (!debugSymbolTable)
debugSymbolTable = new SymbolTable;
/**