diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index e20af22fb4dcc3..0d920efac46d52 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 9 #define V8_BUILD_NUMBER 211 -#define V8_PATCH_LEVEL 32 +#define V8_PATCH_LEVEL 37 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/builtins/builtins-promise-gen.cc b/deps/v8/src/builtins/builtins-promise-gen.cc index b1412eb7cd5f81..1b236ec97c62ac 100644 --- a/deps/v8/src/builtins/builtins-promise-gen.cc +++ b/deps/v8/src/builtins/builtins-promise-gen.cc @@ -106,6 +106,10 @@ Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context, debug_event = TrueConstant(); } + Label if_not_constructor(this, Label::kDeferred); + GotoIf(TaggedIsSmi(constructor), &if_not_constructor); + GotoIfNot(IsConstructorMap(LoadMap(constructor)), &if_not_constructor); + Node* native_context = LoadNativeContext(context); Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex); @@ -189,6 +193,13 @@ Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context, Unreachable(); } + BIND(&if_not_constructor); + { + Node* const message_id = SmiConstant(MessageTemplate::kNotConstructor); + CallRuntime(Runtime::kThrowTypeError, context, message_id, constructor); + Unreachable(); + } + BIND(&out); return var_result.value(); } @@ -312,6 +323,7 @@ Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object, // 7. If IsConstructor(S) is true, return S. Label throw_error(this); + GotoIf(TaggedIsSmi(species), &throw_error); Node* species_bitfield = LoadMapBitField(LoadMap(species)); GotoIfNot(Word32Equal(Word32And(species_bitfield, Int32Constant((1 << Map::kIsConstructor))), diff --git a/deps/v8/src/compiler/escape-analysis.cc b/deps/v8/src/compiler/escape-analysis.cc index 2e0adc6f85a0ea..75a73ffce9be8e 100644 --- a/deps/v8/src/compiler/escape-analysis.cc +++ b/deps/v8/src/compiler/escape-analysis.cc @@ -853,6 +853,13 @@ bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep, case IrOpcode::kObjectIsString: case IrOpcode::kObjectIsSymbol: case IrOpcode::kObjectIsUndetectable: + case IrOpcode::kNumberLessThan: + case IrOpcode::kNumberLessThanOrEqual: + case IrOpcode::kNumberEqual: +#define CASE(opcode) case IrOpcode::k##opcode: + SIMPLIFIED_NUMBER_BINOP_LIST(CASE) + SIMPLIFIED_NUMBER_UNOP_LIST(CASE) +#undef CASE if (SetEscaped(rep)) { TRACE("Setting #%d (%s) to escaped because of use by #%d (%s)\n", rep->id(), rep->op()->mnemonic(), use->id(), diff --git a/deps/v8/src/safepoint-table.cc b/deps/v8/src/safepoint-table.cc index 03b68276dd8724..e9850b11d8bbb2 100644 --- a/deps/v8/src/safepoint-table.cc +++ b/deps/v8/src/safepoint-table.cc @@ -52,7 +52,12 @@ SafepointTable::SafepointTable(Code* code) { SafepointEntry SafepointTable::FindEntry(Address pc) const { unsigned pc_offset = static_cast(pc - code_->instruction_start()); - for (unsigned i = 0; i < length(); i++) { + // We use kMaxUInt32 as sentinel value, so check that we don't hit that. + DCHECK_NE(kMaxUInt32, pc_offset); + unsigned len = length(); + // If pc == kMaxUInt32, then this entry covers all call sites in the function. + if (len == 1 && GetPcOffset(0) == kMaxUInt32) return GetEntry(0); + for (unsigned i = 0; i < len; i++) { // TODO(kasperl): Replace the linear search with binary search. if (GetPcOffset(i) == pc_offset) return GetEntry(i); } @@ -137,6 +142,8 @@ unsigned SafepointTableBuilder::GetCodeOffset() const { void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { + RemoveDuplicates(); + // Make sure the safepoint table is properly aligned. Pad with nops. assembler->Align(kIntSize); assembler->RecordComment(";;; Safepoint table."); @@ -211,6 +218,63 @@ uint32_t SafepointTableBuilder::EncodeExceptPC(const DeoptimizationInfo& info, return encoding; } +void SafepointTableBuilder::RemoveDuplicates() { + // If the table contains more than one entry, and all entries are identical + // (except for the pc), replace the whole table by a single entry with pc = + // kMaxUInt32. This especially compacts the table for wasm code without tagged + // pointers and without deoptimization info. + + int length = deoptimization_info_.length(); + DCHECK_EQ(length, deopt_index_list_.length()); + DCHECK_EQ(length, indexes_.length()); + DCHECK_EQ(length, registers_.length()); + + if (length < 2) return; + + // Check that all entries (1, length] are identical to entry 0. + for (int i = 1; i < length; ++i) { + if (!IsIdenticalExceptForPc(0, i)) return; + } + + // If we get here, all entries were identical. Rewind all lists to just one + // entry, and set the pc to kMaxUInt32. + deoptimization_info_.Rewind(1); + deopt_index_list_.Rewind(1); + indexes_.Rewind(1); + registers_.Rewind(1); + deoptimization_info_[0].pc = kMaxUInt32; +} + +bool SafepointTableBuilder::IsIdenticalExceptForPc(int index1, + int index2) const { + DeoptimizationInfo& deopt_info_1 = deoptimization_info_[index1]; + DeoptimizationInfo& deopt_info_2 = deoptimization_info_[index2]; + if (deopt_info_1.arguments != deopt_info_2.arguments) return false; + if (deopt_info_1.has_doubles != deopt_info_2.has_doubles) return false; + + if (deopt_index_list_[index1] != deopt_index_list_[index2]) return false; + + ZoneList* indexes1 = indexes_[index1]; + ZoneList* indexes2 = indexes_[index2]; + if (indexes1->length() != indexes2->length()) return false; + for (int i = 0; i < indexes1->length(); ++i) { + if (indexes1->at(i) != indexes2->at(i)) return false; + } + + ZoneList* registers1 = registers_[index1]; + ZoneList* registers2 = registers_[index2]; + if (registers1) { + if (!registers2) return false; + if (registers1->length() != registers2->length()) return false; + for (int i = 0; i < registers1->length(); ++i) { + if (registers1->at(i) != registers2->at(i)) return false; + } + } else if (registers2) { + return false; + } + + return true; +} } // namespace internal } // namespace v8 diff --git a/deps/v8/src/safepoint-table.h b/deps/v8/src/safepoint-table.h index e0e9d95c488467..a368d0e77dd1a5 100644 --- a/deps/v8/src/safepoint-table.h +++ b/deps/v8/src/safepoint-table.h @@ -216,6 +216,10 @@ class SafepointTableBuilder BASE_EMBEDDED { uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index); + bool IsIdenticalExceptForPc(int index1, int index2) const; + // If all entries are identical, replace them by 1 entry with pc = kMaxUInt32. + void RemoveDuplicates(); + ZoneList deoptimization_info_; ZoneList deopt_index_list_; ZoneList*> indexes_; diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index 2b58065e77bd2b..b05840975b977e 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -214,7 +214,7 @@ class WasmSectionIterator { TRACE("Section: %s\n", SectionName(section_code_)); if (section_code_ == kUnknownSectionCode && - section_end_ > decoder_.pc()) { + section_end_ >= decoder_.pc()) { // skip to the end of the unknown section. uint32_t remaining = static_cast(section_end_ - decoder_.pc()); diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-17.js b/deps/v8/test/mjsunit/compiler/escape-analysis-17.js new file mode 100644 index 00000000000000..5709d47129ebd7 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/escape-analysis-17.js @@ -0,0 +1,27 @@ +// Copyright 2017 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 --turbo-escape + +function foo() { + var a = {x:1}; + var b = {x:1.5, y: 1}; + var x = 0; + for (var i = 0; i < 1; i = {}) { + // The second iteration of this loop is dead code, leading to a + // contradiction between dynamic and static information. + x += a.x + 0.5; + x += a.x % 0.5; + x += Math.abs(a.x); + x += a.x < 6; + x += a.x === 7; + x += a.x <= 8; + a = b; + } + return x; +} +foo(); +foo(); +%OptimizeFunctionOnNextCall(foo); +foo(); diff --git a/deps/v8/test/mjsunit/regress/regress-726636.js b/deps/v8/test/mjsunit/regress/regress-726636.js new file mode 100644 index 00000000000000..843cfdf883465b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-726636.js @@ -0,0 +1,14 @@ +// Copyright 2017 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 + +Object.defineProperty(Promise, Symbol.species, { value: 0 }); +var p = new Promise(function() {}); +try { + p.then(); + assertUnreachable(); +} catch(e) { + assertTrue(e instanceof TypeError); +}