diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 7cc2493b83f8e9..a2abfc0485e57a 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 5 #define V8_MINOR_VERSION 4 #define V8_BUILD_NUMBER 500 -#define V8_PATCH_LEVEL 31 +#define V8_PATCH_LEVEL 36 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/compiler/js-builtin-reducer.cc b/deps/v8/src/compiler/js-builtin-reducer.cc index bbd5a92a7fd040..926bd3f715af6b 100644 --- a/deps/v8/src/compiler/js-builtin-reducer.cc +++ b/deps/v8/src/compiler/js-builtin-reducer.cc @@ -145,11 +145,16 @@ bool CanInlineArrayResizeOperation(Handle receiver_map) { if (!receiver_map->prototype()->IsJSArray()) return false; Handle receiver_prototype(JSArray::cast(receiver_map->prototype()), isolate); + // Ensure that all prototypes of the {receiver} are stable. + for (PrototypeIterator it(isolate, receiver_prototype, kStartAtReceiver); + !it.IsAtEnd(); it.Advance()) { + Handle current = PrototypeIterator::GetCurrent(it); + if (!current->map()->is_stable()) return false; + } return receiver_map->instance_type() == JS_ARRAY_TYPE && IsFastElementsKind(receiver_map->elements_kind()) && !receiver_map->is_dictionary_map() && receiver_map->is_extensible() && (!receiver_map->is_prototype_map() || receiver_map->is_stable()) && - receiver_prototype->map()->is_stable() && isolate->IsFastArrayConstructorPrototypeChainIntact() && isolate->IsAnyInitialArrayPrototype(receiver_prototype) && !IsReadOnlyLengthDescriptor(receiver_map); @@ -308,6 +313,10 @@ Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) { AccessBuilder::ForFixedArrayElement(receiver_map->elements_kind())), elements, length, value, effect, control); + // Return the new length of the {receiver}. + value = graph()->NewNode(simplified()->NumberAdd(), length, + jsgraph()->OneConstant()); + ReplaceWithValue(node, value, effect, control); return Replace(value); } diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc index b501b7ac250522..b76744e199241e 100644 --- a/deps/v8/src/compiler/js-native-context-specialization.cc +++ b/deps/v8/src/compiler/js-native-context-specialization.cc @@ -614,7 +614,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( fallthrough_control); this_controls.push_back( graph()->NewNode(common()->IfTrue(), branch)); - this_effects.push_back(effect); + this_effects.push_back(this_effect); fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); } diff --git a/deps/v8/src/compiler/typer.cc b/deps/v8/src/compiler/typer.cc index 6733bd6affeb05..0d07053dedd0a7 100644 --- a/deps/v8/src/compiler/typer.cc +++ b/deps/v8/src/compiler/typer.cc @@ -1352,6 +1352,8 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) { case kArrayIndexOf: case kArrayLastIndexOf: return Type::Range(-1, kMaxSafeInteger, t->zone()); + case kArrayPush: + return t->cache_.kPositiveSafeInteger; // Object functions. case kObjectHasOwnProperty: return Type::Boolean(); diff --git a/deps/v8/src/crankshaft/hydrogen-instructions.cc b/deps/v8/src/crankshaft/hydrogen-instructions.cc index b8020c72706491..9fed9612c6e909 100644 --- a/deps/v8/src/crankshaft/hydrogen-instructions.cc +++ b/deps/v8/src/crankshaft/hydrogen-instructions.cc @@ -259,7 +259,11 @@ bool Range::AddAndCheckOverflow(const Representation& r, Range* other) { bool may_overflow = false; lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow); upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow); - KeepOrder(); + if (may_overflow) { + Clear(); + } else { + KeepOrder(); + } #ifdef DEBUG Verify(); #endif @@ -271,13 +275,21 @@ bool Range::SubAndCheckOverflow(const Representation& r, Range* other) { bool may_overflow = false; lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow); upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow); - KeepOrder(); + if (may_overflow) { + Clear(); + } else { + KeepOrder(); + } #ifdef DEBUG Verify(); #endif return may_overflow; } +void Range::Clear() { + lower_ = kMinInt; + upper_ = kMaxInt; +} void Range::KeepOrder() { if (lower_ > upper_) { @@ -301,8 +313,12 @@ bool Range::MulAndCheckOverflow(const Representation& r, Range* other) { int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow); int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow); int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow); - lower_ = Min(Min(v1, v2), Min(v3, v4)); - upper_ = Max(Max(v1, v2), Max(v3, v4)); + if (may_overflow) { + Clear(); + } else { + lower_ = Min(Min(v1, v2), Min(v3, v4)); + upper_ = Max(Max(v1, v2), Max(v3, v4)); + } #ifdef DEBUG Verify(); #endif @@ -3184,6 +3200,13 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, return false; } + if (IsAllocationFoldingDominator()) { + if (FLAG_trace_allocation_folding) { + PrintF("#%d (%s) cannot fold into #%d (%s), already dominator\n", id(), + Mnemonic(), dominator->id(), dominator->Mnemonic()); + } + return false; + } if (!IsFoldable(dominator_allocate)) { if (FLAG_trace_allocation_folding) { @@ -3235,17 +3258,6 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, } } - if (IsAllocationFoldingDominator()) { - DeleteAndReplaceWith(dominator_allocate); - if (FLAG_trace_allocation_folding) { - PrintF( - "#%d (%s) folded dominator into #%d (%s), new dominator size: %d\n", - id(), Mnemonic(), dominator_allocate->id(), - dominator_allocate->Mnemonic(), new_dominator_size); - } - return true; - } - if (!dominator_allocate->IsAllocationFoldingDominator()) { HAllocate* first_alloc = HAllocate::New(isolate, zone, dominator_allocate->context(), @@ -3280,6 +3292,8 @@ std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT if (IsOldSpaceAllocation()) os << "P"; if (MustAllocateDoubleAligned()) os << "A"; if (MustPrefillWithFiller()) os << "F"; + if (IsAllocationFoldingDominator()) os << "d"; + if (IsAllocationFolded()) os << "f"; return os << ")"; } diff --git a/deps/v8/src/crankshaft/hydrogen-instructions.h b/deps/v8/src/crankshaft/hydrogen-instructions.h index 98c7275f8558c5..41b1e1be8bf047 100644 --- a/deps/v8/src/crankshaft/hydrogen-instructions.h +++ b/deps/v8/src/crankshaft/hydrogen-instructions.h @@ -237,6 +237,7 @@ class Range final : public ZoneObject { lower_ = Max(lower_, Smi::kMinValue); upper_ = Min(upper_, Smi::kMaxValue); } + void Clear(); void KeepOrder(); #ifdef DEBUG void Verify() const; @@ -4935,7 +4936,7 @@ class HAllocate final : public HTemplateInstruction<3> { static_cast(flags_ | ALLOCATION_FOLDING_DOMINATOR); } - bool IsAllocationFoldingDominator() { + bool IsAllocationFoldingDominator() const { return (flags_ & ALLOCATION_FOLDING_DOMINATOR) != 0; } @@ -4946,7 +4947,7 @@ class HAllocate final : public HTemplateInstruction<3> { SetOperandAt(2, dominator); } - bool IsAllocationFolded() { return (flags_ & ALLOCATION_FOLDED) != 0; } + bool IsAllocationFolded() const { return (flags_ & ALLOCATION_FOLDED) != 0; } bool HandleSideEffectDominator(GVNFlag side_effect, HValue* dominator) override; diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 25571470dce954..cfc2de8f3866a7 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -4506,9 +4506,6 @@ Block* Parser::BuildParameterInitializationBlock( // TODO(adamk): Should this be kNoSourcePosition, since // it's just copying from a temp var to the real param var? descriptor.initialization_pos = parameter.pattern->position(); - // The initializer position which will end up in, - // Variable::initializer_position(), used for hole check elimination. - int initializer_position = parameter.pattern->position(); Expression* initial_value = factory()->NewVariableProxy(parameters.scope->parameter(i)); if (parameter.initializer != nullptr) { @@ -4524,7 +4521,6 @@ Block* Parser::BuildParameterInitializationBlock( initial_value = factory()->NewConditional( condition, parameter.initializer, initial_value, kNoSourcePosition); descriptor.initialization_pos = parameter.initializer->position(); - initializer_position = parameter.initializer_end_position; } Scope* param_scope = scope(); @@ -4547,7 +4543,7 @@ Block* Parser::BuildParameterInitializationBlock( BlockState block_state(&scope_state_, param_scope); DeclarationParsingResult::Declaration decl( - parameter.pattern, initializer_position, initial_value); + parameter.pattern, parameter.initializer_end_position, initial_value); PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr, CHECK_OK); diff --git a/deps/v8/test/mjsunit/regress/regress-5454.js b/deps/v8/test/mjsunit/regress/regress-5454.js new file mode 100644 index 00000000000000..ca6a9433b24025 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-5454.js @@ -0,0 +1,11 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assertThrows(function(...[b = !b]) { }, ReferenceError); +assertThrows(() => (function([b = !b]) { })([]), ReferenceError); +assertThrows(() => (function({b = !b}) { })({}), ReferenceError); + +assertThrows((...[b = !b]) => { }, ReferenceError); +assertThrows(() => (([b = !b]) => { })([]), ReferenceError); +assertThrows(() => (({b = !b}) => { })({}), ReferenceError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-621868.js b/deps/v8/test/mjsunit/regress/regress-crbug-621868.js new file mode 100644 index 00000000000000..dcd7b8755bad3f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-621868.js @@ -0,0 +1,20 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --verify-heap + +function f(a) { // First parameter is tagged. + var n = 1 + a; +} + +function g() { + f(); + var d = {x : f()}; + return [d]; +} + +g(); +g(); +%OptimizeFunctionOnNextCall(g); +g(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-644689-1.js b/deps/v8/test/mjsunit/regress/regress-crbug-644689-1.js new file mode 100644 index 00000000000000..49bf90204725c6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-644689-1.js @@ -0,0 +1,14 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +for (var i = 0; i < 1024; ++i) Object.prototype["i" + i] = i; + +function foo() { [].push(1); } + +foo(); +foo(); +%OptimizeFunctionOnNextCall(foo); +foo(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-644689-2.js b/deps/v8/test/mjsunit/regress/regress-crbug-644689-2.js new file mode 100644 index 00000000000000..03831b15a8c979 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-644689-2.js @@ -0,0 +1,14 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +for (var i = 0; i < 1024; ++i) Object.prototype["i" + i] = i; + +function foo() { [1].pop(); } + +foo(); +foo(); +%OptimizeFunctionOnNextCall(foo); +foo(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-645438.js b/deps/v8/test/mjsunit/regress/regress-crbug-645438.js new file mode 100644 index 00000000000000..ff171524a03ee6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-645438.js @@ -0,0 +1,16 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function n(x,y){ + y = (y-(0x80000000|0)|0); + return (x/y)|0; +}; +var x = -0x80000000; +var y = 0x7fffffff; +n(x,y); +n(x,y); +%OptimizeFunctionOnNextCall(n); +assertEquals(x, n(x,y)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-655004.js b/deps/v8/test/mjsunit/regress/regress-crbug-655004.js new file mode 100644 index 00000000000000..1cba1efc826969 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-655004.js @@ -0,0 +1,15 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function foo(a) { + a.x = 0; + if (a.x === 0) a[1] = 0.1; + a.x = {}; +} +foo(new Array(1)); +foo(new Array(1)); +%OptimizeFunctionOnNextCall(foo); +foo(new Array(1)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-656037.js b/deps/v8/test/mjsunit/regress/regress-crbug-656037.js new file mode 100644 index 00000000000000..47d09aaa4b9d46 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-656037.js @@ -0,0 +1,15 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function foo(a) { + return a.push(true); +} + +var a = []; +assertEquals(1, foo(a)); +assertEquals(2, foo(a)); +%OptimizeFunctionOnNextCall(foo); +assertEquals(3, foo(a));