TEST_F(test_core, transition_NNIS) { // define additional node chains NodeChain<M1> ch1(4, 100), ch2(6, 200), ch3(2, 300); // define network entry. link(ch1[0], pass, atNegative, 1); // N ch1. back(). link(term, digits, atSimple, -1); entry. link(ch2[0], pass, atNegative, 2); // N ch2. back(). link(term, letters, atSimple, -2); entry. link(ch3[0], pass, atInvoke, 3); // I ch3. back(). link(exit, alpha, atSimple, 4); ch3. back(). link(exit, _12345, atSimple, 5); ch3. back(). link(exit, pound, atSimple, 6); entry. link(exit, pass, atSimple, 7); // S exit. link(term, end, atSimple, 8); // test parsing EXPECT_EQ( 0, trace_count(entry, "alpha", 2048) ); EXPECT_EQ( 0, trace_count(entry, "12345", 2048) ); EXPECT_EQ( 1, trace_count(entry, "#", 2048) ); }
//***************************************************************************** // //***************************************************************************** void CPU_HandleDynaRecOnBranch( bool backwards, bool trace_already_enabled ) { DAEDALUS_PROFILE( "CPU_HandleDynaRecOnBranch" ); bool start_of_trace( false ); if( backwards ) { start_of_trace = true; } bool change_core( false ); DAED_LOG( DEBUG_DYNAREC_CACHE, "CPU_HandleDynaRecOnBranch" ); while( gCPUState.GetStuffToDo() == 0 && gCPUState.Delay == NO_DELAY ) { DAEDALUS_ASSERT( gCPUState.Delay == NO_DELAY, "Why are we entering with a delay slot active?" ); #ifdef DAEDALUS_ENABLE_DYNAREC_PROFILE u32 entry_count( gCPUState.CPUControl[C0_COUNT]._u32 ); // Just used DYNAREC_PROFILE_ENTEREXIT #endif u32 entry_address( gCPUState.CurrentPC ); #ifdef DAEDALUS_DEBUG_DYNAREC CFragment * p_fragment( gFragmentCache.LookupFragment( entry_address ) ); #else CFragment * p_fragment( gFragmentCache.LookupFragmentQ( entry_address ) ); #endif if( p_fragment != NULL ) { #ifdef DAEDALUS_PROFILE_EXECUTION gFragmentLookupSuccess++; #endif // Check if another trace is active and we're about to enter if( gTraceRecorder.IsTraceActive() ) { gTraceRecorder.StopTrace( gCPUState.CurrentPC ); CPU_CreateAndAddFragment(); // We need to change the core when exiting change_core = true; } p_fragment->Execute(); DYNAREC_PROFILE_ENTEREXIT( entry_address, gCPUState.CurrentPC, gCPUState.CPUControl[C0_COUNT]._u32 - entry_count ); start_of_trace = true; } else { #ifdef DAEDALUS_PROFILE_EXECUTION gFragmentLookupFailure++; #endif if( start_of_trace ) { start_of_trace = false; if( !gTraceRecorder.IsTraceActive() ) { if (gResetFragmentCache) { #ifdef DAEDALUS_ENABLE_OS_HOOKS //Don't reset the cache if there is no fragment except OSHLE function stubs if (gFragmentCache.GetCacheSize() >= gNumOfOSFunctions) #else if(true) #endif { gFragmentCache.Clear(); gHotTraceCountMap.clear(); // Makes sense to clear this now, to get accurate usage stats #ifdef DAEDALUS_ENABLE_OS_HOOKS Patch_PatchAll(); #endif } #ifdef DAEDALUS_DEBUG_CONSOLE else { DBGConsole_Msg(0, "Safely skipped one flush"); } #endif gResetFragmentCache = false; } if( gFragmentCache.GetCacheSize() > gMaxFragmentCacheSize) { gFragmentCache.Clear(); gHotTraceCountMap.clear(); // Makes sense to clear this now, to get accurate usage stats #ifdef DAEDALUS_ENABLE_OS_HOOKS Patch_PatchAll(); #endif } // If there is no fragment for this target, start tracing u32 trace_count( ++gHotTraceCountMap[ gCPUState.CurrentPC ] ); if( gHotTraceCountMap.size() >= gMaxHotTraceMapSize ) { DBGConsole_Msg( 0, "Hot trace cache hit %d, dumping", gHotTraceCountMap.size() ); gHotTraceCountMap.clear(); gFragmentCache.Clear(); #ifdef DAEDALUS_ENABLE_OS_HOOKS Patch_PatchAll(); #endif } else if( trace_count == gHotTraceThreshold ) { //DBGConsole_Msg( 0, "Identified hot trace at [R%08x]! (size is %d)", gCPUState.CurrentPC, gHotTraceCountMap.size() ); gTraceRecorder.StartTrace( gCPUState.CurrentPC ); if(!trace_already_enabled) { change_core = true; } DAED_LOG( DEBUG_DYNAREC_CACHE, "StartTrace( %08x )", gCPUState.CurrentPC ); } #ifdef DAEDALUS_DEBUG_DYNAREC else if( trace_count > gHotTraceThreshold ) { if(gAbortedTraceReasons.find( gCPUState.CurrentPC ) != gAbortedTraceReasons.end() ) { u32 reason( gAbortedTraceReasons[ gCPUState.CurrentPC ] ); use( reason ); //DBGConsole_Msg( 0, "Hot trace at [R%08x] has count of %d! (reason is %x) size %d", gCPUState.CurrentPC, trace_count, reason, gHotTraceCountMap.size( ) ); DAED_LOG( DEBUG_DYNAREC_CACHE, "Hot trace at %08x has count of %d! (reason is %x) size %d", gCPUState.CurrentPC, trace_count, reason, gHotTraceCountMap.size( ) ); } else { DAED_LOG( DEBUG_DYNAREC_CACHE, "Hot trace at %08x has count of %d! (reason is UNKNOWN!)", gCPUState.CurrentPC, trace_count ); } } #endif //DAEDALUS_DEBUG_DYNAREC } } else { DAED_LOG( DEBUG_DYNAREC_CACHE, "Not start of trace" ); } break; } } if(change_core) { CPU_SelectCore(); } }