Add support for lazy deoptimization from deferred stack checks (issue7212025)

105 views
Skip to first unread message

sgj...@chromium.org

unread,
Jul 5, 2011, 8:52:19 AM7/5/11
to kmil...@chromium.org, v8-...@googlegroups.com, ri...@chromium.org
Reviewers: Kevin Millikin,

Description:
Add support for lazy deoptimization from deferred stack checks

The debugger can be entered from the deferred stack check in optimized code.
This can cause both lazy deoptimization and debugger deoptimization
(setting the
first break point and inspecting the stack for optimized code respectively).
This required deoptimization support from the deferred stack check.

The lazy deoptimiztion call is inserted when the deferred code is done
including
restoring the registers. The bailout to the full code is the begining of the
loop body as that is where the stack check is sitting in the optimized
code. The
bailout is not to the stack check in the full code as that is sitting at
the end
of the loop.

R=kmil...@chromium.org

BUG=none
TEST=none


Please review this at http://codereview.chromium.org/7212025/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
M src/arm/lithium-codegen-arm.cc
M src/ast.h
M src/hydrogen.h
M src/hydrogen.cc
M src/ia32/lithium-codegen-ia32.cc
M src/x64/lithium-codegen-x64.cc
M test/cctest/test-debug.cc


kmil...@chromium.org

unread,
Jul 5, 2011, 9:09:42 AM7/5/11
to sgj...@chromium.org, v8-...@googlegroups.com, ri...@chromium.org

s...@google.com

unread,
Jul 5, 2011, 11:59:09 PM7/5/11
to sgj...@chromium.org, kmil...@chromium.org, v8-...@googlegroups.com, ri...@chromium.org

http://codereview.chromium.org/7212025/diff/1/src/ia32/lithium-codegen-ia32.cc
File src/ia32/lithium-codegen-ia32.cc (right):

http://codereview.chromium.org/7212025/diff/1/src/ia32/lithium-codegen-ia32.cc#newcode273
src/ia32/lithium-codegen-ia32.cc:273: // have room for lazy bailout.
I don't understand why the last piece of deferred code is special in the
need for some room for lazy bailout. Is the last piece special? If it
is special, this seems fragile. Perhaps in the future the deferred code
fragments get sorted in some way, e.g. to optimize the number of exit
jumps that can be in the short form. If the last piece of code is
always a certain kind of deferred code, the deferred code Generate
method should allocate the nops.

Please take a look at http://codereview.chromium.org/7277081/.
This change invalidates your assumption that the deferred code ends in a
jump to the exit label.
You can still make the deferred stack check end with a jump but please
don't force that constraint on other deferred code fragments. The
constraint is adding 2-3% extra code size.

http://codereview.chromium.org/7212025/

Kevin Millikin

unread,
Jul 6, 2011, 12:45:51 AM7/6/11
to sgj...@chromium.org, kmil...@chromium.org, s...@google.com, v8-...@googlegroups.com, ri...@chromium.org
Hi Stephen,

The last piece of deferred code is different because it's last---there's no code after it so it has to make its own space for patching and not rely on stomping the code after it.

Søren's change doesn't assume the jump (well, it does assume it because the identifier name "last_jump" used in the debug assertion is a bad name if there's not jump, but identifier's can be renamed---Søren, how about "deferred_end" or some such?).

;; Kevin

Søren Gjesse

unread,
Jul 6, 2011, 3:02:01 AM7/6/11
to Kevin Millikin, s...@google.com, v8-...@googlegroups.com, ri...@chromium.org
I did notice http://codereview.chromium.org/7277081/ yesterday and noticed that it might never reach the last jump. However the patching of the jump back to inline code is only relevant if the deferred code have calls which can lead to lazy deoptimization. And the deferred code for stack check is exactly such a place as this might enter the debugger. The deferred code for instance of is another such place I need to fix, as it might call into the builtins JavaScript potentially leading to lazy deoptimization.

Lazy deoptimization is what happens when all code in a context is forced to be deoptimized either due to starting debugging or due to a global assumption on the optimized code that no longer holds. The reason for the term "lazy" is that actual deoptimization will not happen until control returns to the optimized function. The way we do this lazy deoptimization is somewhat fragile and we have had quite a few bugs in that code. It is based on destructively patching the optimized code placing a call just after each call forcing deoptimization. And actually the patching is not right after the return point but after the gap code inserted at the return point. For the deferred stack check the code up to restoring the registers (popad in IA-32) is considered the gap code.

Bottom line: The change to DeferredTaggedToI is not affected by this as it has no lazy deoptimization points, and I will rename the label used for the assertion and add a comment.

Regards,
Søren
Reply all
Reply to author
Forward
0 new messages