diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index f43a776eac99d3..63dc5e7a7bab0f 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 7 #define V8_MINOR_VERSION 0 #define V8_BUILD_NUMBER 276 -#define V8_PATCH_LEVEL 36 +#define V8_PATCH_LEVEL 38 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc index b950c590b5c6b2..892a4e980e8b55 100644 --- a/deps/v8/src/wasm/module-compiler.cc +++ b/deps/v8/src/wasm/module-compiler.cc @@ -2329,12 +2329,6 @@ void AsyncCompileJob::CancelPendingForegroundTask() { pending_foreground_task_ = nullptr; } -template -void AsyncCompileJob::DoSync(Args&&... args) { - NextStep(std::forward(args)...); - StartForegroundTask(); -} - void AsyncCompileJob::StartBackgroundTask() { auto task = base::make_unique(this, false); @@ -2347,6 +2341,18 @@ void AsyncCompileJob::StartBackgroundTask() { } } +template +void AsyncCompileJob::DoSync(Args&&... args) { + NextStep(std::forward(args)...); + StartForegroundTask(); +} + +template +void AsyncCompileJob::DoImmediately(Args&&... args) { + NextStep(std::forward(args)...); + ExecuteForegroundTaskImmediately(); +} + template void AsyncCompileJob::DoAsync(Args&&... args) { NextStep(std::forward(args)...); @@ -2686,11 +2692,10 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader(size_t functions_count, FinishAsyncCompileJobWithError(decoder_.FinishDecoding(false)); return false; } - job_->NextStep( - decoder_.shared_module(), false); // Execute the PrepareAndStartCompile step immediately and not in a separate // task. - job_->ExecuteForegroundTaskImmediately(); + job_->DoImmediately( + decoder_.shared_module(), false); job_->native_module_->compilation_state()->SetNumberOfFunctionsToCompile( functions_count); @@ -2734,25 +2739,26 @@ void AsyncStreamingProcessor::OnFinishedChunk() { // Finish the processing of the stream. void AsyncStreamingProcessor::OnFinishedStream(OwnedVector bytes) { TRACE_STREAMING("Finish stream...\n"); - if (job_->native_module_) { - job_->wire_bytes_ = ModuleWireBytes(bytes.as_vector()); - job_->native_module_->set_wire_bytes(std::move(bytes)); - } ModuleResult result = decoder_.FinishDecoding(false); DCHECK(result.ok()); - if (job_->DecrementAndCheckFinisherCount()) { - if (job_->native_module_ == nullptr) { - // We are processing a WebAssembly module without code section. We need to - // prepare compilation first before we can finish it. - // {PrepareAndStartCompile} will call {FinishCompile} by itself if there - // is no code section. - job_->DoSync(result.val, true); - } else { - HandleScope scope(job_->isolate_); - SaveContext saved_context(job_->isolate_); - job_->isolate_->set_context(*job_->native_context_); - job_->FinishCompile(); - } + bool needs_finish = job_->DecrementAndCheckFinisherCount(); + if (job_->native_module_ == nullptr) { + // We are processing a WebAssembly module without code section. We need to + // prepare compilation first before we can finish it. + // {PrepareAndStartCompile} will call {FinishCompile} by itself if there + // is no code section. + DCHECK(needs_finish); + needs_finish = false; + job_->DoImmediately(result.val, + true); + } + job_->wire_bytes_ = ModuleWireBytes(bytes.as_vector()); + job_->native_module_->set_wire_bytes(std::move(bytes)); + if (needs_finish) { + HandleScope scope(job_->isolate_); + SaveContext saved_context(job_->isolate_); + job_->isolate_->set_context(*job_->native_context_); + job_->FinishCompile(); } } diff --git a/deps/v8/src/wasm/module-compiler.h b/deps/v8/src/wasm/module-compiler.h index 57bbd883e21f30..934c978d491109 100644 --- a/deps/v8/src/wasm/module-compiler.h +++ b/deps/v8/src/wasm/module-compiler.h @@ -126,6 +126,10 @@ class AsyncCompileJob { template void DoSync(Args&&... args); + // Switches to the compilation step {Step} and immediately executes that step. + template + void DoImmediately(Args&&... args); + // Switches to the compilation step {Step} and starts a background task to // execute it. template diff --git a/deps/v8/test/mjsunit/regress/regress-897366.js b/deps/v8/test/mjsunit/regress/regress-897366.js new file mode 100644 index 00000000000000..990e21590e5a7f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-897366.js @@ -0,0 +1,15 @@ +// Copyright 2018 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: --gc-interval=100 + +let xs = []; +for (let i = 0; i < 205; ++i) { + xs.push(i); +} +xs.sort((a, b) => { + xs.shift(); + xs[xs.length] = -246; + return a - b; +}); diff --git a/deps/v8/test/mjsunit/wasm/async-compile.js b/deps/v8/test/mjsunit/wasm/async-compile.js index e7f87c30e9e418..39a339aae63209 100644 --- a/deps/v8/test/mjsunit/wasm/async-compile.js +++ b/deps/v8/test/mjsunit/wasm/async-compile.js @@ -70,3 +70,10 @@ assertPromiseResult(async function badFunctionInTheMiddle() { let buffer = builder.toBuffer(); await assertCompileError(buffer); }()); + +assertPromiseResult(async function importWithoutCode() { + // Regression test for https://crbug.com/898310. + let builder = new WasmModuleBuilder(); + builder.addImport('m', 'q', kSig_i_i); + await builder.asyncInstantiate({'m': {'q': i => i}}); +}()); diff --git a/deps/v8/third_party/v8/builtins/array-sort.tq b/deps/v8/third_party/v8/builtins/array-sort.tq index 3f5a3b19b7af8c..65d0b8348bd210 100644 --- a/deps/v8/third_party/v8/builtins/array-sort.tq +++ b/deps/v8/third_party/v8/builtins/array-sort.tq @@ -826,7 +826,7 @@ module array { assert(i >= 0); assert(i == stack_size - 2 || i == stack_size - 3); - const elements: HeapObject = ReloadElements(sortState); + let elements: HeapObject = ReloadElements(sortState); const Load: LoadFn = GetLoadFn(sortState); const pending_runs: FixedArray = @@ -859,6 +859,7 @@ module array { const k: Smi = CallGallopRight( context, sortState, Load, key_right, base_a, length_a, 0, False) otherwise Bailout; + elements = ReloadElements(sortState); assert(k >= 0); base_a = base_a + k; @@ -874,6 +875,7 @@ module array { length_b = CallGallopLeft( context, sortState, Load, key_left, base_b, length_b, length_b - 1, False) otherwise Bailout; + elements = ReloadElements(sortState); assert(length_b >= 0); if (length_b == 0) return kSuccess; @@ -893,6 +895,12 @@ module array { } } + macro LoadElementsOrTempArray( + useTempArray: Boolean, sortState: FixedArray): HeapObject { + return useTempArray == True ? GetTempArray(sortState) : + ReloadElements(sortState); + } + // Locates the proper position of key in a sorted array; if the array contains // an element equal to key, return the position immediately to the left of // the leftmost equal element. (GallopRight does the same except returns the @@ -916,25 +924,17 @@ module array { assert(length > 0 && base >= 0); assert(0 <= hint && hint < length); - // We cannot leave a pointer to elements on the stack (see comment at - // ReloadElements). For this reason we pass a flag whether to reload - // and which array to use. - let elements: HeapObject = useTempArray == True ? GetTempArray(sortState) : - ReloadElements(sortState); - let last_ofs: Smi = 0; let offset: Smi = 1; try { - const base_hint_element: Object = - CallLoad(context, sortState, Load, elements, base + hint) + const base_hint_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), base + hint) otherwise Bailout; let order: Number = CallCompareFn(context, sortState, base_hint_element, key) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order < 0) { // a[base + hint] < key: gallop right, until @@ -943,14 +943,13 @@ module array { // a[base + length - 1] is highest. let max_ofs: Smi = length - hint; while (offset < max_ofs) { - const offset_element: Object = - CallLoad(context, sortState, Load, elements, base + hint + offset) + const offset_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), + base + hint + offset) otherwise Bailout; order = CallCompareFn(context, sortState, offset_element, key) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } // a[base + hint + offset] >= key? Break. if (order >= 0) break; @@ -975,14 +974,13 @@ module array { // a[base + hint] is lowest. let max_ofs: Smi = hint + 1; while (offset < max_ofs) { - const offset_element: Object = - CallLoad(context, sortState, Load, elements, base + hint - offset) + const offset_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), + base + hint - offset) otherwise Bailout; order = CallCompareFn(context, sortState, offset_element, key) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order < 0) break; @@ -1011,14 +1009,12 @@ module array { while (last_ofs < offset) { const m: Smi = last_ofs + ((offset - last_ofs) >>> 1); - const base_m_element: Object = - CallLoad(context, sortState, Load, elements, base + m) + const base_m_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), base + m) otherwise Bailout; order = CallCompareFn(context, sortState, base_m_element, key) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order < 0) { last_ofs = m + 1; // a[base + m] < key. @@ -1051,25 +1047,17 @@ module array { assert(length > 0 && base >= 0); assert(0 <= hint && hint < length); - // We cannot leave a pointer to elements on the stack (see comment at - // ReloadElements). For this reason we pass a flag whether to reload - // and which array to use. - let elements: HeapObject = useTempArray == True ? GetTempArray(sortState) : - ReloadElements(sortState); - let last_ofs: Smi = 0; let offset: Smi = 1; try { - const base_hint_element: Object = - CallLoad(context, sortState, Load, elements, base + hint) + const base_hint_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), base + hint) otherwise Bailout; let order: Number = CallCompareFn(context, sortState, key, base_hint_element) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order < 0) { // key < a[base + hint]: gallop left, until @@ -1078,14 +1066,13 @@ module array { // a[base + hint] is lowest. let max_ofs: Smi = hint + 1; while (offset < max_ofs) { - const offset_element: Object = - CallLoad(context, sortState, Load, elements, base + hint - offset) + const offset_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), + base + hint - offset) otherwise Bailout; order = CallCompareFn(context, sortState, key, offset_element) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order >= 0) break; @@ -1109,14 +1096,13 @@ module array { // a[base + length - 1] is highest. let max_ofs: Smi = length - hint; while (offset < max_ofs) { - const offset_element: Object = - CallLoad(context, sortState, Load, elements, base + hint + offset) + const offset_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), + base + hint + offset) otherwise Bailout; order = CallCompareFn(context, sortState, key, offset_element) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } // a[base + hint + ofs] <= key. if (order < 0) break; @@ -1144,14 +1130,12 @@ module array { while (last_ofs < offset) { const m: Smi = last_ofs + ((offset - last_ofs) >>> 1); - const base_m_element: Object = - CallLoad(context, sortState, Load, elements, base + m) + const base_m_element: Object = CallLoad( + context, sortState, Load, + LoadElementsOrTempArray(useTempArray, sortState), base + m) otherwise Bailout; order = CallCompareFn(context, sortState, key, base_m_element) otherwise Bailout; - if (useTempArray == False) { - elements = ReloadElements(sortState); - } if (order < 0) { offset = m; // key < a[base + m]. @@ -1288,6 +1272,7 @@ module array { nof_wins_a = CallGallopRight( context, sortState, Load, key_right, cursor_temp, length_a, 0, True) otherwise Bailout; + elements = ReloadElements(sortState); assert(nof_wins_a >= 0); if (nof_wins_a > 0) { @@ -1313,6 +1298,7 @@ module array { context, sortState, LoadF, temp_array[cursor_temp], cursor_b, length_b, 0, False) otherwise Bailout; + elements = ReloadElements(sortState); assert(nof_wins_b >= 0); if (nof_wins_b > 0) { CallCopyWithinSortArray( @@ -1461,6 +1447,7 @@ module array { context, sortState, LoadF, temp_array[cursor_temp], baseA, length_a, length_a - 1, False) otherwise Bailout; + elements = ReloadElements(sortState); assert(k >= 0); nof_wins_a = length_a - k; @@ -1487,6 +1474,7 @@ module array { k = CallGallopLeft( context, sortState, Load, key, 0, length_b, length_b - 1, True) otherwise Bailout; + elements = ReloadElements(sortState); assert(k >= 0); nof_wins_b = length_b - k; @@ -1743,8 +1731,7 @@ module array { // 2. Let obj be ? ToObject(this value). const obj: JSReceiver = ToObject(context, receiver); - const sort_state: FixedArray = - AllocateZeroedFixedArray(kSortStateSize); + const sort_state: FixedArray = AllocateZeroedFixedArray(kSortStateSize); FillFixedArrayWithSmiZero(sort_state, SmiTag(kSortStateSize)); sort_state[kReceiverIdx] = obj;