Backed out changeset 94a7bb476fca: caused memory leak.
This commit is contained in:
parent
6b45238316
commit
caaac16803
17 changed files with 57 additions and 87 deletions
|
@ -80,8 +80,8 @@ class DefaultFetch
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Default constructor. */
|
/** Default constructor. */
|
||||||
IcachePort(DefaultFetch<Impl> *_fetch, O3CPU *_cpu)
|
IcachePort(DefaultFetch<Impl> *_fetch)
|
||||||
: Port(_fetch->name() + "-iport", _cpu), fetch(_fetch)
|
: Port(_fetch->name() + "-iport"), fetch(_fetch)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool snoopRangeSent;
|
bool snoopRangeSent;
|
||||||
|
|
|
@ -167,7 +167,7 @@ DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, Params *params)
|
||||||
instSize = sizeof(TheISA::MachInst);
|
instSize = sizeof(TheISA::MachInst);
|
||||||
|
|
||||||
// Name is finally available, so create the port.
|
// Name is finally available, so create the port.
|
||||||
icachePort = new IcachePort(this, cpu);
|
icachePort = new IcachePort(this);
|
||||||
|
|
||||||
icachePort->snoopRangeSent = false;
|
icachePort->snoopRangeSent = false;
|
||||||
|
|
||||||
|
|
|
@ -296,8 +296,8 @@ class LSQ {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Default constructor. */
|
/** Default constructor. */
|
||||||
DcachePort(LSQ *_lsq, O3CPU *_cpu)
|
DcachePort(LSQ *_lsq)
|
||||||
: Port(_lsq->name() + "-dport", _cpu), lsq(_lsq)
|
: Port(_lsq->name() + "-dport"), lsq(_lsq)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool snoopRangeSent;
|
bool snoopRangeSent;
|
||||||
|
|
|
@ -112,7 +112,7 @@ LSQ<Impl>::DcachePort::recvRetry()
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params)
|
LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params)
|
||||||
: cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this, cpu_ptr),
|
: cpu(cpu_ptr), iewStage(iew_ptr), dcachePort(this),
|
||||||
LQEntries(params->LQEntries),
|
LQEntries(params->LQEntries),
|
||||||
SQEntries(params->SQEntries),
|
SQEntries(params->SQEntries),
|
||||||
numThreads(params->numberOfThreads),
|
numThreads(params->numberOfThreads),
|
||||||
|
|
|
@ -103,6 +103,7 @@ void
|
||||||
O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
|
O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
|
||||||
{
|
{
|
||||||
if (vp != thread->getVirtPort()) {
|
if (vp != thread->getVirtPort()) {
|
||||||
|
vp->removeConn();
|
||||||
delete vp;
|
delete vp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -747,6 +747,7 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
|
OzoneCPU<Impl>::OzoneTC::delVirtPort(VirtualPort *vp)
|
||||||
{
|
{
|
||||||
|
vp->removeConn();
|
||||||
delete vp;
|
delete vp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -302,6 +302,7 @@ void
|
||||||
SimpleThread::delVirtPort(VirtualPort *vp)
|
SimpleThread::delVirtPort(VirtualPort *vp)
|
||||||
{
|
{
|
||||||
if (vp != virtPort) {
|
if (vp != virtPort) {
|
||||||
|
vp->removeConn();
|
||||||
delete vp;
|
delete vp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ ThreadState::connectPhysPort()
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
// already existed. Fix this memory leak once the bus port IDs
|
||||||
// for functional ports is resolved.
|
// for functional ports is resolved.
|
||||||
if (physPort)
|
if (physPort)
|
||||||
physPort->disconnectFromPeer();
|
physPort->removeConn();
|
||||||
else
|
else
|
||||||
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
|
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
|
||||||
baseCpu->name(), tid));
|
baseCpu->name(), tid));
|
||||||
|
@ -140,7 +140,7 @@ ThreadState::connectVirtPort()
|
||||||
// already existed. Fix this memory leak once the bus port IDs
|
// already existed. Fix this memory leak once the bus port IDs
|
||||||
// for functional ports is resolved.
|
// for functional ports is resolved.
|
||||||
if (virtPort)
|
if (virtPort)
|
||||||
virtPort->disconnectFromPeer();
|
virtPort->removeConn();
|
||||||
else
|
else
|
||||||
virtPort = new VirtualPort(csprintf("%s-%d-vport",
|
virtPort = new VirtualPort(csprintf("%s-%d-vport",
|
||||||
baseCpu->name(), tid));
|
baseCpu->name(), tid));
|
||||||
|
|
|
@ -47,7 +47,7 @@ Bridge::BridgePort::BridgePort(const std::string &_name,
|
||||||
int _delay, int _nack_delay, int _req_limit,
|
int _delay, int _nack_delay, int _req_limit,
|
||||||
int _resp_limit,
|
int _resp_limit,
|
||||||
std::vector<Range<Addr> > filter_ranges)
|
std::vector<Range<Addr> > filter_ranges)
|
||||||
: Port(_name, _bridge), bridge(_bridge), otherPort(_otherPort),
|
: Port(_name), bridge(_bridge), otherPort(_otherPort),
|
||||||
delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
|
delay(_delay), nackDelay(_nack_delay), filterRanges(filter_ranges),
|
||||||
outstandingResponses(0), queuedRequests(0), inRetry(false),
|
outstandingResponses(0), queuedRequests(0), inRetry(false),
|
||||||
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
|
reqQueueLimit(_req_limit), respQueueLimit(_resp_limit), sendEvent(this)
|
||||||
|
|
|
@ -72,8 +72,8 @@ Bus::getPort(const std::string &if_name, int idx)
|
||||||
return bp;
|
return bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
Bus::deletePort(Port *p)
|
Bus::deletePortRefs(Port *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
BusPort *bp = dynamic_cast<BusPort*>(p);
|
BusPort *bp = dynamic_cast<BusPort*>(p);
|
||||||
|
@ -81,11 +81,10 @@ Bus::deletePort(Port *p)
|
||||||
panic("Couldn't convert Port* to BusPort*\n");
|
panic("Couldn't convert Port* to BusPort*\n");
|
||||||
// If this is our one functional port
|
// If this is our one functional port
|
||||||
if (funcPort == bp)
|
if (funcPort == bp)
|
||||||
return false;
|
return;
|
||||||
interfaces.erase(bp->getId());
|
interfaces.erase(bp->getId());
|
||||||
clearBusCache();
|
clearBusCache();
|
||||||
delete bp;
|
delete bp;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the ranges of anyone other buses that we are connected to. */
|
/** Get the ranges of anyone other buses that we are connected to. */
|
||||||
|
|
|
@ -364,7 +364,7 @@ class Bus : public MemObject
|
||||||
|
|
||||||
/** A function used to return the port associated with this bus object. */
|
/** A function used to return the port associated with this bus object. */
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||||
virtual bool deletePort(Port *p);
|
virtual void deletePortRefs(Port *p);
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void startup();
|
virtual void startup();
|
||||||
|
|
2
src/mem/cache/cache.hh
vendored
2
src/mem/cache/cache.hh
vendored
|
@ -217,7 +217,7 @@ class Cache : public BaseCache
|
||||||
Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher);
|
Cache(const Params *p, TagStore *tags, BasePrefetcher *prefetcher);
|
||||||
|
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
virtual Port *getPort(const std::string &if_name, int idx = -1);
|
||||||
virtual bool deletePort(Port *p);
|
virtual void deletePortRefs(Port *p);
|
||||||
|
|
||||||
void regStats();
|
void regStats();
|
||||||
|
|
||||||
|
|
5
src/mem/cache/cache_impl.hh
vendored
5
src/mem/cache/cache_impl.hh
vendored
|
@ -105,14 +105,13 @@ Cache<TagStore>::getPort(const std::string &if_name, int idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TagStore>
|
template<class TagStore>
|
||||||
bool
|
void
|
||||||
Cache<TagStore>::deletePort(Port *p)
|
Cache<TagStore>::deletePortRefs(Port *p)
|
||||||
{
|
{
|
||||||
if (cpuSidePort == p || memSidePort == p)
|
if (cpuSidePort == p || memSidePort == p)
|
||||||
panic("Can only delete functional ports\n");
|
panic("Can only delete functional ports\n");
|
||||||
|
|
||||||
delete p;
|
delete p;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ MemObject::makeParams(const std::string &name)
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
MemObject::deletePort(Port *p)
|
MemObject::deletePortRefs(Port *p)
|
||||||
{
|
{
|
||||||
panic("This object does not support port deletion\n");
|
panic("This object does not support port deletion\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,13 +64,9 @@ class MemObject : public SimObject
|
||||||
/** Additional function to return the Port of a memory object. */
|
/** Additional function to return the Port of a memory object. */
|
||||||
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
|
virtual Port *getPort(const std::string &if_name, int idx = -1) = 0;
|
||||||
|
|
||||||
/** Tell MemObject that this port is no longer in use, so it
|
/** Tell object that this port is about to disappear, so it should remove it
|
||||||
* should remove it from any structures that it's keeping it in.
|
* from any structures that it's keeping it in. */
|
||||||
* If the port was allocated dynamically for this connection, it
|
virtual void deletePortRefs(Port *p) ;
|
||||||
* should be deleted here.
|
|
||||||
* @return True if the port was deleted, false if it still exists.
|
|
||||||
*/
|
|
||||||
virtual bool deletePort(Port *p);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__MEM_MEM_OBJECT_HH__
|
#endif //__MEM_MEM_OBJECT_HH__
|
||||||
|
|
|
@ -39,25 +39,17 @@
|
||||||
#include "mem/mem_object.hh"
|
#include "mem/mem_object.hh"
|
||||||
#include "mem/port.hh"
|
#include "mem/port.hh"
|
||||||
|
|
||||||
/**
|
|
||||||
* Special class for port objects that are used as peers for
|
|
||||||
* unconnected ports. Assigning instances of this class to newly
|
|
||||||
* allocated ports allows us to guarantee that every port has a peer
|
|
||||||
* object (so there's no need to check for null peer pointers), while
|
|
||||||
* catching uses of unconnected ports.
|
|
||||||
*/
|
|
||||||
class DefaultPeerPort : public Port
|
class DefaultPeerPort : public Port
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void blowUp()
|
void blowUp()
|
||||||
{
|
{
|
||||||
Port *peer = getPeer();
|
fatal("%s: Unconnected port!", peer->name());
|
||||||
fatal("unconnected port: %s", peer ? peer->name() : "<unknown>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DefaultPeerPort(Port *_peer)
|
DefaultPeerPort()
|
||||||
: Port("default_port", NULL, _peer)
|
: Port("default_port")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool recvTiming(PacketPtr)
|
bool recvTiming(PacketPtr)
|
||||||
|
@ -96,61 +88,38 @@ class DefaultPeerPort : public Port
|
||||||
bool isDefaultPort() const { return true; }
|
bool isDefaultPort() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DefaultPeerPort defaultPeerPort;
|
||||||
|
|
||||||
Port::Port(const std::string &_name, MemObject *_owner, Port *_peer) :
|
Port::Port()
|
||||||
portName(_name),
|
: peer(&defaultPeerPort), owner(NULL)
|
||||||
peer(_peer ? _peer : new DefaultPeerPort(this)),
|
{
|
||||||
owner(_owner)
|
}
|
||||||
|
|
||||||
|
Port::Port(const std::string &_name, MemObject *_owner)
|
||||||
|
: portName(_name), peer(&defaultPeerPort), owner(_owner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Port::~Port()
|
Port::~Port()
|
||||||
{
|
{
|
||||||
disconnectFromPeer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Port::disconnectFromPeer()
|
|
||||||
{
|
|
||||||
if (peer) {
|
|
||||||
assert(peer->getPeer() == this);
|
|
||||||
peer->disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Port::disconnect()
|
|
||||||
{
|
|
||||||
// This notification should come only from our peer, so we must
|
|
||||||
// have one,
|
|
||||||
assert(peer != NULL);
|
|
||||||
// We must clear 'peer' here, else if owner->deletePort() calls
|
|
||||||
// delete on us then we'll recurse infinitely through the Port
|
|
||||||
// destructor.
|
|
||||||
peer = NULL;
|
|
||||||
// If owner->deletePort() returns true, then we've been deleted,
|
|
||||||
// so don't do anything but get out of here. If not, reset peer
|
|
||||||
// pointer to a DefaultPeerPort.
|
|
||||||
if (!(owner && owner->deletePort(this)))
|
|
||||||
peer = new DefaultPeerPort(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Port::setPeer(Port *port)
|
Port::setPeer(Port *port)
|
||||||
{
|
{
|
||||||
DPRINTF(Config, "setting peer to %s, old peer %s\n",
|
DPRINTF(Config, "setting peer to %s\n", port->name());
|
||||||
port->name(), peer ? peer->name() : "<null>");
|
|
||||||
|
|
||||||
// You'd think we'd want to disconnect from the previous peer
|
|
||||||
// here, but it turns out that with some functional ports the old
|
|
||||||
// peer keeps using the connection, and it works because
|
|
||||||
// functional ports are unidirectional.
|
|
||||||
//
|
|
||||||
// disconnectFromPeer();
|
|
||||||
|
|
||||||
peer = port;
|
peer = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Port::removeConn()
|
||||||
|
{
|
||||||
|
if (peer->getOwner())
|
||||||
|
peer->getOwner()->deletePortRefs(peer);
|
||||||
|
peer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
|
Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,14 +87,17 @@ class Port
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Port();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param _name Port name for DPRINTF output. Should include name
|
* @param _name Port name for DPRINTF output. Should include name
|
||||||
* of memory system object to which the port belongs.
|
* of memory system object to which the port belongs.
|
||||||
* @param _owner Pointer to the MemObject that owns this port.
|
* @param _owner Pointer to the MemObject that owns this port.
|
||||||
|
* Will not necessarily be set.
|
||||||
*/
|
*/
|
||||||
Port(const std::string &_name, MemObject *_owner, Port *_peer = NULL);
|
Port(const std::string &_name, MemObject *_owner = NULL);
|
||||||
|
|
||||||
/** Return port name (for DPRINTF). */
|
/** Return port name (for DPRINTF). */
|
||||||
const std::string &name() const { return portName; }
|
const std::string &name() const { return portName; }
|
||||||
|
@ -108,18 +111,24 @@ class Port
|
||||||
RangeChange
|
RangeChange
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void setName(const std::string &name)
|
||||||
|
{ portName = name; }
|
||||||
|
|
||||||
/** Function to set the pointer for the peer port. */
|
/** Function to set the pointer for the peer port. */
|
||||||
virtual void setPeer(Port *port);
|
virtual void setPeer(Port *port);
|
||||||
|
|
||||||
/** Function to get the pointer to the peer port. */
|
/** Function to get the pointer to the peer port. */
|
||||||
Port *getPeer() { return peer; }
|
Port *getPeer() { return peer; }
|
||||||
|
|
||||||
|
/** Function to set the owner of this port. */
|
||||||
|
void setOwner(MemObject *_owner) { owner = _owner; }
|
||||||
|
|
||||||
/** Function to return the owner of this port. */
|
/** Function to return the owner of this port. */
|
||||||
MemObject *getOwner() { return owner; }
|
MemObject *getOwner() { return owner; }
|
||||||
|
|
||||||
/** Notify my peer port that I'm disconnecting (by calling its
|
/** Inform the peer port to delete itself and notify it's owner about it's
|
||||||
* disconnect() method) so it can clean up. */
|
* demise. */
|
||||||
void disconnectFromPeer();
|
void removeConn();
|
||||||
|
|
||||||
virtual bool isDefaultPort() const { return false; }
|
virtual bool isDefaultPort() const { return false; }
|
||||||
|
|
||||||
|
@ -245,11 +254,6 @@ class Port
|
||||||
/** Internal helper function for read/writeBlob().
|
/** Internal helper function for read/writeBlob().
|
||||||
*/
|
*/
|
||||||
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
|
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd);
|
||||||
|
|
||||||
/** Receive notification that my peer is disconnecting and clean
|
|
||||||
* up (potentially deleting myself in the process). Should be
|
|
||||||
* called only from peer's disconnectFromPeer(). */
|
|
||||||
void disconnect();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A simple functional port that is only meant for one way communication to
|
/** A simple functional port that is only meant for one way communication to
|
||||||
|
|
Loading…
Reference in a new issue