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 set_tbe(TBE tbe);
void unset_tbe(); void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" { Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
return static_cast(Entry, directory[addr]); 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) { State getState(TBE tbe, Address addr) {

View file

@ -79,8 +79,16 @@ machine(Directory, "Directory protocol")
void set_tbe(TBE b); void set_tbe(TBE b);
void unset_tbe(); void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" { Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
return static_cast(Entry, directory[addr]); 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) { State getState(TBE tbe, Address addr) {

View file

@ -126,8 +126,16 @@ machine(Directory, "Directory protocol")
void set_tbe(TBE b); void set_tbe(TBE b);
void unset_tbe(); void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" { Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
return static_cast(Entry, directory[addr]); 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) { State getState(TBE tbe, Address addr) {

View file

@ -165,8 +165,16 @@ machine(Directory, "Token protocol")
void set_tbe(TBE b); void set_tbe(TBE b);
void unset_tbe(); void unset_tbe();
Entry getDirectoryEntry(Address addr), return_by_ref="yes" { Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
return static_cast(Entry, directory[addr]); 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" { 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>"; TBETable TBEs, template_hack="<Directory_TBE>";
Entry getDirectoryEntry(Address addr), return_by_ref="yes" { Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
return static_cast(Entry, directory[addr]); 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" { DataBlock getDataBlock(Address addr), return_by_ref="yes" {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -52,8 +52,9 @@ class FormalParamAST(AST):
self.pairs) self.pairs)
self.symtab.newSymbol(v) self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or ( 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) return type, "%s* %s" % (type.c_ident, param)
else: else:
return type, "const %s& %s" % (type.c_ident, param) return type, "const %s& %s" % (type.c_ident, param)

View file

@ -52,7 +52,9 @@ class LocalVariableAST(StatementAST):
self.pairs) self.pairs)
self.symtab.newSymbol(v) self.symtab.newSymbol(v)
if self.pointer or str(type) == "TBE" or ( 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) code += "%s* %s" % (type.c_ident, ident)
else: else:
code += "%s %s" % (type.c_ident, ident) code += "%s %s" % (type.c_ident, ident)

View file

@ -41,7 +41,10 @@ class MemberExprAST(ExprAST):
return_type, gcode = self.expr_ast.inline(True) return_type, gcode = self.expr_ast.inline(True)
fix = code.nofix() 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}}") code("(*$gcode).m_${{self.field}}")
else: else:
code("($gcode).m_${{self.field}}") code("($gcode).m_${{self.field}}")

View file

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