This code crash node without notice:
"use strict";
var test = function () {
var random = 0 | Math.random()*1000;
var today = Date.now();
var o = {
['prop_' + random] : today,
random,
today
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test();
}
console.timeEnd('test');
When run this simple code, node 6.2.0 end without message. If I reduce the loop from 100.000 to 10.000, the code run perfectly and show
test: 14.188ms
This segfaults for me (x64 Linux) on current master. Output/stack trace from a debug build:
#
# Fatal error in ../deps/v8/src/type-info.cc, line 365
# Check failed: FeedbackVectorSlotKind::KEYED_STORE_IC == kind (KEYED_STORE_IC vs. INVALID).
#
==== C stack trace ===============================
1: V8_Fatal
2: v8::internal::TypeFeedbackOracle::CollectReceiverTypes(v8::internal::FeedbackVectorSlot, v8::internal::SmallMapList*)
3: v8::internal::AstTyper::VisitObjectLiteral(v8::internal::ObjectLiteral*)
4: v8::internal::ObjectLiteral::Accept(v8::internal::AstVisitor*)
5: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
6: v8::internal::AstTyper::VisitAssignment(v8::internal::Assignment*)
7: v8::internal::Assignment::Accept(v8::internal::AstVisitor*)
8: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
9: v8::internal::AstTyper::VisitExpressionStatement(v8::internal::ExpressionStatement*)
10: v8::internal::ExpressionStatement::Accept(v8::internal::AstVisitor*)
11: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
12: v8::internal::AstTyper::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
13: v8::internal::AstTyper::VisitBlock(v8::internal::Block*)
14: v8::internal::Block::Accept(v8::internal::AstVisitor*)
15: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
16: v8::internal::AstTyper::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
17: v8::internal::AstTyper::Run()
18: v8::internal::HOptimizedGraphBuilder::TryInline(v8::internal::Handle<v8::internal::JSFunction>, int, v8::internal::HValue*, v8::internal::BailoutId, v8::internal::BailoutId, v8::internal::InliningKind)
19: v8::internal::HOptimizedGraphBuilder::TryInlineCall(v8::internal::Call*)
20: v8::internal::HOptimizedGraphBuilder::VisitCall(v8::internal::Call*)
21: v8::internal::Call::Accept(v8::internal::AstVisitor*)
22: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
23: v8::internal::HOptimizedGraphBuilder::VisitForEffect(v8::internal::Expression*)
24: v8::internal::HOptimizedGraphBuilder::VisitExpressionStatement(v8::internal::ExpressionStatement*)
25: v8::internal::ExpressionStatement::Accept(v8::internal::AstVisitor*)
26: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
27: v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
28: v8::internal::HOptimizedGraphBuilder::VisitBlock(v8::internal::Block*)
29: v8::internal::Block::Accept(v8::internal::AstVisitor*)
30: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
31: v8::internal::HOptimizedGraphBuilder::VisitLoopBody(v8::internal::IterationStatement*, v8::internal::HBasicBlock*)
32: v8::internal::HOptimizedGraphBuilder::VisitForStatement(v8::internal::ForStatement*)
33: v8::internal::ForStatement::Accept(v8::internal::AstVisitor*)
34: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
35: v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
36: v8::internal::HOptimizedGraphBuilder::BuildGraph()
37: v8::internal::HGraphBuilder::CreateGraph()
38: v8::internal::OptimizedCompileJob::CreateGraph()
39: 0x13ec558
40: v8::internal::Compiler::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ConcurrencyMode, v8::internal::BailoutId, v8::internal::JavaScriptFrame*)
41: 0x1855904
42: v8::internal::Runtime_CompileForOnStackReplacement(int, v8::internal::Object**, v8::internal::Isolate*)
43: 0x12781bc0961b
/cc @nodejs/v8
Code reduced to this still ends without message.
var test = function () {
var t = Date.now();
var o = {
['p'] : 1,
t
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test();
}
console.timeEnd('test');
Could you please open an issue here: https://bugs.chromium.org/p/v8/issues/list
The same code also crashes on Chrome.
Any of these works properly:
var test = function () {
var t = Date.now();
var o = {
['p'] : 1,
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test();
}
console.timeEnd('test');
var test = function () {
var t = Date.now();
var o = {
'p' : 1,
t
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test();
}
console.timeEnd('test');
var test = function () {
var t = 0;
var o = {
['p'] : 1,
t
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test();
}
console.timeEnd('test');
var test = function (arg) {
var t = arg;
var o = {
['p'] : 1,
t
};
};
console.time('test');
for (var n = 0; n < 100000; n++) {
test(Date.now());
}
console.timeEnd('test');
I don't get a failed CHECK but it does segfault with master on x86_64 Linux:
(gdb) bt
#0 0x0000000000e7e611 in v8::internal::FeedbackNexus::ExtractMaps(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*) const ()
#1 0x0000000000e8589e in void v8::internal::TypeFeedbackOracle::CollectReceiverTypes<v8::internal::FeedbackNexus>(v8::internal::FeedbackNexus*, v8::internal::SmallMapList*) ()
#2 0x0000000000e85dfd in v8::internal::TypeFeedbackOracle::CollectReceiverTypes(v8::internal::FeedbackVectorSlot, v8::internal::SmallMapList*) ()
#3 0x0000000000b8f33b in v8::internal::AstTyper::VisitObjectLiteral(v8::internal::ObjectLiteral*) ()
#4 0x0000000000b91b41 in v8::internal::AstTyper::VisitAssignment(v8::internal::Assignment*) ()
#5 0x0000000000b929fc in v8::internal::AstTyper::VisitBlock(v8::internal::Block*) ()
#6 0x0000000000b8fb14 in v8::internal::AstTyper::Run() ()
#7 0x0000000000b775b1 in v8::internal::HOptimizedGraphBuilder::TryInline(v8::internal::Handle<v8::internal::JSFunction>, int, v8::internal::HValue*, v8::internal::BailoutId, v8::internal::BailoutId, v8::internal::InliningKind) ()
#8 0x0000000000b781b4 in v8::internal::HOptimizedGraphBuilder::TryInlineCall(v8::internal::Call*) ()
#9 0x0000000000b7f2b9 in v8::internal::HOptimizedGraphBuilder::VisitCall(v8::internal::Call*) ()
#10 0x0000000000b44158 in v8::internal::HOptimizedGraphBuilder::VisitForEffect(v8::internal::Expression*) ()
#11 0x0000000000b3d44d in v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*) ()
#12 0x0000000000b566df in v8::internal::HOptimizedGraphBuilder::VisitBlock(v8::internal::Block*) ()
#13 0x0000000000b5c7c3 in v8::internal::HOptimizedGraphBuilder::VisitForStatement(v8::internal::ForStatement*) ()
#14 0x0000000000b3d44d in v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*) ()
#15 0x0000000000b55725 in v8::internal::HOptimizedGraphBuilder::BuildGraph() ()
#16 0x0000000000b53994 in v8::internal::HGraphBuilder::CreateGraph() ()
#17 0x0000000000ae96f4 in v8::internal::OptimizedCompileJob::CreateGraph() ()
#18 0x0000000000ae99ad in v8::internal::GetOptimizedCodeNow(v8::internal::CompilationInfo*) ()
#19 0x0000000000aea245 in v8::internal::Compiler::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ConcurrencyMode, v8::internal::BailoutId, v8::internal::JavaScriptFrame*) ()
#20 0x0000000000dea228 in v8::internal::Runtime_CompileForOnStackReplacement(int, v8::internal::Object**, v8::internal::Isolate*) ()
Clearly a V8 bug.
Here is a similar backtrace from the Debug build:
#
# Fatal error in ../deps/v8/src/type-info.cc, line 365
# Check failed: FeedbackVectorSlotKind::KEYED_STORE_IC == kind (KEYED_STORE_IC vs. INVALID).
#
==== C stack trace ===============================
1: V8_Fatal
2: v8::internal::TypeFeedbackOracle::CollectReceiverTypes(v8::internal::FeedbackVectorSlot, v8::internal::SmallMapList*)
3: v8::internal::AstTyper::VisitObjectLiteral(v8::internal::ObjectLiteral*)
4: v8::internal::ObjectLiteral::Accept(v8::internal::AstVisitor*)
5: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
6: v8::internal::AstTyper::VisitAssignment(v8::internal::Assignment*)
7: v8::internal::Assignment::Accept(v8::internal::AstVisitor*)
8: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
9: v8::internal::AstTyper::VisitExpressionStatement(v8::internal::ExpressionStatement*)
10: v8::internal::ExpressionStatement::Accept(v8::internal::AstVisitor*)
11: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
12: v8::internal::AstTyper::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
13: v8::internal::AstTyper::VisitBlock(v8::internal::Block*)
14: v8::internal::Block::Accept(v8::internal::AstVisitor*)
15: v8::internal::AstTyper::Visit(v8::internal::AstNode*)
16: v8::internal::AstTyper::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
17: v8::internal::AstTyper::Run()
18: v8::internal::HOptimizedGraphBuilder::TryInline(v8::internal::Handle<v8::internal::JSFunction>, int, v8::internal::HValue*, v8::internal::BailoutId, v8::internal::BailoutId, v8::internal::InliningKind)
19: v8::internal::HOptimizedGraphBuilder::TryInlineCall(v8::internal::Call*)
20: v8::internal::HOptimizedGraphBuilder::VisitCall(v8::internal::Call*)
21: v8::internal::Call::Accept(v8::internal::AstVisitor*)
22: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
23: v8::internal::HOptimizedGraphBuilder::VisitForEffect(v8::internal::Expression*)
24: v8::internal::HOptimizedGraphBuilder::VisitExpressionStatement(v8::internal::ExpressionStatement*)
25: v8::internal::ExpressionStatement::Accept(v8::internal::AstVisitor*)
26: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
27: v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
28: v8::internal::HOptimizedGraphBuilder::VisitBlock(v8::internal::Block*)
29: v8::internal::Block::Accept(v8::internal::AstVisitor*)
30: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
31: v8::internal::HOptimizedGraphBuilder::VisitLoopBody(v8::internal::IterationStatement*, v8::internal::HBasicBlock*)
32: v8::internal::HOptimizedGraphBuilder::VisitForStatement(v8::internal::ForStatement*)
33: v8::internal::ForStatement::Accept(v8::internal::AstVisitor*)
34: v8::internal::HOptimizedGraphBuilder::Visit(v8::internal::AstNode*)
35: v8::internal::HOptimizedGraphBuilder::VisitStatements(v8::internal::ZoneList<v8::internal::Statement*>*)
36: v8::internal::HOptimizedGraphBuilder::BuildGraph()
37: v8::internal::HGraphBuilder::CreateGraph()
38: v8::internal::OptimizedCompileJob::CreateGraph()
39: v8::internal::GetOptimizedCodeNow(v8::internal::CompilationInfo*)
40: v8::internal::Compiler::GetOptimizedCode(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ConcurrencyMode, v8::internal::BailoutId, v8::internal::JavaScriptFrame*)
41: v8::internal::__RT_impl_Runtime_CompileForOnStackReplacement(v8::internal::Arguments, v8::internal::Isolate*)
42: v8::internal::Runtime_CompileForOnStackReplacement(int, v8::internal::Object**, v8::internal::Isolate*)
43: 0xc82e920959b
If the loop number <= 12290, it is OK. With loop number > 12290 there is permanent crash.
Opened issue upstream: https://bugs.chromium.org/p/v8/issues/detail?id=5033
The linked issues hint at it but for posterity, node --nocrankshaft works around it.
@bnoordhuis that's what one should expect after seeing HOptimizedGraphBuilder in a backtrace :)
As work around I prefer --turbo because the performance is slightly better and the code works.
BenchmarkJS (https://www.npmjs.com/package/benchmarkjs) has been the source of found this problem and show that the --turbo parameter gives a better result.
This simple variation works without problem:
var test = function () {
var random = 0 | Math.random()*1000;
var today = Date.now();
var o = {
random,
today,
['prop_' + random] : today
};
};
console.time('test');
for (var n = 0; n < 20000; n++) {
test();
}
console.timeEnd('test');
Only change the objet properties order. It's the better solution, but very very weird, but the optimization process is very complicated and the order of elements is very important.
Thanks
Segfaults:
var test = function () {
var o = {
['p']: 0,
x: Number.MAX_VALUE
}
};
console.time('test');
for (var n = 0; n < 12291; n++) {
test();
}
console.timeEnd('test');
Does not segfault:
var test = function () {
var o = {
['p']: 0,
x: Number.MAX_VALUE
}
};
console.time('test');
for (var n = 0; n < 12291; n++) {
test();
}
console.timeEnd('test');
console.log(Number.MAX_VALUE);
Only difference is the last console.log(Number.MAX_VALUE)
The issue has been fixed upstream. We are waiting for the backmerge.
Inquired about the status of the back-port: https://bugs.chromium.org/p/v8/issues/detail?id=5033#c15
It was merged into 5.1 and 5.2:
Version 5.2.361.28
Version 5.1.281.70
https://github.com/nodejs/node/pull/7863: pull request with the cherry-pick for 5.0
Closing as the fix landed in v6.x
For posterity, the fix is scheduled to be released in v6.4.0.