Fix assert in stub-cache.cc when loading qml-mode functions
authorKent Hansen <kent.hansen@nokia.com>
Tue, 20 Mar 2012 13:13:31 +0000 (14:13 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 20 Mar 2012 15:15:25 +0000 (16:15 +0100)
commit70adcad251ae129c15e5146c54bb3e0c11ee728f
tree53ba29a190f4d8d1dbb60e1280053fc2edcc8a16
parente4b7d4364ba3813655692a4f519658fbd2d7a9c4
Fix assert in stub-cache.cc when loading qml-mode functions

Commit c511fa8a6a631e45ee4075453bcb2eeb7f01ba63 introduced a
regression that could cause an assert in V8 to be triggered:

Fatal error in ../3rdparty/v8/src/stub-cache.cc, line 1171
CHECK(!CallIC::Contextual::decode( Code::ExtractExtraICStateFromFlags(flags))) failed

The assert would be triggered when 1) the "QML global object"
(implicit receiver in qml-mode evaluation) defined more than 12
properties, and 2) a function property of the QML global object was
looked up at least twice from JavaScript. In particular, the V8 IC
would assert that there should be an explicit receiver when
advancing the function lookup from pre-monomorphic state to
monomorphic state.

(The magic number 12 (number of properties needed to trigger the bug)
is the kMaxFastProperties constant. This is the threshold where V8
switches to using a dictionary for the object storage, instead of
using "fast properties" (array).)

The IC correctly determines that the property holder object (the QML
global object) is not the JS Global Object, and hence compiles it as
a "normal" call, in which it asserts that "there must be an explicit
receiver here". But in QML mode, the receiver can be implicit when
the holder is the QML global object.

Propagate this information to the stub cache to avoid the assert
triggering. The generated JIT code still works as expected when the
receiver is implicit (i.e., the receiver is always loaded).
None of the other property/function-load IC handlers have a similar
assert.

It might be worth investigating whether "QML global object" property
loading should have dedicated cache stubs; e.g. a
ComputeCallQmlGlobal() akin to ComputeCallGlobal(). This could
potentially simplify/speed up the generated code, since we can take
advantage of the read-only nature of the QML global object type right
off the bat. But that's a bigger change that would require all the
JIT compilers and the GC to be adapted.

Task-number: QTBUG-24871
Change-Id: I55e499d9c61ff264e3a96e5628e2f30292ee565d
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
src/3rdparty/v8/src/ic.cc
src/3rdparty/v8/src/stub-cache.cc
src/3rdparty/v8/src/stub-cache.h
tests/auto/v8/tst_v8.cpp
tests/auto/v8/v8test.cpp
tests/auto/v8/v8test.h