#include <MemOrderManager.h>
Onikiri::MemOrderManagerに対する継承グラフ
MemOrderManager.h の 51 行で定義されています。
typedef HookPoint<MemOrderManager, MemImageAccessParam> Onikiri::MemOrderManager::MemImageAccessHook |
MemOrderManager.h の 134 行で定義されています。
typedef DataPredMissRecovery Onikiri::MemOrderManager::Recovery [protected] |
MemOrderManager.h の 140 行で定義されています。
MemOrderManager::~MemOrderManager | ( | ) | [virtual] |
void MemOrderManager::Allocate | ( | OpIterator | op | ) |
MemOrderManager.cpp の 221 行で定義されています。
参照先 ASSERT・Onikiri::OpClass::IsLoad()・Onikiri::OpClass::IsMem()・m_loadList・m_storeList・Onikiri::OpList::push_back().
参照元 Onikiri::InorderSystem::Run().
00222 { 00223 const OpClass& opClass = op->GetOpClass(); 00224 ASSERT( opClass.IsMem() ); 00225 if( opClass.IsLoad() ){ 00226 m_loadList.push_back( op ); 00227 } 00228 else{ 00229 m_storeList.push_back( op ); 00230 } 00231 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
Onikiri::MemOrderManager::BEGIN_PARAM_PATH | ( | GetParamPath() | ) |
bool MemOrderManager::CanAllocate | ( | OpIterator * | infoArray, | |
int | numOp | |||
) |
MemOrderManager.cpp の 199 行で定義されています。
参照先 Onikiri::OpClassCode::IsLoad()・Onikiri::OpClassCode::IsStore()・m_loadCapacity・m_loadList・m_storeCapacity・m_storeList・m_unified・m_unifiedCapacity・Onikiri::OpList::size().
00200 { 00201 if( m_unified ){ 00202 return m_unifiedCapacity >= (int)m_storeList.size() + (int)m_loadList.size() + numOp; 00203 } 00204 else{ 00205 int loads = 0; 00206 int stores = 0; 00207 for( int i = 0; i < numOp; ++i ){ 00208 if( infoArray[i]->GetOpClass().IsStore() ){ 00209 stores++; 00210 } 00211 if( infoArray[i]->GetOpClass().IsLoad() ){ 00212 loads++; 00213 } 00214 } 00215 return 00216 ( m_loadCapacity >= ((int)m_loadList.size() + loads) ) && 00217 ( m_storeCapacity >= ((int)m_storeList.size() + stores) ); 00218 } 00219 }
関数の呼び出しグラフ:
void MemOrderManager::Commit | ( | OpIterator | op | ) |
MemOrderManager.cpp の 324 行で定義されています。
参照先 Delete()・Onikiri::OpClass::IsLoad()・Onikiri::OpClass::IsStore()・m_cache・m_numRetiredLoadAccess・m_numRetiredStoreForwarding・m_removeOpsOnCommit・Onikiri::MemAccess::MAR_SUCCESS・Onikiri::CacheAccess::OT_WRITE・RUNTIME_WARNING・Onikiri::Cache::Write()・WriteMemImage().
参照元 Onikiri::InorderList::NotifyCommit()・Onikiri::InorderSystem::Run().
00325 { 00326 // O 00327 const OpClass& opClass = op->GetOpClass(); 00328 if( opClass.IsStore() ){ 00329 00330 // G~[^C[W 00331 MemAccess writeAccess = op->GetMemAccess(); 00332 WriteMemImage( op, &writeAccess ); 00333 00334 if( writeAccess.result != MemAccess::MAR_SUCCESS ){ 00335 RUNTIME_WARNING( 00336 "An access violation occurs.\n%s\n%s", 00337 writeAccess.ToString().c_str(), op->ToString().c_str() 00338 ); 00339 } 00340 00341 if( m_cache ) { 00342 CacheAccess access( op->GetMemAccess(), op, CacheAccess::OT_WRITE ); 00343 CacheAccessResult result = 00344 m_cache->Write( access, NULL ); // LbV 00345 op->SetCacheAccessResult( result ); 00346 } 00347 } 00348 00349 if( opClass.IsLoad() ){ 00350 const MemAccess& readAccess = op->GetMemAccess(); 00351 if( readAccess.result != MemAccess::MAR_SUCCESS ){ 00352 RUNTIME_WARNING( 00353 "An access violation occurs.\n%s\n%s", 00354 readAccess.ToString().c_str(), op->ToString().c_str() 00355 ); 00356 } 00357 00358 // Update dispersion of load accesses 00359 const CacheAccessResult& result = op->GetCacheAccessResult(); 00360 if( result.cache == NULL ){ // NULL is store forwarding. 00361 m_numRetiredStoreForwarding++; 00362 } 00363 m_numRetiredLoadAccess++; 00364 } 00365 00366 if( m_removeOpsOnCommit ){ 00367 Delete( op ); 00368 } 00369 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Delete | ( | OpIterator | op | ) | [protected] |
MemOrderManager.cpp の 383 行で定義されています。
参照先 Onikiri::OpList::erase()・Onikiri::OpClass::IsLoad()・Onikiri::OpClass::IsStore()・m_loadList・m_storeList・Onikiri::OpStatus::OS_FETCH.
参照元 Commit()・Flush()・Retire().
00384 { 00385 if( op->GetStatus() == OpStatus::OS_FETCH ){ 00386 return; 00387 } 00388 00389 const OpClass& opClass = op->GetOpClass(); 00390 if( opClass.IsLoad() ) { 00391 m_loadList.erase(op); 00392 } 00393 else if( opClass.IsStore() ){ 00394 m_storeList.erase(op); 00395 } 00396 00397 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::DetectAccessOrderViolation | ( | OpIterator | store | ) | [protected] |
MemOrderManager.cpp の 129 行で定義されています。
参照先 ASSERT・Onikiri::OpList::count()・Onikiri::DS_ADDRESS_PREDICTION_MISS・Onikiri::Dumper::Dump()・Onikiri::g_dumper・GetConsumerLoad()・m_storeList・Onikiri::Recoverer::RecoverDataPredMiss()・THROW_RUNTIME_ERROR・Onikiri::DataPredMissRecovery::TYPE_ADDRESS_MATCH.
参照元 Finished().
00130 { 00131 /* 00132 F 00133 vOI[_ 00134 00135 store1 [A] = Y --- op 00136 load1 U = [A] 00137 store2 [A] = Z 00138 load2 V = [A] 00139 00140 store1 XPW[OAload1, load2XPW[O 00141 Aload1store1タsAload1, load2XPW[O 00142 */ 00143 00144 // store G[ 00145 ASSERT( store->GetOpClass().IsStore(), "Not store op." ); 00146 00147 // m store G[ 00148 ASSERT( m_storeList.count(store) == 1, "unknown op." ); 00149 00150 OpIterator conflictedConsumer = GetConsumerLoad( store, store->GetMemAccess(), 0 ); 00151 00152 if( !conflictedConsumer.IsNull() ){ 00153 00154 if( store->GetSerialID() >= conflictedConsumer->GetSerialID() ) { 00155 THROW_RUNTIME_ERROR("memory order is not inorder."); 00156 } 00157 00158 g_dumper.Dump( DS_ADDRESS_PREDICTION_MISS, conflictedConsumer ); 00159 00160 // MemDepPred m 00161 store->GetThread()->GetMemDepPred()->OrderConflicted( store, conflictedConsumer ); 00162 00163 // 00164 Recoverer* recoverer = store->GetThread()->GetRecoverer(); 00165 recoverer->RecoverDataPredMiss( 00166 store, 00167 conflictedConsumer, 00168 Recovery::TYPE_ADDRESS_MATCH 00169 ); 00170 00171 } 00172 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
bool MemOrderManager::DetectPartialLoadViolation | ( | OpIterator | op | ) | [protected] |
MemOrderManager.cpp の 176 行で定義されています。
参照先 GetProducerStore()・Onikiri::MemAccess::MAR_READ_INVALID_PARTIAL_READ・Onikiri::Recoverer::RecoverDataPredMiss()・Onikiri::DataPredMissRecovery::TYPE_PARTIAL_LOAD.
参照元 Finished().
00177 { 00178 if( op->GetOpClass().IsLoad() ){ 00179 // Validate whether invalid partial read occurs or not. 00180 // If invalid partial read occurs, MAR_READ_INVALID_PARTIAL_READ is 00181 // set to a result and need to recover. 00182 const MemAccess& mem = op->GetMemAccess(); 00183 if( mem.result == MemAccess::MAR_READ_INVALID_PARTIAL_READ ){ 00184 OpIterator producer = 00185 GetProducerStore( op, mem ); 00186 Recoverer* recoverer = op->GetThread()->GetRecoverer(); 00187 00188 recoverer->RecoverDataPredMiss( 00189 producer, 00190 op, 00191 DataPredMissRecovery::TYPE_PARTIAL_LOAD 00192 ); 00193 return true; 00194 } 00195 } 00196 return false; 00197 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Finalize | ( | ) | [virtual] |
Onikiri::PhysicalResourceNodeを再定義しています。
MemOrderManager.cpp の 121 行で定義されています。
参照先 Onikiri::PhysicalResourceNode::ReleaseParam().
00122 { 00123 ReleaseParam(); 00124 }
関数の呼び出しグラフ:
void MemOrderManager::Finished | ( | OpIterator | op | ) |
MemOrderManager.cpp の 234 行で定義されています。
参照先 ASSERT・Onikiri::OpList::count()・DetectAccessOrderViolation()・DetectPartialLoadViolation()・Onikiri::OpClass::IsLoad()・Onikiri::OpClass::IsStore()・m_loadList・m_storeList.
参照元 Onikiri::OpFinishEvent::Update().
00235 { 00236 const OpClass& opClass = op->GetOpClass(); 00237 // Detect access order violation. 00238 if( opClass.IsStore() ){ 00239 ASSERT( m_storeList.count(op) == 1, "unknown op." ); 00240 DetectAccessOrderViolation( op ); 00241 } 00242 00243 if( opClass.IsLoad() ){ 00244 ASSERT( m_loadList.count(op) == 1, "unknown op." ); 00245 DetectPartialLoadViolation( op ); 00246 } 00247 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Flush | ( | OpIterator | op | ) |
MemOrderManager.cpp の 378 行で定義されています。
参照先 Delete().
参照元 Onikiri::InorderList::NotifyFlush().
00379 { 00380 Delete( op ); 00381 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
OpIterator MemOrderManager::GetConsumerLoad | ( | OpIterator | producer, | |
const MemAccess & | access, | |||
int | index | |||
) |
MemOrderManager.cpp の 287 行で定義されています。
参照先 ASSERT・Onikiri::OpList::begin()・Onikiri::OpList::count()・Onikiri::OpList::end()・Onikiri::OpClass::IsLoad()・Onikiri::MemOrderOperations::IsOverlapped()・m_loadList・m_memOperations・m_storeList・Onikiri::OpStatus::OS_EXECUTING.
参照元 DetectAccessOrderViolation()・Onikiri::Op::GetFirstConsumer().
00288 { 00289 ASSERT( producer->GetOpClass().IsStore(), "Not store op." ); 00290 ASSERT( m_storeList.count( producer ) == 1, "unknown op." ); 00291 00292 OpIterator consumer; 00293 00294 int num = 0; 00295 for( OpList::iterator i = m_loadList.begin(); i != m_loadList.end(); ++i ){ 00296 00297 OpIterator op = *i; 00298 if( op->GetGlobalSerialID() < producer->GetGlobalSerialID() ){ 00299 continue; 00300 } 00301 00302 if( op->GetStatus() < OpStatus::OS_EXECUTING ){ 00303 continue; 00304 } 00305 00306 OpClass opClass = op->GetOpClass(); 00307 if( !opClass.IsLoad() ){ 00308 continue; 00309 } 00310 00311 if( m_memOperations.IsOverlapped( producerAccess, op->GetMemAccess() ) ){ 00312 if( num == index ){ 00313 consumer = op; 00314 break; 00315 } 00316 num++; 00317 } 00318 } 00319 00320 return consumer; 00321 00322 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
Core* Onikiri::MemOrderManager::GetCore | ( | ) | const [inline] |
MemOrderManager.h の 125 行で定義されています。
参照先 m_core.
参照元 Initialize().
00125 { return m_core; }
Here is the caller graph for this function:
MemIF* Onikiri::MemOrderManager::GetMemImage | ( | ) | const [inline] |
MemOrderManager.h の 124 行で定義されています。
参照先 Onikiri::EmulatorIF::GetMemImage()・m_emulator.
参照元 ReadMemImage()・WriteMemImage().
00124 { return m_emulator->GetMemImage(); }
関数の呼び出しグラフ:
Here is the caller graph for this function:
OpIterator MemOrderManager::GetProducerStore | ( | OpIterator | op, | |
const MemAccess & | access | |||
) | const |
MemOrderManager.cpp の 251 行で定義されています。
参照先 Onikiri::MemAccess::address・ASSERT・Onikiri::OpList::begin()・Onikiri::OpList::count()・Onikiri::OpList::end()・Onikiri::MemOrderOperations::IsOverlapped()・m_loadList・m_memOperations・m_storeList・Onikiri::OpStatus::OS_EXECUTING・Onikiri::LogicalData::pid.
参照元 DetectPartialLoadViolation()・Onikiri::MemExecUnit::GetProducerStore()・Read().
00252 { 00253 ASSERT( access.address.pid != PID_INVALID ); 00254 00255 // AhXvsstoreMemOrderManagerAMemOrderManagerReads 00256 // m_listopuOT 00257 ASSERT( m_loadList.count(consumer) == 1, "unknown load:\n%s", consumer->ToString().c_str() ); 00258 00259 OpIterator producer = OpIterator(0); 00260 00261 OpList::const_iterator i = m_storeList.end(); 00262 while( i != m_storeList.begin() ) { 00263 --i; 00264 00265 OpIterator op = *i; 00266 00267 if( op->GetGlobalSerialID() > consumer->GetGlobalSerialID() ){ 00268 continue; 00269 } 00270 00271 if( op->GetStatus() < OpStatus::OS_EXECUTING ){ 00272 continue; 00273 } 00274 00275 // Gg[OpXgAAhXd 00276 if( op->GetOpClass().IsStore() && 00277 m_memOperations.IsOverlapped( access, op->GetMemAccess() ) 00278 ){ 00279 producer = op; 00280 break; 00281 } 00282 }; 00283 00284 return producer; 00285 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Initialize | ( | InitPhase | phase | ) | [virtual] |
MemOrderManager.cpp の 86 行で定義されています。
参照先 Onikiri::PhysicalResourceNode::CheckNodeInitialized()・GetCore()・Onikiri::Core::GetFetcher()・Onikiri::Fetcher::GetFetchWidth()・Onikiri::CacheSystem::GetFirstLevelDataCache()・Onikiri::EmulatorIF::GetISAInfo()・Onikiri::Core::GetOpArray()・Onikiri::Cache::GetStaticLatency()・Onikiri::PhysicalResourceNode::INIT_POST_CONNECTION・Onikiri::PhysicalResourceNode::INIT_PRE_CONNECTION・Onikiri::ISAInfoIF::IsLittleEndian()・Onikiri::ParamExchange::LoadParam()・m_cache・m_cacheLatency・m_cacheSystem・m_core・m_emulator・m_loadCapacity・m_loadList・m_memOperations・m_storeCapacity・m_storeList・m_unified・m_unifiedCapacity・Onikiri::OpList::resize()・Onikiri::MemOrderOperations::SetTargetEndian()・THROW_RUNTIME_ERROR.
00087 { 00088 if( phase == INIT_PRE_CONNECTION ){ 00089 LoadParam(); 00090 } 00091 else if( phase == INIT_POST_CONNECTION ){ 00092 00093 // oZbg`FbN 00094 CheckNodeInitialized( "core", m_core ); 00095 CheckNodeInitialized( "emulator", m_emulator ); 00096 CheckNodeInitialized( "cacheSystem", m_cacheSystem ); 00097 00098 m_cache = m_cacheSystem->GetFirstLevelDataCache(); 00099 m_cacheLatency = m_cache->GetStaticLatency(); 00100 00101 // List 00102 m_loadList.resize(*m_core->GetOpArray()); 00103 m_storeList.resize(*m_core->GetOpArray()); 00104 m_memOperations.SetTargetEndian( m_emulator->GetISAInfo()->IsLittleEndian() ); 00105 00106 int fetchWidth = GetCore()->GetFetcher()->GetFetchWidth(); 00107 if( m_unified ){ 00108 if( fetchWidth > m_unifiedCapacity ){ 00109 THROW_RUNTIME_ERROR( "The capacity of MemOrderManager is too small. It must be larger than fetch width." ); 00110 } 00111 } 00112 else{ 00113 if( fetchWidth > m_loadCapacity || fetchWidth > m_storeCapacity ){ 00114 THROW_RUNTIME_ERROR( "The capacity of MemOrderManager is too small. It must be larger than fetch width." ); 00115 } 00116 } 00117 } 00118 00119 }
関数の呼び出しグラフ:
bool Onikiri::MemOrderManager::IsIdealPatialLoadEnabled | ( | ) | const [inline] |
void MemOrderManager::Read | ( | OpIterator | op, | |
MemAccess * | access | |||
) |
MemOrderManager.cpp の 399 行で定義されています。
参照先 Onikiri::OpList::begin()・Onikiri::OpList::end()・GetProducerStore()・Onikiri::MemOrderOperations::IsInnerAccess()・Onikiri::OpIterator::IsNull()・Onikiri::MemOrderOperations::IsOverlapped()・m_idealPartialLoad・m_memOperations・m_numExecutedLoadAccess・m_numExecutedStoreForwarding・m_storeList・Onikiri::MemAccess::MAR_READ_INVALID_PARTIAL_READ・Onikiri::MemOrderOperations::MergePartialAccess()・ReadMemImage()・Onikiri::MemOrderOperations::ReadPreviousAccess()・Onikiri::MemAccess::result・Onikiri::MemAccess::value.
参照元 Onikiri::Op::Read().
00400 { 00401 OpIterator producer = GetProducerStore( op, *access ); 00402 00403 m_numExecutedLoadAccess++; 00404 00405 if( !producer.IsNull() ){ 00406 00407 // AhXvsstoreMemOrderManagerAMemOrderManagerReads 00408 const MemAccess& producerAccess = producer->GetMemAccess(); 00409 if( m_memOperations.IsInnerAccess( *access, producerAccess ) ){ 00410 // Normal forwarding 00411 access->value = m_memOperations.ReadPreviousAccess( *access, producerAccess ); 00412 m_numExecutedStoreForwarding++; 00413 } 00414 else{ 00415 // Partial load forwarding 00416 if( !m_idealPartialLoad ){ 00417 // Partial load is treated as exception. 00418 access->result = MemAccess::MAR_READ_INVALID_PARTIAL_READ; 00419 } 00420 else{ 00421 // Ideal mode. 00422 // Store data is forwarded ideally. 00423 ReadMemImage( op, access ); 00424 00425 for( OpList::iterator i = m_storeList.begin(); i != m_storeList.end(); ++i ){ 00426 if( (*i)->GetGlobalSerialID() > op->GetGlobalSerialID() ){ 00427 break; 00428 } 00429 // Merge a store access to 'access'. 00430 const MemAccess& storeAccess = (*i)->GetMemAccess(); 00431 if( m_memOperations.IsOverlapped( *access, storeAccess ) ){ 00432 access->value = 00433 m_memOperations.MergePartialAccess( *access, storeAccess ); 00434 } 00435 } 00436 } 00437 } 00438 } 00439 else{ 00440 00441 // AhXvsstoreAemulator C[W 00442 ReadMemImage( op, access ); 00443 } 00444 00445 op->SetMemAccess( *access ); 00446 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::ReadMemImage | ( | OpIterator | op, | |
MemAccess * | access | |||
) | [protected] |
MemOrderManager.cpp の 454 行で定義されています。
参照先 GetMemImage()・HOOK_SECTION_OP_PARAM・Onikiri::MemOrderManager::MemImageAccessParam::memAccess・Onikiri::MemOrderManager::MemImageAccessParam::memImage・Onikiri::MemIF::Read()・s_readMemImageHook.
参照元 Read().
00455 { 00456 MemImageAccessParam param = { GetMemImage(), access }; 00457 00458 HOOK_SECTION_OP_PARAM( s_readMemImageHook, op, param ) 00459 { 00460 MemIF* memImage = param.memImage; 00461 memImage->Read( param.memAccess ); 00462 } 00463 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Retire | ( | OpIterator | op | ) |
MemOrderManager.cpp の 371 行で定義されています。
参照先 Delete()・m_removeOpsOnCommit.
参照元 Onikiri::InorderList::NotifyRetire()・Onikiri::InorderSystem::Run().
00372 { 00373 if( !m_removeOpsOnCommit ){ 00374 Delete( op ); 00375 } 00376 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void MemOrderManager::Write | ( | OpIterator | op, | |
MemAccess * | access | |||
) |
MemOrderManager.cpp の 448 行で定義されています。
参照元 Onikiri::Op::Write().
Here is the caller graph for this function:
void MemOrderManager::WriteMemImage | ( | OpIterator | op, | |
MemAccess * | access | |||
) | [protected] |
MemOrderManager.cpp の 465 行で定義されています。
参照先 GetMemImage()・HOOK_SECTION_OP_PARAM・Onikiri::MemOrderManager::MemImageAccessParam::memAccess・Onikiri::MemOrderManager::MemImageAccessParam::memImage・s_writeMemImageHook・Onikiri::MemIF::Write().
参照元 Commit().
00466 { 00467 MemImageAccessParam param = { GetMemImage(), access }; 00468 00469 HOOK_SECTION_OP_PARAM( s_writeMemImageHook, op, param ) 00470 { 00471 MemIF* memImage = param.memImage; 00472 memImage->Write( param.memAccess ); 00473 } 00474 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
Cache* Onikiri::MemOrderManager::m_cache [protected] |
int Onikiri::MemOrderManager::m_cacheLatency [protected] |
CacheSystem* Onikiri::MemOrderManager::m_cacheSystem [protected] |
Core* Onikiri::MemOrderManager::m_core [protected] |
EmulatorIF* Onikiri::MemOrderManager::m_emulator [protected] |
bool Onikiri::MemOrderManager::m_idealPartialLoad [protected] |
int Onikiri::MemOrderManager::m_loadCapacity [protected] |
OpList Onikiri::MemOrderManager::m_loadList [protected] |
MemOrderManager.h の 164 行で定義されています。
参照元 Allocate()・CanAllocate()・Delete()・Finished()・GetConsumerLoad()・GetProducerStore()・Initialize().
s64 Onikiri::MemOrderManager::m_numExecutedLoadAccess [protected] |
s64 Onikiri::MemOrderManager::m_numRetiredLoadAccess [protected] |
bool Onikiri::MemOrderManager::m_removeOpsOnCommit [protected] |
int Onikiri::MemOrderManager::m_storeCapacity [protected] |
OpList Onikiri::MemOrderManager::m_storeList [protected] |
bool Onikiri::MemOrderManager::m_unified [protected] |
int Onikiri::MemOrderManager::m_unifiedCapacity [protected] |