Thanks, Simon and others for the helpful comments.

Even caching the result of the scope analysis (#1072939) will likely be
slow for our use case, if the first hit of each breakpoint still requires
re-parsing the whole script. I think we'll be looking for alternative
methods at this point (e.g., adding our TRACE calls).

In the meantime, I measured the time reduction if Chrome were to re-parse
functions
<https://source.chromium.org/chromium/chromium/src/+/master:v8/src/debug/debug-scopes.cc;l=274>
(not whole scripts) in TryParseAndRetrieveScopes: it reduced the time for
each DebugBreakOnBytecode from 12-13 ms to 0.25 ms for our test case.
(Admittedly these figures depend on script and function length, and not
reparsing the whole script may possibly yield incorrect evaluations).

Thanks so much,
Gunes


On Wed, Oct 7, 2020 at 9:04 AM Simon Zünd <[email protected]> wrote:

> We discussed this actually on this bug:
> https://bugs.chromium.org/p/chromium/issues/detail?id=1072939
>
> In essence, for local debug-evaluate there is not really an "anchor" where
> we can put a scope information cache. For conditional breakpoints it's
> easier, we use the breakpoint itself. So ideally we only re-parse the first
> time a conditional breakpoint is hit, cache the parsed scope information on
> the breakpoint and then re-use it on future breakpoint hits to evaluate the
> break condition. Given that this is not an issue for most users of
> conditional breakpoints, implementing the fix has (unfortunately) lower
> priority.
>
> On Tue, Oct 6, 2020 at 3:32 PM Jakob Kummerow <[email protected]>
> wrote:
>
>> You can get some function call tracing data by using the --trace flag.
>> No breakpoints or parsing required -- but you also don't get to
>> choose/configure the data that's produced.
>>
>>
>> On Tue, Oct 6, 2020 at 2:20 PM Yang Guo <[email protected]> wrote:
>>
>>> Yes, indeed. When evaluating a conditional breakpoint, we reconstruct
>>> the entire scope chain for the break position in order to evaluate the
>>> condition expression as if it was inserted at the break location. Some of
>>> this scope information can no longer be reconstructed without parsing, so
>>> we indeed need to parse. We enter the parser from here
>>> <https://source.chromium.org/chromium/chromium/src/+/master:v8/src/debug/debug-scopes.cc;l=270>
>>> .
>>>
>>> It is possible to avoid repeated parsing if we cache the scope
>>> information for debugging. We have not implemented that because usually,
>>> hitting breakpoints and resuming is an interactive process so that
>>> reasonably slow performance is not a deal breaker.
>>>
>>> +Simon Zünd <[email protected]> probably can point to a tracking issue
>>> for this.
>>>
>>> Cheers,
>>>
>>> Yang
>>>
>>> On Tue, Oct 6, 2020 at 2:13 PM 'Seth Brenith' via v8-dev <
>>> [email protected]> wrote:
>>>
>>>> I haven't looked into the details, but it sort of makes sense that
>>>> evaluating a breakpoint condition would require reparsing. Conditional
>>>> breakpoints are basically a local eval(), which can bind to variables from
>>>> any enclosing scope by name. But if those scopes didn't contain the word
>>>> "eval" during the original parse, then they had no reason to keep full
>>>> variable data around. There's no way to reparse every enclosing scope
>>>> without at least lazy-parsing through the rest of the code in the file. And
>>>> lazy-parsing the rest of the file could cause this exact problem, because
>>>> presumably we don't save full local-eval data for the other functions which
>>>> might also have conditional breakpoints.
>>>>
>>>>
>>>>
>>>> ------------------------------
>>>> *From:* [email protected] <[email protected]> on behalf of
>>>> Gunes Acar <[email protected]>
>>>> *Sent:* Tuesday, October 6, 2020 4:27 AM
>>>> *To:* [email protected] <[email protected]>
>>>> *Subject:* [EXTERNAL] Re: [v8-dev] Re: Breakpoints trigger repeated
>>>> full-parse of the debugged script
>>>>
>>>> Thank you, Leszek and Dan for the suggestions.
>>>>
>>>> I tried passing
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgist.github.com%2Fgunesacar%2F2daf6cca049b10c832536591f69b58a8%23file-breakpoint_perf-js-L77&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933671070%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=dzGy5XoFPLbBzlHfGI7rZ3OUZXDYual8mibiaEUn6ho%3D&reserved=0>
>>>> --no-enable-lazy-source-positions, but I still get full script parses for
>>>> each hit breakpoint.
>>>>
>>>> I put together the small repro
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgist.github.com%2Fgunesacar%2F2daf6cca049b10c832536591f69b58a8&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933681022%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=zx%2BJY37H2gp8zH4971RK3AAnaJV2whXSTsaKWnKy7Nk%3D&reserved=0>
>>>> that Dan suggested. It uses Puppeteer, although passing `headless=false`
>>>> didn't change things either.
>>>>
>>>> The script will print instructions
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgist.github.com%2Fgunesacar%2F2daf6cca049b10c832536591f69b58a8%23file-breakpoint_perf-js-L175-L177&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933681022%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=Ubhe8tD3PavmL%2F%2FkfH3gskQwZlOAGv9Qyw9sXPYSmx4%3D&reserved=0>
>>>> to count the number of full parses in the logs. Let me know if I can make
>>>> it easier for you to reproduce the issue.
>>>>
>>>> Thanks again,
>>>> Gunes
>>>>
>>>>
>>>>
>>>> On Tue, Oct 6, 2020 at 10:23 AM Dan Elphick <[email protected]>
>>>> wrote:
>>>>
>>>> If it is down to lazy source positions, then what *should* happen is
>>>> that it would reparse each function at the point that you set the
>>>> breakpoint as otherwise it wouldn't know where to set it. In that case you
>>>> would get 1000 function reparses. It shouldn't need to reparse every
>>>> function each time, because a) it only needs the source positions for the
>>>> function it's setting the break point on and b) it doesn't need to parse
>>>> the entire program to do that.
>>>>
>>>> As Leszek says, disabling the feature via the flag would tell you if
>>>> it's responsible.
>>>>
>>>> The code in your gist is just the code to be debugged, but not the code
>>>> that sets the break points. A repro with just 10 functions should be
>>>> sufficient to show that it's doing 100 reparses and we can go from there.
>>>>
>>>> Thanks,
>>>> Dan
>>>>
>>>> On Tue, 6 Oct 2020 at 09:08, Leszek Swirski <[email protected]>
>>>> wrote:
>>>>
>>>> This might be lazy source positions forcing a reparse, have you tried
>>>> running with --no-enable-lazy-source-positions?
>>>>
>>>> On Tue, Oct 6, 2020 at 3:23 AM Gunes Acar <[email protected]> wrote:
>>>>
>>>> The missing screenshot of the trace can be seen at: Github:
>>>> https://gist.github.com/gunesacar/b8f82266e93fbfda2bf06c573af3caea#gistcomment-3478635
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgist.github.com%2Fgunesacar%2Fb8f82266e93fbfda2bf06c573af3caea%23gistcomment-3478635&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933690981%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=rZ2L%2FyZpm6jrpQkkIMlyl2DBnltBALX0NpjVWUze3KY%3D&reserved=0>
>>>>
>>>> On Tuesday, October 6, 2020 at 3:15:53 AM UTC+2 Gunes Acar wrote:
>>>>
>>>> Hi all,
>>>>
>>>> For an academic research project, we use Chrome Devtools Protocol to
>>>> set breakpoints at function returns, and collect function call metadata
>>>> (stack frames, arguments, timestamps) using a condition script(*).
>>>>
>>>> Although the condition script always returns `false` to avoid pausing
>>>> the debugger, we still observe a significant overhead per "hit" breakpoint.
>>>>
>>>> To identify the root cause, we set up tracing and found that
>>>> *V8.ParseProgram* is called for each "hit" breakpoint. We then logged
>>>> function events using "*--js-flags=--log-function-events*", which
>>>> showed that all functions in the debugged script is *fully parsed*
>>>> (i.e., `function,full-parse,...` event) for each "hit" breakpoint.
>>>>
>>>>
>>>> For example, assume the debugged script contains 10K function
>>>> definitions, of which only a 100 is called. We observe ~10K*100=~1M
>>>> function (full-)parse events in the logs, which slows down the process and
>>>> makes it unfeasible on heavy websites.
>>>>
>>>> 1) Is it possible to prevent repeated parsing of the debugged script
>>>> for each evaluated breakpoint?
>>>>
>>>> 2) Could there be an easier and faster way of logging all function
>>>> calls with the associated stack frames and arguments? Pointers to the
>>>> relevant code locations would be much appreciated if modifying Chrome/V8
>>>> source code is the only way to do that.
>>>> The trace and test files can be found in this Gist
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgist.github.com%2Fgunesacar%2Fb8f82266e93fbfda2bf06c573af3caea%23file-trace-json&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933690981%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=bKo0KZMWMvSK1CDP959M2V0bDfGe0J%2Feg1zZFwb4%2Fc8%3D&reserved=0>.
>>>>
>>>>
>>>> Thanks so much and stay safe,
>>>> Gunes
>>>>
>>>> PS: None of our breakpoints were actually hit, since the condition
>>>> script always returns false. Also, the debugged scripts were not modified
>>>> during the execution through `Debugger.setScriptSource` or by any other
>>>> means
>>>>
>>>> *: Idea from the DuckDuckGo’s Tracker Radar Collector
>>>> <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fduckduckgo%2Ftracker-radar-collector%2Fblob%2F98fa0f5a00016a2d10a43d86e16b38601f7ee387%2Fcollectors%2FAPICalls%2FTrackerTracker.js%23L76&data=04%7C01%7Cseth.brenith%40microsoft.com%7Ca7e89172bb6644c6c01408d869eacc4b%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637375805933700937%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=JQU1Tw77WyLQS3EOARYO7lb0GnqvI%2FjSXfA8oX4xBvs%3D&reserved=0>
>>>>
>>>>
>>>>
>>>

-- 
-- 
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- 
You received this message because you are subscribed to the Google Groups 
"v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/v8-dev/CABb%3D4dVgJ60EuVGc4vOPUhj00Xf09Md1dYSVoAvzeVi%3Dm11AJA%40mail.gmail.com.

Reply via email to