SLICC: Use pointers for directory entries

SLICC uses pointers for cache and TBE entries but not for directory entries.
This patch changes the protocols, SLICC and Ruby memory system so that even
directory entries are referenced using pointers.

--HG--
extra : rebase_source : abeb4ac78033d003153751f216fd1948251fcfad
This commit is contained in:
Nilay Vaish 2011-12-31 16:38:30 -06:00
parent 19e65a6502
commit 734ef9a209
14 changed files with 112 additions and 62 deletions

View file

@ -110,8 +110,16 @@ machine(Directory, "MESI_CMP_filter_directory protocol")
void set_tbe(TBE tbe);
void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
return static_cast(Entry, directory[addr]);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
if (is_valid(dir_entry)) {
return dir_entry;
}
dir_entry := static_cast(Entry, "pointer",
directory.allocate(addr, new Entry));
return dir_entry;
}
State getState(TBE tbe, Address addr) {

View file

@ -79,8 +79,16 @@ machine(Directory, "Directory protocol")
void set_tbe(TBE b);
void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
return static_cast(Entry, directory[addr]);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
if (is_valid(dir_entry)) {
return dir_entry;
}
dir_entry := static_cast(Entry, "pointer",
directory.allocate(addr, new Entry));
return dir_entry;
}
State getState(TBE tbe, Address addr) {

View file

@ -126,8 +126,16 @@ machine(Directory, "Directory protocol")
void set_tbe(TBE b);
void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
return static_cast(Entry, directory[addr]);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
if (is_valid(dir_entry)) {
return dir_entry;
}
dir_entry := static_cast(Entry, "pointer",
directory.allocate(addr, new Entry));
return dir_entry;
}
State getState(TBE tbe, Address addr) {

View file

@ -165,8 +165,16 @@ machine(Directory, "Token protocol")
void set_tbe(TBE b);
void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
return static_cast(Entry, directory[addr]);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
if (is_valid(dir_entry)) {
return dir_entry;
}
dir_entry := static_cast(Entry, "pointer",
directory.allocate(addr, new Entry));
return dir_entry;
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {

View file

@ -186,8 +186,16 @@ machine(Directory, "AMD Hammer-like protocol")
TBETable TBEs, template_hack="<Directory_TBE>";
Entry getDirectoryEntry(Address addr), return_by_ref="yes" {
return static_cast(Entry, directory[addr]);
Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);
if (is_valid(dir_entry)) {
return dir_entry;
}
dir_entry := static_cast(Entry, "pointer",
directory.allocate(addr, new Entry));
return dir_entry;
}
DataBlock getDataBlock(Address addr), return_by_ref="yes" {

View file

@ -125,6 +125,7 @@ structure(AbstractEntry, primitive="yes", external = "yes") {
}
structure (DirectoryMemory, external = "yes") {
AbstractEntry allocate(Address, AbstractEntry);
AbstractEntry lookup(Address);
bool isPresent(Address);
void invalidateBlock(Address);

View file

@ -59,7 +59,7 @@ DirectoryMemory::init()
if (m_use_map) {
m_sparseMemory = new SparseMemory(m_map_levels);
} else {
m_entries = new Directory_Entry*[m_num_entries];
m_entries = new AbstractEntry*[m_num_entries];
for (int i = 0; i < m_num_entries; i++)
m_entries[i] = NULL;
m_ram = g_system_ptr->getMemoryVector();
@ -150,38 +150,40 @@ DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
return ret >> (RubySystem::getBlockSizeBits());
}
Directory_Entry&
AbstractEntry*
DirectoryMemory::lookup(PhysAddress address)
{
assert(isPresent(address));
Directory_Entry* entry;
DPRINTF(RubyCache, "Looking up address: %s\n", address);
if (m_use_map) {
return m_sparseMemory->lookup(address);
} else {
uint64_t idx = mapAddressToLocalIdx(address);
assert(idx < m_num_entries);
return m_entries[idx];
}
}
AbstractEntry*
DirectoryMemory::allocate(const PhysAddress& address, AbstractEntry* entry)
{
assert(isPresent(address));
uint64 idx;
DPRINTF(RubyCache, "Looking up address: %s\n", address);
if (m_use_map) {
if (m_sparseMemory->exist(address)) {
entry = m_sparseMemory->lookup(address);
assert(entry != NULL);
} else {
// Note: SparseMemory internally creates a new Directory Entry
m_sparseMemory->add(address);
entry = m_sparseMemory->lookup(address);
entry->changePermission(AccessPermission_Read_Write);
}
m_sparseMemory->add(address, entry);
entry->changePermission(AccessPermission_Read_Write);
} else {
idx = mapAddressToLocalIdx(address);
assert(idx < m_num_entries);
entry = m_entries[idx];
if (entry == NULL) {
entry = new Directory_Entry();
entry->getDataBlk().assign(m_ram->getBlockPtr(address));
entry->changePermission(AccessPermission_Read_Only);
m_entries[idx] = entry;
}
entry->getDataBlk().assign(m_ram->getBlockPtr(address));
entry->changePermission(AccessPermission_Read_Only);
m_entries[idx] = entry;
}
return *entry;
return entry;
}
void

View file

@ -32,9 +32,9 @@
#include <iostream>
#include <string>
#include "mem/protocol/Directory_Entry.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/AbstractEntry.hh"
#include "mem/ruby/system/MemoryVector.hh"
#include "mem/ruby/system/SparseMemory.hh"
#include "params/RubyDirectoryMemory.hh"
@ -58,7 +58,9 @@ class DirectoryMemory : public SimObject
void printConfig(std::ostream& out) const;
static void printGlobalConfig(std::ostream & out);
bool isPresent(PhysAddress address);
Directory_Entry& lookup(PhysAddress address);
AbstractEntry* lookup(PhysAddress address);
AbstractEntry* allocate(const PhysAddress& address,
AbstractEntry* new_entry);
void invalidateBlock(PhysAddress address);
@ -72,7 +74,7 @@ class DirectoryMemory : public SimObject
private:
const std::string m_name;
Directory_Entry **m_entries;
AbstractEntry **m_entries;
// int m_size; // # of memory module blocks this directory is
// responsible for
uint64 m_size_bytes;

View file

@ -92,9 +92,7 @@ SparseMemory::recursivelyRemoveTables(SparseMapType* curTable, int curLevel)
delete nextTable;
} else {
// If at the last level, delete the directory entry
Directory_Entry* dirEntry;
dirEntry = (Directory_Entry*)(entryStruct->entry);
delete dirEntry;
delete (AbstractEntry*)(entryStruct->entry);
}
entryStruct->entry = NULL;
}
@ -149,7 +147,7 @@ SparseMemory::exist(const Address& address) const
// add an address to memory
void
SparseMemory::add(const Address& address)
SparseMemory::add(const Address& address, AbstractEntry* entry)
{
assert(address == line_address(address));
assert(!exist(address));
@ -187,9 +185,8 @@ SparseMemory::add(const Address& address)
// if the last level, add a directory entry. Otherwise add a map.
if (level == (m_number_of_levels - 1)) {
Directory_Entry* tempDirEntry = new Directory_Entry();
tempDirEntry->getDataBlk().clear();
newEntry = (void*)tempDirEntry;
entry->getDataBlk().clear();
newEntry = (void*)entry;
} else {
SparseMapType* tempMap = new SparseMapType;
newEntry = (void*)(tempMap);
@ -262,10 +259,8 @@ SparseMemory::recursivelyRemoveLevels(const Address& address,
// if this is the last level, we have reached the Directory
// Entry and thus we should delete it including the
// SparseMemEntry container struct.
Directory_Entry* dirEntry;
dirEntry = (Directory_Entry*)(entryStruct->entry);
delete (AbstractEntry*)(entryStruct->entry);
entryStruct->entry = NULL;
delete dirEntry;
curInfo.curTable->erase(curAddress);
m_removes_per_level[curInfo.level]++;
}
@ -303,17 +298,14 @@ SparseMemory::remove(const Address& address)
}
// looks an address up in memory
Directory_Entry*
AbstractEntry*
SparseMemory::lookup(const Address& address)
{
assert(exist(address));
assert(address == line_address(address));
DPRINTF(RubyCache, "address: %s\n", address);
Address curAddress;
SparseMapType* curTable = m_map_head;
Directory_Entry* entry = NULL;
AbstractEntry* entry = NULL;
// Initiallize the high bit to be the total number of bits plus
// the block offset. However the highest bit index is one less
@ -336,13 +328,18 @@ SparseMemory::lookup(const Address& address)
// Adjust the highBit value for the next level
highBit -= m_number_of_bits_per_level[level];
// The entry should be in the table and valid
curTable = (SparseMapType*)(((*curTable)[curAddress]).entry);
assert(curTable != NULL);
// If the address is found, move on to the next level.
// Otherwise, return not found
if (curTable->count(curAddress) != 0) {
curTable = (SparseMapType*)(((*curTable)[curAddress]).entry);
} else {
DPRINTF(RubyCache, "Not found\n");
return NULL;
}
}
// The last entry actually points to the Directory entry not a table
entry = (Directory_Entry*)curTable;
entry = (AbstractEntry*)curTable;
return entry;
}

View file

@ -32,7 +32,7 @@
#include <iostream>
#include "base/hashmap.hh"
#include "mem/protocol/Directory_Entry.hh"
#include "mem/ruby/slicc_interface/AbstractEntry.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Global.hh"
@ -60,10 +60,10 @@ class SparseMemory
void printConfig(std::ostream& out) { }
bool exist(const Address& address) const;
void add(const Address& address);
void add(const Address& address, AbstractEntry*);
void remove(const Address& address);
Directory_Entry* lookup(const Address& address);
AbstractEntry* lookup(const Address& address);
// Print cache contents
void print(std::ostream& out) const;

View file

@ -52,8 +52,9 @@ class FormalParamAST(AST):
self.pairs)
self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or (
"interface" in type and type["interface"] == "AbstractCacheEntry"):
"interface" in type and (
type["interface"] == "AbstractCacheEntry" or
type["interface"] == "AbstractEntry")):
return type, "%s* %s" % (type.c_ident, param)
else:
return type, "const %s& %s" % (type.c_ident, param)

View file

@ -52,7 +52,9 @@ class LocalVariableAST(StatementAST):
self.pairs)
self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or (
"interface" in type and type["interface"] == "AbstractCacheEntry"):
"interface" in type and (
type["interface"] == "AbstractCacheEntry" or
type["interface"] == "AbstractEntry")):
code += "%s* %s" % (type.c_ident, ident)
else:
code += "%s %s" % (type.c_ident, ident)

View file

@ -41,7 +41,10 @@ class MemberExprAST(ExprAST):
return_type, gcode = self.expr_ast.inline(True)
fix = code.nofix()
if str(return_type) == "TBE" or ("interface" in return_type and return_type["interface"] == "AbstractCacheEntry"):
if str(return_type) == "TBE" \
or ("interface" in return_type and
(return_type["interface"] == "AbstractCacheEntry" or
return_type["interface"] == "AbstractEntry")):
code("(*$gcode).m_${{self.field}}")
else:
code("($gcode).m_${{self.field}}")

View file

@ -162,8 +162,10 @@ class MemberMethodCallExprAST(MethodCallExprAST):
prefix = "static_cast<%s &>" % return_type.c_ident
if str(obj_type) == "AbstractCacheEntry" or \
("interface" in obj_type and
obj_type["interface"] == "AbstractCacheEntry"):
str(obj_type) == "AbstractEntry" or \
("interface" in obj_type and (
obj_type["interface"] == "AbstractCacheEntry" or
obj_type["interface"] == "AbstractEntry")):
prefix = "%s((*(%s))." % (prefix, code)
else:
prefix = "%s((%s)." % (prefix, code)