SLICC: Use pointers for directory entries
authorNilay Vaish <nilay@cs.wisc.edu>
Sat, 31 Dec 2011 22:38:30 +0000 (16:38 -0600)
committerNilay Vaish <nilay@cs.wisc.edu>
Sat, 31 Dec 2011 22:38:30 +0000 (16:38 -0600)
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

14 files changed:
src/mem/protocol/MESI_CMP_directory-dir.sm
src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MOESI_CMP_directory-dir.sm
src/mem/protocol/MOESI_CMP_token-dir.sm
src/mem/protocol/MOESI_hammer-dir.sm
src/mem/protocol/RubySlicc_Types.sm
src/mem/ruby/system/DirectoryMemory.cc
src/mem/ruby/system/DirectoryMemory.hh
src/mem/ruby/system/SparseMemory.cc
src/mem/ruby/system/SparseMemory.hh
src/mem/slicc/ast/FormalParamAST.py
src/mem/slicc/ast/LocalVariableAST.py
src/mem/slicc/ast/MemberExprAST.py
src/mem/slicc/ast/MethodCallExprAST.py

index 4232729054b9e39ee0a7894cbe05a6ae92ed4742..d026e7b90c26f26ae3b15a8977b8e83fbfb1deb7 100644 (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) {
index 2bd3afa44da0fda55e53f40d83fd23fd68789d19..40b919c92403c2f7eeda946c54632c36a4fce30b 100644 (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) {
index b71518b3f65a7c104d16a8551aceefd53b2bb344..202bd11f66beb8d0b8c2e18c82c6791db0f27f96 100644 (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) {
index 9e6c6c99b739e3270eeb566bbe0272a1563322cd..39e8a8d275a512aefc569d36b2f2d6eb63dd66d9 100644 (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" {
index a4f4bf17afc3df8cd29030b25c1eeb4ab28efc6c..a20619d46d251b83d498062a40d9fe10da3939ed 100644 (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" {
index cc404394dfff633db0ac3c3e972dffec2021c251..c76e0fe3e71f025dec816bd37f9f3167b814c16e 100644 (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);
index a91f05a693b0b5aef192c32cc7ed6352b8f42d4c..03aa6891942c96de9809e472dd328c42acba3271 100644 (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
index 79b04726a9de9e77506cfc8471581b83c0bae43f..7005ce23433c51756338622efe5b47229b036d16 100644 (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;
index fd90e2214ba7df26ef2a3646eb45bbd2f465f171..8e4f37c46e0e1026755bb1dfa99ebd5a2741582f 100644 (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;
 }
index 78a3080a17ac6ab30d490a5beb9800f3ae0967ab..f6937ef547eb7a1dd703df007eb1bb8f4b984631 100644 (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;
index e94f24ccbaab2ab70bf6989706b3aa031e1ebd66..6ed5bca0a9fb9db1a16ec6d062bdec227982ce58 100644 (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)
index b779415f3c2f1164ae5fa4a68b24b94268fc9266..0b77323b7f61b4ae9fa16c2034a8fd2282be8934 100644 (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)
index 412c178d8a174d1a6f4b04a7263c119c0239dfae..6a6fc49bbe28e9ec32c6c28abc367568aff90084 100644 (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}}")
index cfee9b19dcfbcc1ec892fd1e3016885bf516ff04..cf30cfa964bb3430a66ed7201b1813f497b8abcf 100644 (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)