diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/ex_docmd.c | 87 | ||||
| -rw-r--r-- | src/nvim/testdir/test_profile.vim | 225 | 
2 files changed, 278 insertions, 34 deletions
| diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index b1f80d791e..34717b631e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1471,22 +1471,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,               || (cstack->cs_idx >= 0                   && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE))); -  /* Count this line for profiling if ea.skip is FALSE. */ -  if (do_profiling == PROF_YES && !ea.skip) { -    if (getline_equal(fgetline, cookie, get_func_line)) -      func_line_exec(getline_cookie(fgetline, cookie)); -    else if (getline_equal(fgetline, cookie, getsourceline)) -      script_line_exec(); -  } - -  /* May go to debug mode.  If this happens and the ">quit" debug command is -   * used, throw an interrupt exception and skip the next command. */ -  dbg_check_breakpoint(&ea); -  if (!ea.skip && got_int) { -    ea.skip = TRUE; -    (void)do_intthrow(cstack); -  } -    // 3. Skip over the range to find the command. Let "p" point to after it.    //    // We need the command to know what kind of range it uses. @@ -1498,22 +1482,61 @@ static char_u * do_one_cmd(char_u **cmdlinep,    }    p = find_command(&ea, NULL); -  /* -   * 4. Parse a range specifier of the form: addr [,addr] [;addr] .. -   * -   * where 'addr' is: -   * -   * %	      (entire file) -   * $  [+-NUM] -   * 'x [+-NUM] (where x denotes a currently defined mark) -   * .  [+-NUM] -   * [+-NUM].. -   * NUM -   * -   * The ea.cmd pointer is updated to point to the first character following the -   * range spec. If an initial address is found, but no second, the upper bound -   * is equal to the lower. -   */ +  // Count this line for profiling if skip is TRUE. +  if (do_profiling == PROF_YES +      && (!ea.skip || cstack->cs_idx == 0 +          || (cstack->cs_idx > 0 +              && (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) { +    int skip = did_emsg || got_int || current_exception; + +    if (ea.cmdidx == CMD_catch) { +      skip = !skip && !(cstack->cs_idx >= 0 +                        && (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN) +                        && !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT)); +    } else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif) { +      skip = skip || !(cstack->cs_idx >= 0 +                       && !(cstack->cs_flags[cstack->cs_idx] +                            & (CSF_ACTIVE | CSF_TRUE))); +    } else if (ea.cmdidx == CMD_finally) { +      skip = false; +    } else if (ea.cmdidx != CMD_endif +               && ea.cmdidx != CMD_endfor +               && ea.cmdidx != CMD_endtry +               && ea.cmdidx != CMD_endwhile) { +      skip = ea.skip; +    } + +    if (!skip) { +      if (getline_equal(fgetline, cookie, get_func_line)) { +        func_line_exec(getline_cookie(fgetline, cookie)); +      } else if (getline_equal(fgetline, cookie, getsourceline)) { +        script_line_exec(); +      } +    } +  } + +  // May go to debug mode.  If this happens and the ">quit" debug command is +  // used, throw an interrupt exception and skip the next command. +  dbg_check_breakpoint(&ea); +  if (!ea.skip && got_int) { +    ea.skip = TRUE; +    (void)do_intthrow(cstack); +  } + +  // 4. Parse a range specifier of the form: addr [,addr] [;addr] .. +  // +  // where 'addr' is: +  // +  // %  (entire file) +  // $  [+-NUM] +  // 'x [+-NUM] (where x denotes a currently defined mark) +  // .  [+-NUM] +  // [+-NUM].. +  // NUM +  // +  // The ea.cmd pointer is updated to point to the first character following the +  // range spec. If an initial address is found, but no second, the upper bound +  // is equal to the lower.    // ea.addr_type for user commands is set by find_ucmd    if (!IS_USER_CMDIDX(ea.cmdidx)) { diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim index 9b78d90b0b..af572bee8f 100644 --- a/src/nvim/testdir/test_profile.vim +++ b/src/nvim/testdir/test_profile.vim @@ -67,7 +67,7 @@ func Test_profile_func()    call assert_match('^\s*1\s\+.*\slet l:count = 100$',             lines[13])    call assert_match('^\s*101\s\+.*\swhile l:count > 0$',           lines[14])    call assert_match('^\s*100\s\+.*\s  let l:count = l:count - 1$', lines[15]) -  call assert_match('^\s*100\s\+.*\sendwhile$',                    lines[16]) +  call assert_match('^\s*101\s\+.*\sendwhile$',                    lines[16])    call assert_equal('',                                            lines[17])    call assert_equal('FUNCTIONS SORTED ON TOTAL TIME',              lines[18])    call assert_equal('count  total (s)   self (s)  function',       lines[19]) @@ -84,6 +84,227 @@ func Test_profile_func()    call delete('Xprofile_func.log')  endfunc +func Test_profile_func_with_ifelse() +  let lines = [ +    \ "func! Foo1()", +    \ "  if 1", +    \ "    let x = 0", +    \ "  elseif 1", +    \ "    let x = 1", +    \ "  else", +    \ "    let x = 2", +    \ "  endif", +    \ "endfunc", +    \ "func! Foo2()", +    \ "  if 0", +    \ "    let x = 0", +    \ "  elseif 1", +    \ "    let x = 1", +    \ "  else", +    \ "    let x = 2", +    \ "  endif", +    \ "endfunc", +    \ "func! Foo3()", +    \ "  if 0", +    \ "    let x = 0", +    \ "  elseif 0", +    \ "    let x = 1", +    \ "  else", +    \ "    let x = 2", +    \ "  endif", +    \ "endfunc", +    \ "call Foo1()", +    \ "call Foo2()", +    \ "call Foo3()", +    \ ] + +  call writefile(lines, 'Xprofile_func.vim') +  call system(v:progpath +    \ . ' -es -u NONE -U NONE -i NONE --noplugin' +    \ . ' -c "profile start Xprofile_func.log"' +    \ . ' -c "profile func Foo*"' +    \ . ' -c "so Xprofile_func.vim"' +    \ . ' -c "qall!"') +  call assert_equal(0, v:shell_error) + +  let lines = readfile('Xprofile_func.log') + +  " - Foo1() should pass 'if' block. +  " - Foo2() should pass 'elseif' block. +  " - Foo3() should pass 'else' block. +  call assert_equal(54, len(lines)) + +  call assert_equal('FUNCTION  Foo1()',                            lines[0]) +  call assert_equal('Called 1 time',                               lines[1]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[2]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[3]) +  call assert_equal('',                                            lines[4]) +  call assert_equal('count  total (s)   self (s)',                 lines[5]) +  call assert_match('^\s*1\s\+.*\sif 1$',                          lines[6]) +  call assert_match('^\s*1\s\+.*\s  let x = 0$',                   lines[7]) +  call assert_match(        '^\s\+elseif 1$',                      lines[8]) +  call assert_match(          '^\s\+let x = 1$',                   lines[9]) +  call assert_match(        '^\s\+else$',                          lines[10]) +  call assert_match(          '^\s\+let x = 2$',                   lines[11]) +  call assert_match('^\s*1\s\+.*\sendif$',                         lines[12]) +  call assert_equal('',                                            lines[13]) +  call assert_equal('FUNCTION  Foo2()',                            lines[14]) +  call assert_equal('Called 1 time',                               lines[15]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[16]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[17]) +  call assert_equal('',                                            lines[18]) +  call assert_equal('count  total (s)   self (s)',                 lines[19]) +  call assert_match('^\s*1\s\+.*\sif 0$',                          lines[20]) +  call assert_match(          '^\s\+let x = 0$',                   lines[21]) +  call assert_match('^\s*1\s\+.*\selseif 1$',                      lines[22]) +  call assert_match('^\s*1\s\+.*\s  let x = 1$',                   lines[23]) +  call assert_match(        '^\s\+else$',                          lines[24]) +  call assert_match(          '^\s\+let x = 2$',                   lines[25]) +  call assert_match('^\s*1\s\+.*\sendif$',                         lines[26]) +  call assert_equal('',                                            lines[27]) +  call assert_equal('FUNCTION  Foo3()',                            lines[28]) +  call assert_equal('Called 1 time',                               lines[29]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[30]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[31]) +  call assert_equal('',                                            lines[32]) +  call assert_equal('count  total (s)   self (s)',                 lines[33]) +  call assert_match('^\s*1\s\+.*\sif 0$',                          lines[34]) +  call assert_match(          '^\s\+let x = 0$',                   lines[35]) +  call assert_match('^\s*1\s\+.*\selseif 0$',                      lines[36]) +  call assert_match(          '^\s\+let x = 1$',                   lines[37]) +  call assert_match('^\s*1\s\+.*\selse$',                          lines[38]) +  call assert_match('^\s*1\s\+.*\s  let x = 2$',                   lines[39]) +  call assert_match('^\s*1\s\+.*\sendif$',                         lines[40]) +  call assert_equal('',                                            lines[41]) +  call assert_equal('FUNCTIONS SORTED ON TOTAL TIME',              lines[42]) +  call assert_equal('count  total (s)   self (s)  function',       lines[43]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[44]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[45]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[46]) +  call assert_equal('',                                            lines[47]) +  call assert_equal('FUNCTIONS SORTED ON SELF TIME',               lines[48]) +  call assert_equal('count  total (s)   self (s)  function',       lines[49]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[50]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[51]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[52]) +  call assert_equal('',                                            lines[53]) + +  call delete('Xprofile_func.vim') +  call delete('Xprofile_func.log') +endfunc + +func Test_profile_func_with_trycatch() +  let lines = [ +    \ "func! Foo1()", +    \ "  try", +    \ "    let x = 0", +    \ "  catch", +    \ "    let x = 1", +    \ "  finally", +    \ "    let x = 2", +    \ "  endtry", +    \ "endfunc", +    \ "func! Foo2()", +    \ "  try", +    \ "    throw 0", +    \ "  catch", +    \ "    let x = 1", +    \ "  finally", +    \ "    let x = 2", +    \ "  endtry", +    \ "endfunc", +    \ "func! Foo3()", +    \ "  try", +    \ "    throw 0", +    \ "  catch", +    \ "    throw 1", +    \ "  finally", +    \ "    let x = 2", +    \ "  endtry", +    \ "endfunc", +    \ "call Foo1()", +    \ "call Foo2()", +    \ "try", +    \ "  call Foo3()", +    \ "catch", +    \ "endtry", +    \ ] + +  call writefile(lines, 'Xprofile_func.vim') +  call system(v:progpath +    \ . ' -es -u NONE -U NONE -i NONE --noplugin' +    \ . ' -c "profile start Xprofile_func.log"' +    \ . ' -c "profile func Foo*"' +    \ . ' -c "so Xprofile_func.vim"' +    \ . ' -c "qall!"') +  call assert_equal(0, v:shell_error) + +  let lines = readfile('Xprofile_func.log') + +  " - Foo1() should pass 'try' 'finally' blocks. +  " - Foo2() should pass 'catch' 'finally' blocks. +  " - Foo3() should not pass 'endtry'. +  call assert_equal(54, len(lines)) + +  call assert_equal('FUNCTION  Foo1()',                            lines[0]) +  call assert_equal('Called 1 time',                               lines[1]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[2]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[3]) +  call assert_equal('',                                            lines[4]) +  call assert_equal('count  total (s)   self (s)',                 lines[5]) +  call assert_match('^\s*1\s\+.*\stry$',                           lines[6]) +  call assert_match('^\s*1\s\+.*\s  let x = 0$',                   lines[7]) +  call assert_match(        '^\s\+catch$',                         lines[8]) +  call assert_match(          '^\s\+let x = 1$',                   lines[9]) +  call assert_match('^\s*1\s\+.*\sfinally$',                       lines[10]) +  call assert_match('^\s*1\s\+.*\s  let x = 2$',                   lines[11]) +  call assert_match('^\s*1\s\+.*\sendtry$',                        lines[12]) +  call assert_equal('',                                            lines[13]) +  call assert_equal('FUNCTION  Foo2()',                            lines[14]) +  call assert_equal('Called 1 time',                               lines[15]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[16]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[17]) +  call assert_equal('',                                            lines[18]) +  call assert_equal('count  total (s)   self (s)',                 lines[19]) +  call assert_match('^\s*1\s\+.*\stry$',                           lines[20]) +  call assert_match('^\s*1\s\+.*\s  throw 0$',                     lines[21]) +  call assert_match('^\s*1\s\+.*\scatch$',                         lines[22]) +  call assert_match('^\s*1\s\+.*\s  let x = 1$',                   lines[23]) +  call assert_match('^\s*1\s\+.*\sfinally$',                       lines[24]) +  call assert_match('^\s*1\s\+.*\s  let x = 2$',                   lines[25]) +  call assert_match('^\s*1\s\+.*\sendtry$',                        lines[26]) +  call assert_equal('',                                            lines[27]) +  call assert_equal('FUNCTION  Foo3()',                            lines[28]) +  call assert_equal('Called 1 time',                               lines[29]) +  call assert_match('^Total time:\s\+\d\+\.\d\+$',                 lines[30]) +  call assert_match('^ Self time:\s\+\d\+\.\d\+$',                 lines[31]) +  call assert_equal('',                                            lines[32]) +  call assert_equal('count  total (s)   self (s)',                 lines[33]) +  call assert_match('^\s*1\s\+.*\stry$',                           lines[34]) +  call assert_match('^\s*1\s\+.*\s  throw 0$',                     lines[35]) +  call assert_match('^\s*1\s\+.*\scatch$',                         lines[36]) +  call assert_match('^\s*1\s\+.*\s  throw 1$',                     lines[37]) +  call assert_match('^\s*1\s\+.*\sfinally$',                       lines[38]) +  call assert_match('^\s*1\s\+.*\s  let x = 2$',                   lines[39]) +  call assert_match(        '^\s\+endtry$',                        lines[40]) +  call assert_equal('',                                            lines[41]) +  call assert_equal('FUNCTIONS SORTED ON TOTAL TIME',              lines[42]) +  call assert_equal('count  total (s)   self (s)  function',       lines[43]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[44]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[45]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[46]) +  call assert_equal('',                                            lines[47]) +  call assert_equal('FUNCTIONS SORTED ON SELF TIME',               lines[48]) +  call assert_equal('count  total (s)   self (s)  function',       lines[49]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[50]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[51]) +  call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$',              lines[52]) +  call assert_equal('',                                            lines[53]) + +  call delete('Xprofile_func.vim') +  call delete('Xprofile_func.log') +endfunc +  func Test_profile_file()    let lines = [      \ 'func! Foo()', @@ -123,7 +344,7 @@ func Test_profile_file()    call assert_equal('                              " a comment',      lines[9])    " if self and total are equal we only get one number    call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10]) -  call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$',                lines[11]) +  call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$',                lines[11])    " if self and total are equal we only get one number    call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])    call assert_equal('',                                               lines[13]) | 
