summaryrefslogtreecommitdiff
path: root/tests/auto/v8/v8test.cpp
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-03-20 14:13:31 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-20 16:15:25 +0100
commit70adcad251ae129c15e5146c54bb3e0c11ee728f (patch)
tree53ba29a190f4d8d1dbb60e1280053fc2edcc8a16 /tests/auto/v8/v8test.cpp
parente4b7d4364ba3813655692a4f519658fbd2d7a9c4 (diff)
downloadqtjsbackend-70adcad251ae129c15e5146c54bb3e0c11ee728f.tar.gz
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>
Diffstat (limited to 'tests/auto/v8/v8test.cpp')
-rw-r--r--tests/auto/v8/v8test.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/tests/auto/v8/v8test.cpp b/tests/auto/v8/v8test.cpp
index f0d3aa8..3ea313f 100644
--- a/tests/auto/v8/v8test.cpp
+++ b/tests/auto/v8/v8test.cpp
@@ -493,5 +493,41 @@ cleanup:
ENDTEST();
}
+bool v8test_qtbug_24871()
+{
+ BEGINTEST();
+
+ HandleScope handle_scope;
+ Persistent<Context> context = Context::New();
+ Context::Scope context_scope(context);
+
+ Local<Object> qmlglobal = Object::New();
+
+ Local<Script> script = Script::Compile(String::New(
+ // Create a bunch of properties to exceed kMaxFastProperties
+ "var a1, a2, a3, a4, a5, a6, a7, a8;\n"
+ "var b1, b2, b3, b4, b5, b6, b7, b8;\n"
+ "var c1, c2, c3, c4, c5, c6, c7, c8;\n"
+ "var d1, d2, d3, d4, d5, d6, d7, d8;\n"
+ "function index(a) { return a + 1; }\n"
+ "function init() {\n"
+ " for (var i = 0; i < 300; ++i)\n"
+ " index(i);\n"
+ "}\n"
+ "init();"), NULL, NULL,
+ Handle<String>(), Script::QmlMode);
+
+ TryCatch tc;
+ Local<Value> result = script->Run(qmlglobal);
+
+ VERIFY(!tc.HasCaught());
+ VERIFY(result->IsUndefined());
+
+cleanup:
+ context.Dispose();
+
+ ENDTEST();
+}
+
#undef VARNAME
#undef VARVALUE