Thanks for the link to that video, I'll give it a look. Based on your
On Tue, Jul 17, 2012 at 3:32 PM, Jakob Kummerow <jkumme...
> Seems like you're finding out the hard way what a complicated beast a modern
> JS engine is ;-)
> --trace-deopt is certainly usable; but it is not geared towards ease-of-use
> Helpful flags are --print-opt-code and --code-comments. Those two together
> will print the disassembled code for *optimized* functions, interleaved with
> some comments, such as the IDs of the HIR instructions that generated the
> code (which is what the "@36" in your example refers to), and the
> deoptimization IDs ("bailout #7" in your example). And yes, there can be a
> code to V8 -- redirecting output to a file and opening that with an editor
> makes this easier to manage.
> Since disassembly is involved, --print-opt-code only works when V8 has been
> built with disassembler support. That's the case in a debug mode build, or
> in release mode when you specify GYPFLAGS="-Dv8_enable_disassembler=1" (when
> you build d8 with GYP/make, we have a convenience option for that: "make
> disassembler=on ia32.release"). If you build your own Chromium anyway, you
> can also change the flag's default value in src/v8/build/common.gypi, if you
> find that easier than setting an environment variable.
> Due to the optimizations that the optimizing compiler does, there is no
> mapping from assembly instructions (or deopt points) to line numbers. I'm
> not sure if and with how much effort it'd be possible to hack up support for
> that. I agree that it would be great if Chrome's dev tools could show you
> where deopts happened, and why...
> c1visualizer is still state of the art to visualize what the optimizing
> compiler does. Yes, it's a somewhat sorry state of things, but it can be
> very helpful. Probably more helpful for debugging the compiler than for
> large hydrogen.cfg dumps.
> There aren't all that many reasons for deopts, and it's relatively easy to
> learn which JS constructs can cause a deopt at all: mainly stuff that hasn't
> happened earlier, e.g. accessing a property of an object with a new type, or
> a double value suddenly being undefined, or code after a long-running loop
> that's never been executed before, or an array access out of bounds that was
> within bounds earlier, and so on. So with some experience, and assuming
> you're not running into bugs/deficiencies of V8, staring at assembly code
> won't even be necessary. Also, if you find that by refactoring your function
> (e.g. splitting it into two smaller functions) you can prevent the deopt,
> that's not really a problem, is it? It's kind of the solution you were
> looking for in the first place, right?
> [Btw, there's a pretty recent video of a talk that explains some of this,
> and mentions some common pitfalls to avoid:
> http://www.youtube.com/watch?v=UJPdhx5zTaw ]
> Ranting about flags or their output being cryptic may help you let off some
> steam, but beyond that doesn't get you anywhere. V8's command-line flags let
> you peek at V8's inner workings, and making sense of their output requires
> some understanding of these internals. Nobody ever claimed anything else.
> On Tue, Jul 17, 2012 at 8:34 PM, Kevin Gadd <kevin.g...@gmail.com> wrote:
>> I've spent the last couple hours trying to actually get anything useful
>> out of --trace-deopt. Unfortunately, I've had no success. I'm primarily
>> going off the information from
>> http://floitsch.blogspot.com/2012/03/optimizing-for-v8-inlining.html, as
>> it's the only detailed info I've found on the internet about --trace-deopt.
>> From what I can tell, the only way to use this feature seems to be in a
>> debug build of d8, and to map the offsets (I think they're offsets? Unable
>> to find information on this) in the deopt spew back to the generated
>> assembly from the JIT, using the --print-code option. I.E.:
>> **** DEOPT: MouseCursor_get_ClientBoundsWidth at bailout #7, address 0x0,
>> frame size 12
>> ;;; @36: deoptimize.
>> In this spew I *think* @36 refers to instruction #36 in the generated IR
>> from the JIT? It's unclear whether this is the high level IR or the low
>> level IR (hydrogen.cfg, when you can actually get c1visualizer to load it,
>> claims there are two kinds of IR - more on that later).
>> So, right off the bat, this seems less than helpful - --print-code
>> generates an absolutely titanic dump of all sorts of data and none of it is
>> correlated - nothing in the output ASM maps it back to the source JS, and
>> the IR (the IR that shows up in hydrogen.cfg) doesn't even seem to be there.
>> It's unclear what the @36 in this case would actually point to, or how once
>> I had located 36 I would map it back to a defect in my original source
>> of the opcodes are KIND OF self explanatory if you spend forever
>> understanding V8. But mapping the raw JIT assembly back to JS is just plain
>> nuts - there's way too much going on there to even understand what a given
>> deoptimization means if this is the only information I have.
>> Really, all I need here is a rough mapping that tells me what part of a
>> function is triggering a deoptimization. If V8 can't give me a reason (this
>> seems to almost universally be the case), then fine, I'll just figure it out
>> with brute force - but without knowing roughly what part of the function is
>> responsible it's impossible to do any real debugging or optimization here
>> (trying to binary search the function manually won't work, because changing
>> the size and structure of the function will change whether it deoptimizes
>> and where it deoptimizes).
>> suggests that it's possible to get at the IR using some debug flags, and
>> when I tried them out they indeed generate an enormous file named
>> hydrogen.cfg. Unfortunately, the tool the post suggests using - c1visualizer
>> - is either broken or does not support the version of the .cfg format Chrome
>> now spits out, because it fails to load almost every meaningfully large .cfg
>> file I've ever managed to get. When it does successfully load one, most of
>> the functions I care about are missing, which suggests that the file is
>> incomplete or their parser stopped early. The file is large and noisy enough
>> that I don't think I'd be able to make sense of it by hand without a
>> visualizer tool. Is there a working replacement for c1visualizer that the
>> Chrome team uses now? I searched for one but couldn't find anything. Do I
>> have to write my own visualizer?
>> Even if the enormous spew of raw assembly from d8 with --print-code and
>> --trace-deopt were usable (at present it doesn't seem usable without more
>> complete information), it doesn't feel like enough to solve real performance
>> issues. I'm looking at deoptimizations right now that only seem to occur
>> when actually running an application in Chrome (i.e. interacting with APIs
>> like WebGL and Canvas), which is where I actually care about performance - I
>> can't simply reduce all of these deoptimized functions into test cases
>> because they don't work without access to the rest of their dependencies.
>> It seems like maybe if I built a debug version of Chromium myself, I'd be
>> able to pass *it* --print-code, but then I'd be missing codecs like MP3,
>> and, I'd still have to deal with the enormous spew of data and raw assembly
>> All I really want is line numbers. Is this possible? Could I possibly get
>> it by hand-patching v8 in the right place and building my own Chromium?
>> Also, I could rant about how cryptic --trace-bailout is, but that feature
>> at least seems to work and provide actionable data (if you're willing to
>> grep through the v8 source code and try and understand what the terminology
>> means and set breakpoints to follow consequence chains and understand *why*
>> a particular bailout actually occurred). Really right now the
>> deoptimizations are my biggest concern because hundreds of them are
>> happening every second versus a very small number of bailouts.
> v8-users mailing list