diff options
Diffstat (limited to 'src/jit/sm.cpp')
-rw-r--r-- | src/jit/sm.cpp | 116 |
1 files changed, 59 insertions, 57 deletions
diff --git a/src/jit/sm.cpp b/src/jit/sm.cpp index 859b238ec8..0154c11b0c 100644 --- a/src/jit/sm.cpp +++ b/src/jit/sm.cpp @@ -21,14 +21,16 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // // The array to map from EE opcodes (i.e. CEE_ ) to state machine opcodes (i.e. SM_ ) // -const SM_OPCODE smOpcodeMap[] = { -#define OPCODEMAP(eename, eestring, smname) smname, -#include "smopcodemap.def" -#undef OPCODEMAP +const SM_OPCODE smOpcodeMap[] = +{ + #define OPCODEMAP(eename,eestring,smname) smname, + #include "smopcodemap.def" + #undef OPCODEMAP }; + // ????????? How to make this method inlinable, since it refers to smOpcodeMap???? -/* static */ SM_OPCODE CodeSeqSM::MapToSMOpcode(OPCODE opcode) +/* static */ SM_OPCODE CodeSeqSM::MapToSMOpcode(OPCODE opcode) { assert(opcode < CEE_COUNT); @@ -37,28 +39,29 @@ const SM_OPCODE smOpcodeMap[] = { return smOpcode; } -void CodeSeqSM::Start(Compiler* comp) -{ - pComp = comp; - States = gp_SMStates; - JumpTableCells = gp_SMJumpTableCells; - StateWeights = gp_StateWeights; - NativeSize = 0; +void CodeSeqSM::Start(Compiler * comp) +{ + pComp = comp; + States = gp_SMStates; + JumpTableCells = gp_SMJumpTableCells; + StateWeights = gp_StateWeights; + NativeSize = 0; - Reset(); + Reset(); } -void CodeSeqSM::Reset() +void CodeSeqSM::Reset() { - curState = SM_STATE_ID_START; + curState = SM_STATE_ID_START; #ifdef DEBUG // Reset the state occurence counts memset(StateMatchedCounts, 0, sizeof(StateMatchedCounts)); #endif + } -void CodeSeqSM::End() +void CodeSeqSM::End() { if (States[curState].term) { @@ -66,125 +69,124 @@ void CodeSeqSM::End() } } -void CodeSeqSM::Run(SM_OPCODE opcode DEBUGARG(int level)) -{ +void CodeSeqSM::Run(SM_OPCODE opcode DEBUGARG(int level)) +{ SM_STATE_ID nextState; SM_STATE_ID rollbackState; - SM_OPCODE opcodesToRevisit[MAX_CODE_SEQUENCE_LENGTH]; + SM_OPCODE opcodesToRevisit[MAX_CODE_SEQUENCE_LENGTH]; - assert(level <= MAX_CODE_SEQUENCE_LENGTH); + assert(level<=MAX_CODE_SEQUENCE_LENGTH); _Next: - nextState = GetDestState(curState, opcode); + nextState = GetDestState(curState, opcode); if (nextState != 0) { // This is easy, Just go to the next state. curState = nextState; - return; + return; } - assert(curState != SM_STATE_ID_START); - + assert(curState != SM_STATE_ID_START); + if (States[curState].term) { TermStateMatch(curState DEBUGARG(pComp->verbose)); curState = SM_STATE_ID_START; goto _Next; } - + // This is hard. We need to rollback to the longest matched term state and restart from there. rollbackState = States[curState].longestTermState; TermStateMatch(rollbackState DEBUGARG(pComp->verbose)); assert(States[curState].length > States[rollbackState].length); - + unsigned numOfOpcodesToRevisit = States[curState].length - States[rollbackState].length + 1; - assert(numOfOpcodesToRevisit > 1 && + assert(numOfOpcodesToRevisit > 1 && numOfOpcodesToRevisit <= MAX_CODE_SEQUENCE_LENGTH); // So it can fit in the local array opcodesToRevisit[] - SM_OPCODE* p = opcodesToRevisit + (numOfOpcodesToRevisit - 1); + SM_OPCODE * p = opcodesToRevisit + (numOfOpcodesToRevisit - 1); *p = opcode; // Fill in the local array: - for (unsigned i = 0; i < numOfOpcodesToRevisit - 1; ++i) + for (unsigned i = 0; i<numOfOpcodesToRevisit-1; ++i) { - *(--p) = States[curState].opc; + * (--p) = States[curState].opc; curState = States[curState].prevState; } - assert(curState == rollbackState); + assert(curState == rollbackState); // Now revisit these opcodes, starting from SM_STATE_ID_START. curState = SM_STATE_ID_START; - for (p = opcodesToRevisit; p < opcodesToRevisit + numOfOpcodesToRevisit; ++p) + for (p = opcodesToRevisit; p< opcodesToRevisit + numOfOpcodesToRevisit; ++p) { - Run(*p DEBUGARG(level + 1)); - } + Run(*p DEBUGARG(level+1)); + } } -SM_STATE_ID CodeSeqSM::GetDestState(SM_STATE_ID srcState, SM_OPCODE opcode) + +SM_STATE_ID CodeSeqSM::GetDestState(SM_STATE_ID srcState, SM_OPCODE opcode) { assert(opcode < SM_COUNT); + + JumpTableCell * pThisJumpTable = (JumpTableCell * )(((PBYTE)JumpTableCells) + States[srcState].jumpTableByteOffset); - JumpTableCell* pThisJumpTable = (JumpTableCell*)(((PBYTE)JumpTableCells) + States[srcState].jumpTableByteOffset); - - JumpTableCell* cell = pThisJumpTable + opcode; + JumpTableCell * cell = pThisJumpTable+opcode; if (cell->srcState != srcState) { - assert(cell->srcState == 0 || - cell->srcState != srcState); // Either way means there is not outgoing edge from srcState. + assert(cell->srcState == 0 || cell->srcState != srcState); // Either way means there is not outgoing edge from srcState. return 0; } else { - return cell->destState; + return cell->destState; } } #ifdef DEBUG -const char* CodeSeqSM::StateDesc(SM_STATE_ID stateID) -{ +const char * CodeSeqSM::StateDesc(SM_STATE_ID stateID) +{ static char s_StateDesc[500]; static SM_OPCODE s_StateDescOpcodes[MAX_CODE_SEQUENCE_LENGTH]; if (stateID == 0) - { return "invalid"; - } + if (stateID == SM_STATE_ID_START) - { - return "start"; - } - unsigned i = 0; - - SM_STATE_ID b = stateID; + return "start"; + unsigned i = 0; + + SM_STATE_ID b = stateID; + while (States[b].prevState != 0) { s_StateDescOpcodes[i] = States[b].opc; - b = States[b].prevState; + b = States[b].prevState; ++i; } - assert(i == States[stateID].length && i > 0); + assert(i == States[stateID].length && i>0); - *s_StateDesc = 0; - - while (--i > 0) + * s_StateDesc = 0; + + while (--i>0) { strcat(s_StateDesc, smOpcodeNames[s_StateDescOpcodes[i]]); strcat(s_StateDesc, " -> "); } - strcat(s_StateDesc, smOpcodeNames[s_StateDescOpcodes[0]]); + strcat(s_StateDesc, smOpcodeNames[s_StateDescOpcodes[0]]); return s_StateDesc; } #endif // DEBUG + |