void CodeGen::siCloseAllOpenScopes() { assert(siOpenScopeList.scNext); while (siOpenScopeList.scNext) siEndScope(siOpenScopeList.scNext); }
void CodeGen::siEndScope(unsigned varNum) { for (siScope* scope = siOpenScopeList.scNext; scope; scope = scope->scNext) { if (scope->scVarNum == varNum) { siEndScope(scope); return; } } JITDUMP("siEndScope: Failed to end scope for V%02u\n", varNum); // At this point, we probably have a bad LocalVarTab if (compiler->opts.compDbgCode) { JITDUMP("...checking var tab validity\n"); // Note the following assert is saying that we expect // the VM supplied info to be invalid... assert(!siVerifyLocalVarTab()); compiler->opts.compScopeInfo = false; } }
void CodeGen::siEndBlock(BasicBlock* block) { assert(compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0)); #if FEATURE_EH_FUNCLETS if (siInFuncletRegion) return; #endif // FEATURE_EH_FUNCLETS #ifdef DEBUG if (verbose) { printf("\nScope info: end block BB%02u, IL range ", block->bbNum); block->dspBlockILRange(); printf("\n"); } #endif // DEBUG unsigned endOffs = block->bbCodeOffsEnd; if (endOffs == BAD_IL_OFFSET) { JITDUMP("Scope info: ignoring block end\n"); return; } // If non-debuggable code, find all scopes which end over this block // and close them. For debuggable code, scopes will only end on block // boundaries. VarScopeDsc* varScope; while ((varScope = compiler->compGetNextExitScope(endOffs, !compiler->opts.compDbgCode)) != NULL) { // brace-matching editor workaround for following line: ( JITDUMP("Scope info: ending scope, LVnum=%u [%03X..%03X)\n", varScope->vsdLVnum, varScope->vsdLifeBeg, varScope->vsdLifeEnd); unsigned varNum = varScope->vsdVarNum; LclVarDsc * lclVarDsc1 = &compiler->lvaTable[varNum]; assert(lclVarDsc1); if (lclVarDsc1->lvTracked) { siEndTrackedScope(lclVarDsc1->lvVarIndex); } else { siEndScope(varNum); } } siLastEndOffs = endOffs; #ifdef DEBUG if (verbose) siDispOpenScopes(); #endif }
void CodeGen::siCheckVarScope(unsigned varNum, IL_OFFSET offs) { assert(compiler->opts.compScopeInfo && !compiler->opts.compDbgCode && (compiler->info.compVarScopesCount > 0)); #if FEATURE_EH_FUNCLETS if (siInFuncletRegion) { return; } #endif // FEATURE_EH_FUNCLETS if (offs == BAD_IL_OFFSET) { return; } siScope* scope; LclVarDsc* lclVarDsc1 = &compiler->lvaTable[varNum]; // If there is an open scope corresponding to varNum, find it if (lclVarDsc1->lvTracked) { scope = siLatestTrackedScopes[lclVarDsc1->lvVarIndex]; } else { for (scope = siOpenScopeList.scNext; scope; scope = scope->scNext) { if (scope->scVarNum == varNum) { break; } } } // Look up the compiler->info.compVarScopes[] to find the local var info for (varNum->lvSlotNum, offs) VarScopeDsc* varScope = compiler->compFindLocalVar(varNum, offs); if (varScope == nullptr) { return; } // If the currently open scope does not have the correct LVnum, close it // and create a new scope with this new LVnum if (scope) { if (scope->scLVnum != varScope->vsdLVnum) { siEndScope(scope); siNewScope(varScope->vsdLVnum, varScope->vsdVarNum); } } else { siNewScope(varScope->vsdLVnum, varScope->vsdVarNum); } }
void CodeGen::siEndScope(unsigned varNum) { for (siScope * scope = siOpenScopeList.scNext; scope; scope = scope->scNext) { if (scope->scVarNum == varNum) { siEndScope(scope); return; } } // At this point, we probably have a bad LocalVarTab if (compiler->opts.compDbgCode) { // LocalVarTab is good?? If we reached here implies that we are in a // bad state, so pretend that we don't have any scope info. assert(!siVerifyLocalVarTab()); compiler->opts.compScopeInfo = false; } }