diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-11-08 15:39:11 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-11-08 15:46:25 +0100 |
commit | 6ca81ad72a3c6fdf16c683335be748f22aaa9a0d (patch) | |
tree | 33c8ee75f729aed76c2c0b89c63f9bf1b4dd66aa /deps/v8/test/cctest | |
parent | 1eee0b8bf8bba39b600fb16a9223e545e3bac2bc (diff) | |
download | node-new-6ca81ad72a3c6fdf16c683335be748f22aaa9a0d.tar.gz |
deps: update V8 to 7.9.317.20
PR-URL: https://github.com/nodejs/node/pull/30020
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/test/cctest')
107 files changed, 6362 insertions, 3365 deletions
diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn index d0934c9977..6d6bcdcd67 100644 --- a/deps/v8/test/cctest/BUILD.gn +++ b/deps/v8/test/cctest/BUILD.gn @@ -161,6 +161,7 @@ v8_source_set("cctest_sources") { "interpreter/test-source-positions.cc", "libplatform/test-tracing.cc", "libsampler/test-sampler.cc", + "manually-externalized-buffer.h", "parsing/test-parse-decision.cc", "parsing/test-preparser.cc", "parsing/test-scanner-streams.cc", @@ -185,6 +186,7 @@ v8_source_set("cctest_sources") { "test-api.h", "test-array-list.cc", "test-atomicops.cc", + "test-backing-store.cc", "test-bignum-dtoa.cc", "test-bignum.cc", "test-bit-vector.cc", @@ -267,6 +269,7 @@ v8_source_set("cctest_sources") { "unicode-helpers.cc", "unicode-helpers.h", "wasm/test-c-wasm-entry.cc", + "wasm/test-grow-memory.cc", "wasm/test-jump-table-assembler.cc", "wasm/test-run-wasm-64.cc", "wasm/test-run-wasm-asmjs.cc", diff --git a/deps/v8/test/cctest/DEPS b/deps/v8/test/cctest/DEPS index 7373012870..06ae6f87f6 100644 --- a/deps/v8/test/cctest/DEPS +++ b/deps/v8/test/cctest/DEPS @@ -1,6 +1,7 @@ include_rules = [ + "+perfetto", + "+protos/perfetto", "+src", "+tools", "+torque-generated", - "+perfetto", -]
\ No newline at end of file +] diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index dcfca2b2df..6adf2041cf 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -327,9 +327,9 @@ int main(int argc, char* argv[]) { CcTest::set_array_buffer_allocator( v8::ArrayBuffer::Allocator::NewDefaultAllocator()); - v8::RegisterExtension(v8::base::make_unique<i::PrintExtension>()); - v8::RegisterExtension(v8::base::make_unique<i::ProfilerExtension>()); - v8::RegisterExtension(v8::base::make_unique<i::TraceExtension>()); + v8::RegisterExtension(std::make_unique<i::PrintExtension>()); + v8::RegisterExtension(std::make_unique<i::ProfilerExtension>()); + v8::RegisterExtension(std::make_unique<i::TraceExtension>()); int tests_run = 0; bool print_run_count = true; diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index b1a7b5c101..430ca647b7 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -151,6 +151,8 @@ # Pass but take too long with the simulator. 'test-api/ExternalArrays': [PASS, SLOW], 'test-api/Threading*': [SKIP], + 'test-cpu-profiler/MultipleIsolates': [PASS, SLOW], + 'test-debug/DebugBreakStackTrace': [PASS, SLOW], }], # 'arch == arm64 and simulator_run' ############################################################################## @@ -227,6 +229,7 @@ # operations. 'test-run-wasm-atomics/*': [SKIP], 'test-run-wasm-atomics64/*': [SKIP], + 'test-regexp/Peephole*': [SKIP], }], # 'byteorder == big' ############################################################################## @@ -259,6 +262,7 @@ ['arch == arm and simulator_run', { # Pass but take too long with the simulator. 'test-api/Threading*': [SKIP], + 'test-cpu-profiler/MultipleIsolates': [PASS, SLOW], }], # 'arch == arm and simulator_run' ############################################################################## @@ -471,8 +475,10 @@ 'test-api/WasmI32AtomicWaitCallback': [SKIP], 'test-api/WasmI64AtomicWaitCallback': [SKIP], 'test-api/WasmStreaming*': [SKIP], + 'test-backing-store/Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree': [SKIP], 'test-c-wasm-entry/*': [SKIP], 'test-jump-table-assembler/*': [SKIP], + 'test-grow-memory/*': [SKIP], 'test-run-wasm-64/*': [SKIP], 'test-run-wasm-asmjs/*': [SKIP], 'test-run-wasm-atomics64/*': [SKIP], @@ -610,4 +616,12 @@ '*': [SKIP], }], # variant == jitless and not embedded_builtins +############################################################################## +['variant == turboprop', { + # Require inlining. + 'test-cpu-profiler/DeoptAtFirstLevelInlinedSource': [SKIP], + 'test-cpu-profiler/DeoptAtSecondLevelInlinedSource': [SKIP], + 'test-cpu-profiler/DeoptUntrackedFunction': [SKIP], +}], # variant == turboprop + ] diff --git a/deps/v8/test/cctest/compiler/serializer-tester.cc b/deps/v8/test/cctest/compiler/serializer-tester.cc index 338d1bcbfb..01979a2201 100644 --- a/deps/v8/test/cctest/compiler/serializer-tester.cc +++ b/deps/v8/test/cctest/compiler/serializer-tester.cc @@ -52,17 +52,19 @@ SerializerTester::SerializerTester(const char* source) TEST(SerializeEmptyFunction) { SerializerTester tester( "function f() {}; %EnsureFeedbackVectorForFunction(f); return f;"); - CHECK(tester.function().IsSerializedForCompilation()); + JSFunctionRef function = tester.function(); + CHECK( + function.shared().IsSerializedForCompilation(function.feedback_vector())); } -// This helper function allows for testing weather an inlinee candidate +// This helper function allows for testing whether an inlinee candidate // was properly serialized. It expects that the top-level function (that is // run through the SerializerTester) will return its inlinee candidate. void CheckForSerializedInlinee(const char* source, int argc = 0, Handle<Object> argv[] = {}) { SerializerTester tester(source); JSFunctionRef f = tester.function(); - CHECK(f.IsSerializedForCompilation()); + CHECK(f.shared().IsSerializedForCompilation(f.feedback_vector())); MaybeHandle<Object> g_obj = Execution::Call( tester.isolate(), tester.function().object(), diff --git a/deps/v8/test/cctest/compiler/serializer-tester.h b/deps/v8/test/cctest/compiler/serializer-tester.h index 7c8016ef81..fe5f93895f 100644 --- a/deps/v8/test/cctest/compiler/serializer-tester.h +++ b/deps/v8/test/cctest/compiler/serializer-tester.h @@ -5,6 +5,8 @@ #ifndef V8_CCTEST_COMPILER_SERIALIZER_TESTER_H_ #define V8_CCTEST_COMPILER_SERIALIZER_TESTER_H_ +#include <memory> + #include "src/compiler/js-heap-broker.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/compiler/test-code-assembler.cc b/deps/v8/test/cctest/compiler/test-code-assembler.cc index 9e6318ee88..56628ffde4 100644 --- a/deps/v8/test/cctest/compiler/test-code-assembler.cc +++ b/deps/v8/test/cctest/compiler/test-code-assembler.cc @@ -18,38 +18,33 @@ namespace compiler { namespace { -using Label = CodeAssemblerLabel; using Variable = CodeAssemblerVariable; -Node* SmiTag(CodeAssembler& m, // NOLINT(runtime/references) - Node* value) { +Node* SmiTag(CodeAssembler* m, Node* value) { int32_t constant_value; - if (m.ToInt32Constant(value, &constant_value) && + if (m->ToInt32Constant(value, &constant_value) && Smi::IsValid(constant_value)) { - return m.SmiConstant(Smi::FromInt(constant_value)); + return m->SmiConstant(Smi::FromInt(constant_value)); } - return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize)); + return m->WordShl(value, m->IntPtrConstant(kSmiShiftSize + kSmiTagSize)); } -Node* UndefinedConstant(CodeAssembler& m) { // NOLINT(runtime/references) - return m.LoadRoot(RootIndex::kUndefinedValue); +Node* UndefinedConstant(CodeAssembler* m) { + return m->LoadRoot(RootIndex::kUndefinedValue); } -Node* SmiFromInt32(CodeAssembler& m, // NOLINT(runtime/references) - Node* value) { - value = m.ChangeInt32ToIntPtr(value); - return m.BitcastWordToTaggedSigned( - m.WordShl(value, kSmiShiftSize + kSmiTagSize)); +Node* SmiFromInt32(CodeAssembler* m, Node* value) { + value = m->ChangeInt32ToIntPtr(value); + return m->BitcastWordToTaggedSigned( + m->WordShl(value, kSmiShiftSize + kSmiTagSize)); } -Node* LoadObjectField(CodeAssembler& m, // NOLINT(runtime/references) - Node* object, int offset, +Node* LoadObjectField(CodeAssembler* m, Node* object, int offset, MachineType type = MachineType::AnyTagged()) { - return m.Load(type, object, m.IntPtrConstant(offset - kHeapObjectTag)); + return m->Load(type, object, m->IntPtrConstant(offset - kHeapObjectTag)); } -Node* LoadMap(CodeAssembler& m, // NOLINT(runtime/references) - Node* object) { +Node* LoadMap(CodeAssembler* m, Node* object) { return LoadObjectField(m, object, JSObject::kMapOffset); } @@ -59,7 +54,7 @@ TEST(SimpleSmiReturn) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - m.Return(SmiTag(m, m.Int32Constant(37))); + m.Return(SmiTag(&m, m.Int32Constant(37))); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(37, ft.CallChecked<Smi>()->value()); } @@ -91,7 +86,7 @@ TEST(SimpleCallRuntime1Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* b = SmiTag(m, m.Int32Constant(0)); + Node* b = SmiTag(&m, m.Int32Constant(0)); m.Return(m.CallRuntime(Runtime::kIsSmi, context, b)); FunctionTester ft(asm_tester.GenerateCode()); CHECK(ft.CallChecked<Oddball>().is_identical_to( @@ -104,7 +99,7 @@ TEST(SimpleTailCallRuntime1Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* b = SmiTag(m, m.Int32Constant(0)); + Node* b = SmiTag(&m, m.Int32Constant(0)); m.TailCallRuntime(Runtime::kIsSmi, context, b); FunctionTester ft(asm_tester.GenerateCode()); CHECK(ft.CallChecked<Oddball>().is_identical_to( @@ -117,8 +112,8 @@ TEST(SimpleCallRuntime2Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* a = SmiTag(m, m.Int32Constant(2)); - Node* b = SmiTag(m, m.Int32Constant(4)); + Node* a = SmiTag(&m, m.Int32Constant(2)); + Node* b = SmiTag(&m, m.Int32Constant(4)); m.Return(m.CallRuntime(Runtime::kAdd, context, a, b)); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(6, ft.CallChecked<Smi>()->value()); @@ -130,8 +125,8 @@ TEST(SimpleTailCallRuntime2Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* a = SmiTag(m, m.Int32Constant(2)); - Node* b = SmiTag(m, m.Int32Constant(4)); + Node* a = SmiTag(&m, m.Int32Constant(2)); + Node* b = SmiTag(&m, m.Int32Constant(4)); m.TailCallRuntime(Runtime::kAdd, context, a, b); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(6, ft.CallChecked<Smi>()->value()); @@ -139,8 +134,7 @@ TEST(SimpleTailCallRuntime2Arg) { namespace { -Handle<JSFunction> CreateSumAllArgumentsFunction( - FunctionTester& ft) { // NOLINT(runtime/references) +Handle<JSFunction> CreateSumAllArgumentsFunction(FunctionTester* ft) { const char* source = "(function() {\n" " var sum = 0 + this;\n" @@ -149,7 +143,7 @@ Handle<JSFunction> CreateSumAllArgumentsFunction( " }\n" " return sum;\n" "})"; - return ft.NewFunction(source); + return ft->NewFunction(source); } } // namespace @@ -163,7 +157,7 @@ TEST(SimpleCallJSFunction0Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(kNumParams + 2); - Node* receiver = SmiTag(m, m.Int32Constant(42)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver); @@ -171,7 +165,7 @@ TEST(SimpleCallJSFunction0Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(42), *result.ToHandleChecked()); } @@ -185,8 +179,8 @@ TEST(SimpleCallJSFunction1Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(1); - Node* receiver = SmiTag(m, m.Int32Constant(42)); - Node* a = SmiTag(m, m.Int32Constant(13)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); + Node* a = SmiTag(&m, m.Int32Constant(13)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver, a); @@ -194,7 +188,7 @@ TEST(SimpleCallJSFunction1Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(55), *result.ToHandleChecked()); } @@ -208,9 +202,9 @@ TEST(SimpleCallJSFunction2Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(1); - Node* receiver = SmiTag(m, m.Int32Constant(42)); - Node* a = SmiTag(m, m.Int32Constant(13)); - Node* b = SmiTag(m, m.Int32Constant(153)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); + Node* a = SmiTag(&m, m.Int32Constant(13)); + Node* b = SmiTag(&m, m.Int32Constant(153)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver, a, b); @@ -218,7 +212,7 @@ TEST(SimpleCallJSFunction2Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(208), *result.ToHandleChecked()); } @@ -228,7 +222,7 @@ TEST(VariableMerge1) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -247,7 +241,7 @@ TEST(VariableMerge2) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -269,7 +263,7 @@ TEST(VariableMerge3) { CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); Variable var2(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); var2.Bind(temp); @@ -293,7 +287,7 @@ TEST(VariableMergeBindFirst) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m, &var1), end(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m, &var1), end(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -319,8 +313,8 @@ TEST(VariableMergeSwitch) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), default_label(&m); - Label* labels[] = {&l1, &l2}; + CodeAssemblerLabel l1(&m), l2(&m), default_label(&m); + CodeAssemblerLabel* labels[] = {&l1, &l2}; int32_t values[] = {1, 2}; TNode<Smi> temp1 = m.SmiConstant(0); var1.Bind(temp1); @@ -345,7 +339,7 @@ TEST(SplitEdgeBranchMerge) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label l1(&m), merge(&m); + CodeAssemblerLabel l1(&m), merge(&m); m.Branch(m.Int32Constant(1), &l1, &merge); m.Bind(&l1); m.Goto(&merge); @@ -357,8 +351,8 @@ TEST(SplitEdgeSwitchMerge) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label l1(&m), l2(&m), l3(&m), default_label(&m); - Label* labels[] = {&l1, &l2}; + CodeAssemblerLabel l1(&m), l2(&m), l3(&m), default_label(&m); + CodeAssemblerLabel* labels[] = {&l1, &l2}; int32_t values[] = {1, 2}; m.Branch(m.Int32Constant(1), &l3, &l1); m.Bind(&l3); @@ -389,11 +383,11 @@ TEST(TestToConstant) { CHECK(m.ToInt32Constant(a, &value32)); CHECK(m.ToInt64Constant(a, &value64)); - a = UndefinedConstant(m); + a = UndefinedConstant(&m); CHECK(!m.ToInt32Constant(a, &value32)); CHECK(!m.ToInt64Constant(a, &value64)); - a = UndefinedConstant(m); + a = UndefinedConstant(&m); CHECK(!m.ToInt32Constant(a, &value32)); CHECK(!m.ToInt64Constant(a, &value64)); } @@ -402,17 +396,17 @@ TEST(DeferredCodePhiHints) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label block1(&m, Label::kDeferred); + CodeAssemblerLabel block1(&m, CodeAssemblerLabel::kDeferred); m.Goto(&block1); m.Bind(&block1); { Variable var_object(&m, MachineRepresentation::kTagged); - Label loop(&m, &var_object); + CodeAssemblerLabel loop(&m, &var_object); var_object.Bind(m.SmiConstant(0)); m.Goto(&loop); m.Bind(&loop); { - Node* map = LoadMap(m, var_object.value()); + Node* map = LoadMap(&m, var_object.value()); var_object.Bind(map); m.Goto(&loop); } @@ -424,10 +418,10 @@ TEST(TestOutOfScopeVariable) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label block1(&m); - Label block2(&m); - Label block3(&m); - Label block4(&m); + CodeAssemblerLabel block1(&m); + CodeAssemblerLabel block2(&m); + CodeAssemblerLabel block3(&m); + CodeAssemblerLabel block4(&m); m.Branch(m.WordEqual(m.UncheckedCast<IntPtrT>(m.Parameter(0)), m.IntPtrConstant(0)), &block1, &block4); @@ -463,7 +457,7 @@ TEST(GotoIfException) { m.HeapConstant(isolate->factory()->to_string_tag_symbol()); Variable exception(&m, MachineRepresentation::kTagged); - Label exception_handler(&m); + CodeAssemblerLabel exception_handler(&m); Callable to_string = Builtins::CallableFor(isolate, Builtins::kToString); TNode<Object> string = m.CallStub(to_string, context, to_string_tag); m.GotoIfException(string, &exception_handler, &exception); @@ -498,9 +492,9 @@ TEST(GotoIfExceptionMultiple) { Node* second_value = m.Parameter(1); Node* third_value = m.Parameter(2); - Label exception_handler1(&m); - Label exception_handler2(&m); - Label exception_handler3(&m); + CodeAssemblerLabel exception_handler1(&m); + CodeAssemblerLabel exception_handler2(&m); + CodeAssemblerLabel exception_handler3(&m); Variable return_value(&m, MachineRepresentation::kWord32); Variable error(&m, MachineRepresentation::kTagged); @@ -515,20 +509,20 @@ TEST(GotoIfExceptionMultiple) { // try { ToString(param2); return 7 } catch (e) { ... } m.Bind(&exception_handler1); return_value.Bind(m.Int32Constant(7)); - error.Bind(UndefinedConstant(m)); + error.Bind(UndefinedConstant(&m)); string = m.CallStub(to_string, context, second_value); m.GotoIfException(string, &exception_handler2, &error); - m.Return(SmiFromInt32(m, return_value.value())); + m.Return(SmiFromInt32(&m, return_value.value())); // try { ToString(param3); return 7 & ~2; } catch (e) { return e; } m.Bind(&exception_handler2); // Return returnValue & ~2 - error.Bind(UndefinedConstant(m)); + error.Bind(UndefinedConstant(&m)); string = m.CallStub(to_string, context, third_value); m.GotoIfException(string, &exception_handler3, &error); m.Return(SmiFromInt32( - m, m.Word32And(return_value.value(), - m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1))))); + &m, m.Word32And(return_value.value(), + m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1))))); m.Bind(&exception_handler3); m.Return(error.value()); @@ -578,7 +572,7 @@ TEST(ExceptionHandler) { CodeAssembler m(asm_tester.state()); CodeAssembler::TVariable<Object> var(m.SmiConstant(0), &m); - Label exception(&m, {&var}, Label::kDeferred); + CodeAssemblerLabel exception(&m, {&var}, CodeAssemblerLabel::kDeferred); { CodeAssemblerScopedExceptionHandler handler(&m, &exception, &var); TNode<Context> context = diff --git a/deps/v8/test/cctest/compiler/test-gap-resolver.cc b/deps/v8/test/cctest/compiler/test-gap-resolver.cc index ca26e0b49f..a7b6514c1f 100644 --- a/deps/v8/test/cctest/compiler/test-gap-resolver.cc +++ b/deps/v8/test/cctest/compiler/test-gap-resolver.cc @@ -353,7 +353,7 @@ class ParallelMoveCreator : public HandleAndZoneScope { }; int index = rng_->NextInt(kMaxIndex); // destination can't be Constant. - switch (rng_->NextInt(is_source ? 5 : 4)) { + switch (rng_->NextInt(is_source ? 3 : 2)) { case 0: return AllocatedOperand(LocationOperand::STACK_SLOT, rep, GetValidSlotIndex(rep, index)); @@ -361,12 +361,6 @@ class ParallelMoveCreator : public HandleAndZoneScope { return AllocatedOperand(LocationOperand::REGISTER, rep, GetValidRegisterCode(rep, index)); case 2: - return ExplicitOperand(LocationOperand::REGISTER, rep, - GetValidRegisterCode(rep, 1)); - case 3: - return ExplicitOperand(LocationOperand::STACK_SLOT, rep, - GetValidSlotIndex(rep, index)); - case 4: return ConstantOperand(index); } UNREACHABLE(); diff --git a/deps/v8/test/cctest/compiler/test-jump-threading.cc b/deps/v8/test/cctest/compiler/test-jump-threading.cc index 44bee022b3..7440da7fb0 100644 --- a/deps/v8/test/cctest/compiler/test-jump-threading.cc +++ b/deps/v8/test/cctest/compiler/test-jump-threading.cc @@ -109,16 +109,16 @@ class TestCode : public HandleAndZoneScope { } }; -void VerifyForwarding(TestCode& code, // NOLINT(runtime/references) - int count, int* expected) { +void VerifyForwarding(TestCode* code, int count, int* expected) { v8::internal::AccountingAllocator allocator; Zone local_zone(&allocator, ZONE_NAME); ZoneVector<RpoNumber> result(&local_zone); - JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_, true); + JumpThreading::ComputeForwarding(&local_zone, &result, &code->sequence_, + true); CHECK(count == static_cast<int>(result.size())); for (int i = 0; i < count; i++) { - CHECK(expected[i] == result[i].ToInt()); + CHECK_EQ(expected[i], result[i].ToInt()); } } @@ -133,7 +133,7 @@ TEST(FwEmpty1) { code.End(); static int expected[] = {2, 2, 2}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -150,7 +150,7 @@ TEST(FwEmptyN) { code.End(); static int expected[] = {2, 2, 2}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } } @@ -162,7 +162,7 @@ TEST(FwNone1) { code.End(); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -174,7 +174,7 @@ TEST(FwMoves1) { code.End(); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -188,7 +188,7 @@ TEST(FwMoves2) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -202,7 +202,7 @@ TEST(FwMoves2b) { code.End(); static int expected[] = {0, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -216,7 +216,7 @@ TEST(FwOther2) { code.End(); static int expected[] = {0, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -229,7 +229,7 @@ TEST(FwNone2a) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -242,7 +242,7 @@ TEST(FwNone2b) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -253,7 +253,7 @@ TEST(FwLoop1) { code.Jump(0); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -266,7 +266,7 @@ TEST(FwLoop2) { code.Jump(0); static int expected[] = {0, 0}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -281,7 +281,7 @@ TEST(FwLoop3) { code.Jump(0); static int expected[] = {0, 0, 0}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -294,7 +294,7 @@ TEST(FwLoop1b) { code.Jump(1); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -309,7 +309,7 @@ TEST(FwLoop2b) { code.Jump(1); static int expected[] = {1, 1, 1}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -326,7 +326,7 @@ TEST(FwLoop3b) { code.Jump(1); static int expected[] = {1, 1, 1, 1}; - VerifyForwarding(code, 4, expected); + VerifyForwarding(&code, 4, expected); } @@ -345,7 +345,7 @@ TEST(FwLoop2_1a) { code.Jump(2); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -364,7 +364,7 @@ TEST(FwLoop2_1b) { code.Jump(2); static int expected[] = {2, 2, 2, 2, 2}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -383,7 +383,7 @@ TEST(FwLoop2_1c) { code.Jump(1); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -402,7 +402,7 @@ TEST(FwLoop2_1d) { code.Jump(1); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -423,7 +423,7 @@ TEST(FwLoop3_1a) { code.Jump(0); static int expected[] = {2, 2, 2, 2, 2, 2}; - VerifyForwarding(code, 6, expected); + VerifyForwarding(&code, 6, expected); } @@ -443,7 +443,7 @@ TEST(FwDiamonds) { code.End(); int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3}; - VerifyForwarding(code, 4, expected); + VerifyForwarding(&code, 4, expected); } } } @@ -470,7 +470,7 @@ TEST(FwDiamonds2) { int merge = k ? 3 : 4; int expected[] = {0, i ? 1 : merge, j ? 2 : merge, merge, 4}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } } } @@ -504,7 +504,7 @@ TEST(FwDoubleDiamonds) { int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3, x ? 4 : 6, y ? 5 : 6, 6}; - VerifyForwarding(code, 7, expected); + VerifyForwarding(&code, 7, expected); } } } @@ -568,7 +568,7 @@ void RunPermutedChain(int* permutation, int size) { int expected[] = {size + 1, size + 1, size + 1, size + 1, size + 1, size + 1, size + 1}; - VerifyForwarding(code, size + 2, expected); + VerifyForwarding(&code, size + 2, expected); } @@ -604,55 +604,50 @@ void RunPermutedDiamond(int* permutation, int size) { int expected[] = {br, 5, 5, 5, 5, 5}; expected[br] = br; - VerifyForwarding(code, 6, expected); + VerifyForwarding(&code, 6, expected); } TEST(FwPermuted_diamond) { RunAllPermutations<4>(RunPermutedDiamond); } -void ApplyForwarding(TestCode& code, // NOLINT(runtime/references) - int size, int* forward) { - code.sequence_.RecomputeAssemblyOrderForTesting(); - ZoneVector<RpoNumber> vector(code.main_zone()); +void ApplyForwarding(TestCode* code, int size, int* forward) { + code->sequence_.RecomputeAssemblyOrderForTesting(); + ZoneVector<RpoNumber> vector(code->main_zone()); for (int i = 0; i < size; i++) { vector.push_back(RpoNumber::FromInt(forward[i])); } - JumpThreading::ApplyForwarding(code.main_zone(), vector, &code.sequence_); + JumpThreading::ApplyForwarding(code->main_zone(), vector, &code->sequence_); } -void CheckJump(TestCode& code, // NOLINT(runtime/references) - int pos, int target) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckJump(TestCode* code, int pos, int target) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(kArchJmp, instr->arch_opcode()); CHECK_EQ(1, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); - CHECK_EQ(target, code.sequence_.InputRpo(instr, 0).ToInt()); + CHECK_EQ(target, code->sequence_.InputRpo(instr, 0).ToInt()); } -void CheckNop(TestCode& code, // NOLINT(runtime/references) - int pos) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckNop(TestCode* code, int pos) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(kArchNop, instr->arch_opcode()); CHECK_EQ(0, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); } -void CheckBranch(TestCode& code, // NOLINT(runtime/references) - int pos, int t1, int t2) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckBranch(TestCode* code, int pos, int t1, int t2) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(2, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); - CHECK_EQ(t1, code.sequence_.InputRpo(instr, 0).ToInt()); - CHECK_EQ(t2, code.sequence_.InputRpo(instr, 1).ToInt()); + CHECK_EQ(t1, code->sequence_.InputRpo(instr, 0).ToInt()); + CHECK_EQ(t2, code->sequence_.InputRpo(instr, 1).ToInt()); } -void CheckAssemblyOrder(TestCode& code, // NOLINT(runtime/references) - int size, int* expected) { +void CheckAssemblyOrder(TestCode* code, int size, int* expected) { int i = 0; - for (auto const block : code.sequence_.instruction_blocks()) { + for (auto const block : code->sequence_.instruction_blocks()) { CHECK_EQ(expected[i++], block->ao_number().ToInt()); } } @@ -668,12 +663,12 @@ TEST(Rewire1) { code.End(); static int forward[] = {2, 2, 2}; - ApplyForwarding(code, 3, forward); - CheckJump(code, j1, 2); - CheckNop(code, j2); + ApplyForwarding(&code, 3, forward); + CheckJump(&code, j1, 2); + CheckNop(&code, j2); static int assembly[] = {0, 1, 1}; - CheckAssemblyOrder(code, 3, assembly); + CheckAssemblyOrder(&code, 3, assembly); } @@ -691,13 +686,13 @@ TEST(Rewire1_deferred) { code.End(); static int forward[] = {3, 3, 3, 3}; - ApplyForwarding(code, 4, forward); - CheckJump(code, j1, 3); - CheckNop(code, j2); - CheckNop(code, j3); + ApplyForwarding(&code, 4, forward); + CheckJump(&code, j1, 3); + CheckNop(&code, j2); + CheckNop(&code, j3); static int assembly[] = {0, 1, 2, 1}; - CheckAssemblyOrder(code, 4, assembly); + CheckAssemblyOrder(&code, 4, assembly); } @@ -717,12 +712,12 @@ TEST(Rewire2_deferred) { code.End(); static int forward[] = {0, 1, 2, 3}; - ApplyForwarding(code, 4, forward); - CheckJump(code, j1, 1); - CheckJump(code, j2, 3); + ApplyForwarding(&code, 4, forward); + CheckJump(&code, j1, 1); + CheckJump(&code, j2, 3); static int assembly[] = {0, 2, 3, 1}; - CheckAssemblyOrder(code, 4, assembly); + CheckAssemblyOrder(&code, 4, assembly); } @@ -742,18 +737,18 @@ TEST(Rewire_diamond) { code.End(); int forward[] = {0, 1, i ? 4 : 2, j ? 4 : 3, 4}; - ApplyForwarding(code, 5, forward); - CheckJump(code, j1, 1); - CheckBranch(code, b1, i ? 4 : 2, j ? 4 : 3); + ApplyForwarding(&code, 5, forward); + CheckJump(&code, j1, 1); + CheckBranch(&code, b1, i ? 4 : 2, j ? 4 : 3); if (i) { - CheckNop(code, j2); + CheckNop(&code, j2); } else { - CheckJump(code, j2, 4); + CheckJump(&code, j2, 4); } if (j) { - CheckNop(code, j3); + CheckNop(&code, j3); } else { - CheckJump(code, j3, 4); + CheckJump(&code, j3, 4); } int assembly[] = {0, 1, 2, 3, 4}; @@ -763,7 +758,7 @@ TEST(Rewire_diamond) { if (j) { for (int k = 4; k < 5; k++) assembly[k]--; } - CheckAssemblyOrder(code, 5, assembly); + CheckAssemblyOrder(&code, 5, assembly); } } } diff --git a/deps/v8/test/cctest/compiler/test-loop-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-analysis.cc index 231a3ada5a..38ce2f3463 100644 --- a/deps/v8/test/cctest/compiler/test-loop-analysis.cc +++ b/deps/v8/test/cctest/compiler/test-loop-analysis.cc @@ -201,9 +201,9 @@ struct While { } void chain(Node* control) { loop->ReplaceInput(0, control); } - void nest(While& that) { // NOLINT(runtime/references) - that.loop->ReplaceInput(1, exit); - this->loop->ReplaceInput(0, that.if_true); + void nest(While* that) { + that->loop->ReplaceInput(1, exit); + this->loop->ReplaceInput(0, that->if_true); } }; @@ -214,17 +214,17 @@ struct Counter { Node* phi; Node* add; - Counter(While& w, // NOLINT(runtime/references) - int32_t b, int32_t k) - : base(w.t.jsgraph.Int32Constant(b)), inc(w.t.jsgraph.Int32Constant(k)) { + Counter(While* w, int32_t b, int32_t k) + : base(w->t.jsgraph.Int32Constant(b)), + inc(w->t.jsgraph.Int32Constant(k)) { Build(w); } - Counter(While& w, Node* b, Node* k) : base(b), inc(k) { Build(w); } + Counter(While* w, Node* b, Node* k) : base(b), inc(k) { Build(w); } - void Build(While& w) { - phi = w.t.graph.NewNode(w.t.op(2, false), base, base, w.loop); - add = w.t.graph.NewNode(&kIntAdd, phi, inc); + void Build(While* w) { + phi = w->t.graph.NewNode(w->t.op(2, false), base, base, w->loop); + add = w->t.graph.NewNode(&kIntAdd, phi, inc); phi->ReplaceInput(1, add); } }; @@ -236,16 +236,16 @@ struct StoreLoop { Node* phi; Node* store; - explicit StoreLoop(While& w) // NOLINT(runtime/references) - : base(w.t.graph.start()), val(w.t.jsgraph.Int32Constant(13)) { + explicit StoreLoop(While* w) + : base(w->t.graph.start()), val(w->t.jsgraph.Int32Constant(13)) { Build(w); } - StoreLoop(While& w, Node* b, Node* v) : base(b), val(v) { Build(w); } + StoreLoop(While* w, Node* b, Node* v) : base(b), val(v) { Build(w); } - void Build(While& w) { - phi = w.t.graph.NewNode(w.t.op(2, true), base, base, w.loop); - store = w.t.graph.NewNode(&kStore, val, phi, w.loop); + void Build(While* w) { + phi = w->t.graph.NewNode(w->t.op(2, true), base, base, w->loop); + store = w->t.graph.NewNode(&kStore, val, phi, w->loop); phi->ReplaceInput(1, store); } }; @@ -287,7 +287,7 @@ TEST(LaLoop1c) { // One loop with a counter. LoopFinderTester t; While w(t, t.p0); - Counter c(w, 0, 1); + Counter c(&w, 0, 1); t.Return(c.phi, t.start, w.exit); Node* chain[] = {w.loop}; @@ -303,7 +303,7 @@ TEST(LaLoop1e) { // One loop with an effect phi. LoopFinderTester t; While w(t, t.p0); - StoreLoop c(w); + StoreLoop c(&w); t.Return(t.p0, c.phi, w.exit); Node* chain[] = {w.loop}; @@ -319,8 +319,8 @@ TEST(LaLoop1d) { // One loop with two counters. LoopFinderTester t; While w(t, t.p0); - Counter c1(w, 0, 1); - Counter c2(w, 1, 1); + Counter c1(&w, 0, 1); + Counter c2(&w, 1, 1); t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w.exit); Node* chain[] = {w.loop}; @@ -365,8 +365,8 @@ TEST(LaLoop2c) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); - Counter c2(w2, 0, 1); + Counter c1(&w1, 0, 1); + Counter c2(&w2, 0, 1); w2.chain(w1.exit); t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w2.exit); @@ -396,10 +396,10 @@ TEST(LaLoop2cc) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); + Counter c1(&w1, 0, 1); // various usage scenarios for the second loop. - Counter c2(w2, i & 1 ? t.p0 : c1.phi, i & 2 ? t.p0 : c1.phi); + Counter c2(&w2, i & 1 ? t.p0 : c1.phi, i & 2 ? t.p0 : c1.phi); if (i & 3) w2.branch->ReplaceInput(0, c1.phi); w2.chain(w1.exit); @@ -431,7 +431,7 @@ TEST(LaNestedLoop1) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - w2.nest(w1); + w2.nest(&w1); t.Return(t.p0, t.start, w1.exit); Node* chain[] = {w1.loop, w2.loop}; @@ -452,10 +452,10 @@ TEST(LaNestedLoop1c) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); - Counter c2(w2, 0, 1); + Counter c1(&w1, 0, 1); + Counter c2(&w2, 0, 1); w2.branch->ReplaceInput(0, c2.phi); - w2.nest(w1); + w2.nest(&w1); t.Return(c1.phi, t.start, w1.exit); Node* chain[] = {w1.loop, w2.loop}; @@ -477,7 +477,7 @@ TEST(LaNestedLoop1x) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - w2.nest(w1); + w2.nest(&w1); const Operator* op = t.common.Phi(MachineRepresentation::kWord32, 2); Node* p1a = t.graph.NewNode(op, t.p0, t.p0, w1.loop); @@ -513,8 +513,8 @@ TEST(LaNestedLoop2) { While w1(t, t.p0); While w2(t, t.p0); While w3(t, t.p0); - w2.nest(w1); - w3.nest(w1); + w2.nest(&w1); + w3.nest(&w1); w3.chain(w2.exit); t.Return(t.p0, t.start, w1.exit); @@ -573,11 +573,11 @@ TEST(LaNestedLoop3c) { // Three nested loops with counters. LoopFinderTester t; While w1(t, t.p0); - Counter c1(w1, 0, 1); + Counter c1(&w1, 0, 1); While w2(t, t.p0); - Counter c2(w2, 0, 1); + Counter c2(&w2, 0, 1); While w3(t, t.p0); - Counter c3(w3, 0, 1); + Counter c3(&w3, 0, 1); w2.loop->ReplaceInput(0, w1.if_true); w3.loop->ReplaceInput(0, w2.if_true); w2.loop->ReplaceInput(1, w3.exit); diff --git a/deps/v8/test/cctest/compiler/test-multiple-return.cc b/deps/v8/test/cctest/compiler/test-multiple-return.cc index c054e7654a..ad1c7efbd7 100644 --- a/deps/v8/test/cctest/compiler/test-multiple-return.cc +++ b/deps/v8/test/cctest/compiler/test-multiple-return.cc @@ -43,81 +43,76 @@ CallDescriptor* CreateCallDescriptor(Zone* zone, int return_count, return compiler::GetWasmCallDescriptor(zone, builder.Build()); } -Node* MakeConstant(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, int value) { +Node* MakeConstant(RawMachineAssembler* m, MachineType type, int value) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Constant(static_cast<int32_t>(value)); + return m->Int32Constant(static_cast<int32_t>(value)); case MachineRepresentation::kWord64: - return m.Int64Constant(static_cast<int64_t>(value)); + return m->Int64Constant(static_cast<int64_t>(value)); case MachineRepresentation::kFloat32: - return m.Float32Constant(static_cast<float>(value)); + return m->Float32Constant(static_cast<float>(value)); case MachineRepresentation::kFloat64: - return m.Float64Constant(static_cast<double>(value)); + return m->Float64Constant(static_cast<double>(value)); default: UNREACHABLE(); } } -Node* Add(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Add(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Add(a, b); + return m->Int32Add(a, b); case MachineRepresentation::kWord64: - return m.Int64Add(a, b); + return m->Int64Add(a, b); case MachineRepresentation::kFloat32: - return m.Float32Add(a, b); + return m->Float32Add(a, b); case MachineRepresentation::kFloat64: - return m.Float64Add(a, b); + return m->Float64Add(a, b); default: UNREACHABLE(); } } -Node* Sub(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Sub(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Sub(a, b); + return m->Int32Sub(a, b); case MachineRepresentation::kWord64: - return m.Int64Sub(a, b); + return m->Int64Sub(a, b); case MachineRepresentation::kFloat32: - return m.Float32Sub(a, b); + return m->Float32Sub(a, b); case MachineRepresentation::kFloat64: - return m.Float64Sub(a, b); + return m->Float64Sub(a, b); default: UNREACHABLE(); } } -Node* Mul(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Mul(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Mul(a, b); + return m->Int32Mul(a, b); case MachineRepresentation::kWord64: - return m.Int64Mul(a, b); + return m->Int64Mul(a, b); case MachineRepresentation::kFloat32: - return m.Float32Mul(a, b); + return m->Float32Mul(a, b); case MachineRepresentation::kFloat64: - return m.Float64Mul(a, b); + return m->Float64Mul(a, b); default: UNREACHABLE(); } } -Node* ToInt32(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a) { +Node* ToInt32(RawMachineAssembler* m, MachineType type, Node* a) { switch (type.representation()) { case MachineRepresentation::kWord32: return a; case MachineRepresentation::kWord64: - return m.TruncateInt64ToInt32(a); + return m->TruncateInt64ToInt32(a); case MachineRepresentation::kFloat32: - return m.TruncateFloat32ToInt32(a); + return m->TruncateFloat32ToInt32(a); case MachineRepresentation::kFloat64: - return m.RoundFloat64ToInt32(a); + return m->RoundFloat64ToInt32(a); default: UNREACHABLE(); } @@ -159,9 +154,9 @@ void TestReturnMultipleValues(MachineType type) { using Node_ptr = Node*; std::unique_ptr<Node_ptr[]> returns(new Node_ptr[count]); for (int i = 0; i < count; ++i) { - if (i % 3 == 0) returns[i] = Add(m, type, p0, p1); - if (i % 3 == 1) returns[i] = Sub(m, type, p0, p1); - if (i % 3 == 2) returns[i] = Mul(m, type, p0, p1); + if (i % 3 == 0) returns[i] = Add(&m, type, p0, p1); + if (i % 3 == 1) returns[i] = Sub(&m, type, p0, p1); + if (i % 3 == 2) returns[i] = Mul(&m, type, p0, p1); } m.Return(count, returns.get()); @@ -175,7 +170,7 @@ void TestReturnMultipleValues(MachineType type) { #ifdef ENABLE_DISASSEMBLER if (FLAG_print_code) { StdoutStream os; - code->Disassemble("multi_value", os); + code->Disassemble("multi_value", os, handles.main_isolate()); } #endif @@ -201,29 +196,29 @@ void TestReturnMultipleValues(MachineType type) { // WasmContext dummy call_inputs[1] = mt.PointerConstant(nullptr); // Special inputs for the test. - call_inputs[2] = MakeConstant(mt, type, a); - call_inputs[3] = MakeConstant(mt, type, b); + call_inputs[2] = MakeConstant(&mt, type, a); + call_inputs[3] = MakeConstant(&mt, type, b); for (int i = 2; i < param_count; i++) { - call_inputs[2 + i] = MakeConstant(mt, type, i); + call_inputs[2 + i] = MakeConstant(&mt, type, i); } Node* ret_multi = mt.AddNode(mt.common()->Call(desc), input_count, call_inputs); - Node* ret = MakeConstant(mt, type, 0); + Node* ret = MakeConstant(&mt, type, 0); bool sign = false; for (int i = 0; i < count; ++i) { Node* x = (count == 1) ? ret_multi : mt.AddNode(mt.common()->Projection(i), ret_multi); - ret = sign ? Sub(mt, type, ret, x) : Add(mt, type, ret, x); + ret = sign ? Sub(&mt, type, ret, x) : Add(&mt, type, ret, x); if (i % 4 == 0) sign = !sign; } - mt.Return(ToInt32(mt, type, ret)); + mt.Return(ToInt32(&mt, type, ret)); #ifdef ENABLE_DISASSEMBLER Handle<Code> code2 = mt.GetCode(); if (FLAG_print_code) { StdoutStream os; - code2->Disassemble("multi_value_call", os); + code2->Disassemble("multi_value_call", os, handles.main_isolate()); } #endif CHECK_EQ(expect, mt.Call()); @@ -265,7 +260,7 @@ void ReturnLastValue(MachineType type) { std::unique_ptr<Node* []> returns(new Node*[return_count]); for (int i = 0; i < return_count; ++i) { - returns[i] = MakeConstant(m, type, i); + returns[i] = MakeConstant(&m, type, i); } m.Return(return_count, returns.get()); @@ -292,8 +287,9 @@ void ReturnLastValue(MachineType type) { Node* call = mt.AddNode(mt.common()->Call(desc), 2, inputs); - mt.Return(ToInt32( - mt, type, mt.AddNode(mt.common()->Projection(return_count - 1), call))); + mt.Return( + ToInt32(&mt, type, + mt.AddNode(mt.common()->Projection(return_count - 1), call))); CHECK_EQ(expect, mt.Call()); } @@ -327,7 +323,7 @@ void ReturnSumOfReturns(MachineType type) { std::unique_ptr<Node* []> returns(new Node*[return_count]); for (int i = 0; i < return_count; ++i) { - returns[i] = MakeConstant(m, type, i); + returns[i] = MakeConstant(&m, type, i); } m.Return(return_count, returns.get()); @@ -360,7 +356,7 @@ void ReturnSumOfReturns(MachineType type) { expect += i; result = mt.Int32Add( result, - ToInt32(mt, type, mt.AddNode(mt.common()->Projection(i), call))); + ToInt32(&mt, type, mt.AddNode(mt.common()->Projection(i), call))); } mt.Return(result); diff --git a/deps/v8/test/cctest/compiler/test-run-load-store.cc b/deps/v8/test/cctest/compiler/test-run-load-store.cc index 3a8e9d61d4..6f52f339f3 100644 --- a/deps/v8/test/cctest/compiler/test-run-load-store.cc +++ b/deps/v8/test/cctest/compiler/test-run-load-store.cc @@ -37,6 +37,11 @@ enum TestAlignment { #define A_GIG (1024ULL * 1024ULL * 1024ULL) namespace { +byte* ComputeOffset(void* real_address, int32_t offset) { + return reinterpret_cast<byte*>(reinterpret_cast<Address>(real_address) - + offset); +} + void RunLoadInt32(const TestAlignment t) { RawMachineAssemblerTester<int32_t> m; @@ -65,7 +70,7 @@ void RunLoadInt32Offset(TestAlignment t) { for (size_t i = 0; i < arraysize(offsets); i++) { RawMachineAssemblerTester<int32_t> m; int32_t offset = offsets[i]; - byte* pointer = reinterpret_cast<byte*>(&p1) - offset; + byte* pointer = ComputeOffset(&p1, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { @@ -93,8 +98,8 @@ void RunLoadStoreFloat32Offset(TestAlignment t) { base::AddWithWraparound(0x2342AABB, base::MulWithWraparound(i, 3)); RawMachineAssemblerTester<int32_t> m; int32_t offset = i; - byte* from = reinterpret_cast<byte*>(&p1) - offset; - byte* to = reinterpret_cast<byte*>(&p2) - offset; + byte* from = ComputeOffset(&p1, offset); + byte* to = ComputeOffset(&p2, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), @@ -131,8 +136,8 @@ void RunLoadStoreFloat64Offset(TestAlignment t) { base::AddWithWraparound(0x2342AABB, base::MulWithWraparound(i, 3)); RawMachineAssemblerTester<int32_t> m; int32_t offset = i; - byte* from = reinterpret_cast<byte*>(&p1) - offset; - byte* to = reinterpret_cast<byte*>(&p2) - offset; + byte* from = ComputeOffset(&p1, offset); + byte* to = ComputeOffset(&p2, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), @@ -259,7 +264,7 @@ void RunLoadImmIndex(MachineType type, TestAlignment t) { for (int offset = -1; offset <= 200000; offset *= -5) { for (int i = 0; i < kNumElems; i++) { BufferedRawMachineAssemblerTester<CType> m; - void* base_pointer = &buffer[0] - offset; + void* base_pointer = ComputeOffset(&buffer[0], offset * sizeof(CType)); #ifdef V8_COMPRESS_POINTERS if (type.IsTagged()) { // When pointer compression is enabled then we need to access only diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc index 1e5a73389e..ccc05ce11b 100644 --- a/deps/v8/test/cctest/compiler/test-run-machops.cc +++ b/deps/v8/test/cctest/compiler/test-run-machops.cc @@ -10,9 +10,10 @@ #include "src/base/ieee754.h" #include "src/base/overflowing-math.h" #include "src/base/utils/random-number-generator.h" +#include "src/common/ptr-compr-inl.h" +#include "src/objects/objects-inl.h" #include "src/utils/boxed-float.h" #include "src/utils/utils.h" -#include "src/objects/objects-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/value-helper.h" @@ -410,12 +411,15 @@ TEST(CompressDecompressTaggedAnyPointer) { } TEST(CompressDecompressTaggedAnySigned) { - RawMachineAssemblerTester<int64_t> m; + RawMachineAssemblerTester<void*> m; Smi smi = Smi::FromInt(123); - int64_t smiPointer = static_cast<int64_t>(smi.ptr()); - Node* node = m.Int64Constant(smiPointer); + Node* node = m.Int64Constant(static_cast<int64_t>(smi.ptr())); m.Return(m.ChangeCompressedToTagged(m.ChangeTaggedToCompressed(node))); - CHECK_EQ(smiPointer, m.Call()); + + Object result = Object(reinterpret_cast<Address>(m.Call())); + Address smiPointer = + DecompressTaggedAny(m.isolate(), CompressTagged(smi.ptr())); + CHECK_EQ(smiPointer, result.ptr()); } TEST(CompressDecompressTaggedPointer) { @@ -432,13 +436,15 @@ TEST(CompressDecompressTaggedPointer) { } TEST(CompressDecompressTaggedSigned) { - RawMachineAssemblerTester<int64_t> m; + RawMachineAssemblerTester<void*> m; Smi smi = Smi::FromInt(123); - int64_t smiPointer = static_cast<int64_t>(smi.ptr()); - Node* node = m.Int64Constant(smiPointer); + Address smiPointer = smi.ptr(); + Node* node = m.Int64Constant(static_cast<int64_t>(smiPointer)); m.Return(m.ChangeCompressedSignedToTaggedSigned( m.ChangeTaggedSignedToCompressedSigned(node))); - CHECK_EQ(smiPointer, m.Call()); + + Object result = Object(reinterpret_cast<Address>(m.Call())); + CHECK_EQ(smiPointer, result.ptr()); } #endif // V8_COMPRESS_POINTERS diff --git a/deps/v8/test/cctest/compiler/test-run-native-calls.cc b/deps/v8/test/cctest/compiler/test-run-native-calls.cc index 026e8307ae..6ab480743b 100644 --- a/deps/v8/test/cctest/compiler/test-run-native-calls.cc +++ b/deps/v8/test/cctest/compiler/test-run-native-calls.cc @@ -254,7 +254,7 @@ Handle<Code> CompileGraph(const char* name, CallDescriptor* call_descriptor, #ifdef ENABLE_DISASSEMBLER if (FLAG_print_opt_code) { StdoutStream os; - code->Disassemble(name, os); + code->Disassemble(name, os, isolate); } #endif return code; @@ -327,38 +327,32 @@ class ArgsBuffer { return kTypes; } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - int32_t value) { - return raw.Int32Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, int32_t value) { + return raw->Int32Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - int64_t value) { - return raw.Int64Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, int64_t value) { + return raw->Int64Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - float32 value) { - return raw.Float32Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, float32 value) { + return raw->Float32Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - float64 value) { - return raw.Float64Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, float64 value) { + return raw->Float64Constant(value); } - Node* LoadInput(RawMachineAssembler& raw, // NOLINT(runtime/references) - Node* base, int index) { - Node* offset = raw.Int32Constant(index * sizeof(CType)); - return raw.Load(MachineTypeForC<CType>(), base, offset); + Node* LoadInput(RawMachineAssembler* raw, Node* base, int index) { + Node* offset = raw->Int32Constant(index * sizeof(CType)); + return raw->Load(MachineTypeForC<CType>(), base, offset); } - Node* StoreOutput(RawMachineAssembler& raw, // NOLINT(runtime/references) - Node* value) { - Node* base = raw.PointerConstant(&output); - Node* offset = raw.Int32Constant(0); - return raw.Store(MachineTypeForC<CType>().representation(), base, offset, - value, kNoWriteBarrier); + Node* StoreOutput(RawMachineAssembler* raw, Node* value) { + Node* base = raw->PointerConstant(&output); + Node* offset = raw->Int32Constant(0); + return raw->Store(MachineTypeForC<CType>().representation(), base, offset, + value, kNoWriteBarrier); } // Computes the next set of inputs by updating the {input} array. @@ -425,7 +419,7 @@ template <typename CType> class Computer { public: static void Run(CallDescriptor* desc, - void (*build)(CallDescriptor*, RawMachineAssembler&), + void (*build)(CallDescriptor*, RawMachineAssembler*), CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { int num_params = ParamCount(desc); @@ -438,7 +432,7 @@ class Computer { Zone zone(isolate->allocator(), ZONE_NAME); Graph graph(&zone); RawMachineAssembler raw(isolate, &graph, desc); - build(desc, raw); + build(desc, &raw); inner = CompileGraph("Compute", desc, &graph, raw.ExportForTest()); } @@ -459,11 +453,11 @@ class Computer { int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = io.MakeConstant(raw, io.input[i]); + inputs[input_count++] = io.MakeConstant(&raw, io.input[i]); } Node* call = raw.CallN(desc, input_count, inputs); - Node* store = io.StoreOutput(raw, call); + Node* store = io.StoreOutput(&raw, call); USE(store); raw.Return(raw.Int32Constant(seed)); wrapper = CompileGraph("Compute-wrapper-const", cdesc, &graph, @@ -494,11 +488,11 @@ class Computer { int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = io.LoadInput(raw, base, i); + inputs[input_count++] = io.LoadInput(&raw, base, i); } Node* call = raw.CallN(desc, input_count, inputs); - Node* store = io.StoreOutput(raw, call); + Node* store = io.StoreOutput(&raw, call); USE(store); raw.Return(raw.Int32Constant(seed)); wrapper = @@ -704,28 +698,25 @@ TEST(Run_CopyTwentyInt32_all_allocatable_pairs) { } } - template <typename CType> static void Run_Computation( - CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&), + CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler*), CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { Computer<CType>::Run(desc, build, compute, seed); } - static uint32_t coeff[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113}; -static void Build_Int32_WeightedSum( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) - Node* result = raw.Int32Constant(0); +static void Build_Int32_WeightedSum(CallDescriptor* desc, + RawMachineAssembler* raw) { + Node* result = raw->Int32Constant(0); for (int i = 0; i < ParamCount(desc); i++) { - Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i])); - result = raw.Int32Add(result, term); + Node* term = raw->Int32Mul(raw->Parameter(i), raw->Int32Constant(coeff[i])); + result = raw->Int32Add(result, term); } - raw.Return(result); + raw->Return(result); } static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) { @@ -774,10 +765,8 @@ TEST_INT32_WEIGHTEDSUM(17) TEST_INT32_WEIGHTEDSUM(19) template <int which> -static void Build_Select( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) - raw.Return(raw.Parameter(which)); +static void Build_Select(CallDescriptor* desc, RawMachineAssembler* raw) { + raw->Return(raw->Parameter(which)); } template <typename CType, int which> @@ -950,9 +939,8 @@ TEST(Float64Select_stack_params_return_reg) { } template <typename CType, int which> -static void Build_Select_With_Call( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) +static void Build_Select_With_Call(CallDescriptor* desc, + RawMachineAssembler* raw) { Handle<Code> inner = Handle<Code>::null(); int num_params = ParamCount(desc); CHECK_LE(num_params, kMaxParamCount); @@ -971,16 +959,16 @@ static void Build_Select_With_Call( { // Build a call to the function that does the select. - Node* target = raw.HeapConstant(inner); - Node** inputs = raw.zone()->NewArray<Node*>(num_params + 1); + Node* target = raw->HeapConstant(inner); + Node** inputs = raw->zone()->NewArray<Node*>(num_params + 1); int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = raw.Parameter(i); + inputs[input_count++] = raw->Parameter(i); } - Node* call = raw.CallN(desc, input_count, inputs); - raw.Return(call); + Node* call = raw->CallN(desc, input_count, inputs); + raw->Return(call); } } diff --git a/deps/v8/test/cctest/heap/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h index 6f6cfb46b5..0b47665a78 100644 --- a/deps/v8/test/cctest/heap/heap-tester.h +++ b/deps/v8/test/cctest/heap/heap-tester.h @@ -14,6 +14,7 @@ V(CompactionFullAbortedPage) \ V(CompactionPartiallyAbortedPage) \ V(CompactionPartiallyAbortedPageIntraAbortedPointers) \ + V(CompactionPartiallyAbortedPageWithInvalidatedSlots) \ V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \ V(CompactionSpaceDivideMultiplePages) \ V(CompactionSpaceDivideSinglePage) \ @@ -102,6 +103,7 @@ class HeapTester { // test-heap.cc static AllocationResult AllocateByteArrayForTest(Heap* heap, int length, AllocationType allocation); + static bool CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes); // test-mark-compact.cc static AllocationResult AllocateMapForTest(v8::internal::Isolate* isolate); diff --git a/deps/v8/test/cctest/heap/heap-utils.cc b/deps/v8/test/cctest/heap/heap-utils.cc index 8b53dab9c5..3fa2714a61 100644 --- a/deps/v8/test/cctest/heap/heap-utils.cc +++ b/deps/v8/test/cctest/heap/heap-utils.cc @@ -98,11 +98,15 @@ std::vector<Handle<FixedArray>> CreatePadding(Heap* heap, int padding_size, allocate_memory = free_memory; length = FixedArrayLenFromSize(allocate_memory); if (length <= 0) { - // Not enough room to create another fixed array. Let's create a filler. - if (free_memory > (2 * kTaggedSize)) { + // Not enough room to create another FixedArray, so create a filler. + if (allocation == i::AllocationType::kOld) { heap->CreateFillerObjectAt( *heap->old_space()->allocation_top_address(), free_memory, ClearRecordedSlots::kNo); + } else { + heap->CreateFillerObjectAt( + *heap->new_space()->allocation_top_address(), free_memory, + ClearRecordedSlots::kNo); } break; } @@ -127,8 +131,9 @@ void AllocateAllButNBytes(v8::internal::NewSpace* space, int extra_bytes, if (new_linear_size == 0) return; std::vector<Handle<FixedArray>> handles = heap::CreatePadding( space->heap(), new_linear_size, i::AllocationType::kYoung); - if (out_handles != nullptr) + if (out_handles != nullptr) { out_handles->insert(out_handles->end(), handles.begin(), handles.end()); + } } void FillCurrentPage(v8::internal::NewSpace* space, @@ -144,8 +149,9 @@ bool FillUpOnePage(v8::internal::NewSpace* space, if (space_remaining == 0) return false; std::vector<Handle<FixedArray>> handles = heap::CreatePadding( space->heap(), space_remaining, i::AllocationType::kYoung); - if (out_handles != nullptr) + if (out_handles != nullptr) { out_handles->insert(out_handles->end(), handles.begin(), handles.end()); + } return true; } diff --git a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc index b4122c9619..66354cab7f 100644 --- a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc +++ b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc @@ -193,8 +193,8 @@ TEST(ArrayBuffer_UnregisterDuringSweep) { // barriers and proper synchronization this will trigger a data race on // TSAN. v8::ArrayBuffer::Contents contents = ab->Externalize(); - heap->isolate()->array_buffer_allocator()->Free(contents.Data(), - contents.ByteLength()); + contents.Deleter()(contents.Data(), contents.ByteLength(), + contents.DeleterData()); } } diff --git a/deps/v8/test/cctest/heap/test-compaction.cc b/deps/v8/test/cctest/heap/test-compaction.cc index 35bd9225ea..96eca0f5ae 100644 --- a/deps/v8/test/cctest/heap/test-compaction.cc +++ b/deps/v8/test/cctest/heap/test-compaction.cc @@ -6,6 +6,7 @@ #include "src/heap/factory.h" #include "src/heap/heap-inl.h" #include "src/heap/mark-compact.h" +#include "src/heap/remembered-set.h" #include "src/objects/objects-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/heap/heap-tester.h" @@ -31,9 +32,8 @@ void CheckInvariantsOfAbortedPage(Page* page) { CHECK(!page->IsFlagSet(Page::COMPACTION_WAS_ABORTED)); } -void CheckAllObjectsOnPage( - std::vector<Handle<FixedArray>>& handles, // NOLINT(runtime/references) - Page* page) { +void CheckAllObjectsOnPage(const std::vector<Handle<FixedArray>>& handles, + Page* page) { for (Handle<FixedArray> fixed_array : handles) { CHECK(Page::FromHeapObject(*fixed_array) == page); } @@ -85,6 +85,18 @@ HEAP_TEST(CompactionFullAbortedPage) { } } +namespace { + +int GetObjectSize(int objects_per_page) { + int allocatable = + static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()); + // Make sure that object_size is a multiple of kTaggedSize. + int object_size = + ((allocatable / kTaggedSize) / objects_per_page) * kTaggedSize; + return Min(kMaxRegularHeapObjectSize, object_size); +} + +} // namespace HEAP_TEST(CompactionPartiallyAbortedPage) { if (FLAG_never_compact) return; @@ -97,10 +109,7 @@ HEAP_TEST(CompactionPartiallyAbortedPage) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -163,6 +172,81 @@ HEAP_TEST(CompactionPartiallyAbortedPage) { } } +HEAP_TEST(CompactionPartiallyAbortedPageWithInvalidatedSlots) { + if (FLAG_never_compact) return; + // Test evacuating a page partially when it contains recorded + // slots and invalidated objects. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + ManualGCScope manual_gc_scope; + FLAG_manual_evacuation_candidates_selection = true; + + const int objects_per_page = 10; + const int object_size = GetObjectSize(objects_per_page); + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + + heap::SealCurrentObjects(heap); + + { + HandleScope scope2(isolate); + // Fill another page with objects of size {object_size} (last one is + // properly adjusted). + CHECK(heap->old_space()->Expand()); + auto compaction_page_handles = heap::CreatePadding( + heap, + static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()), + AllocationType::kOld, object_size); + Page* to_be_aborted_page = + Page::FromHeapObject(*compaction_page_handles.front()); + for (Handle<FixedArray> object : compaction_page_handles) { + CHECK_EQ(Page::FromHeapObject(*object), to_be_aborted_page); + + for (int i = 0; i < object->length(); i++) { + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>( + to_be_aborted_page, object->RawFieldOfElementAt(i).address()); + } + } + // First object is going to be evacuated. + to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>( + *compaction_page_handles.front()); + // Last object is NOT going to be evacuated. + // This happens since not all objects fit on the only other page in the + // old space, the GC isn't allowed to allocate another page. + to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>( + *compaction_page_handles.back()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + + { + // Add another page that is filled with {num_objects} objects of size + // {object_size}. + HandleScope scope3(isolate); + CHECK(heap->old_space()->Expand()); + const int num_objects = 3; + std::vector<Handle<FixedArray>> page_to_fill_handles = + heap::CreatePadding(heap, object_size * num_objects, + AllocationType::kOld, object_size); + Page* page_to_fill = + Page::FromAddress(page_to_fill_handles.front()->address()); + + heap->set_force_oom(true); + CcTest::CollectAllGarbage(); + heap->mark_compact_collector()->EnsureSweepingCompleted(); + + CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.front()), + page_to_fill); + CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.back()), + to_be_aborted_page); + } + } + } +} HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) { if (FLAG_never_compact) return; @@ -177,10 +261,7 @@ HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -271,10 +352,7 @@ HEAP_TEST(CompactionPartiallyAbortedPageWithStoreBufferEntries) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); diff --git a/deps/v8/test/cctest/heap/test-embedder-tracing.cc b/deps/v8/test/cctest/heap/test-embedder-tracing.cc index 28553266ff..8ff4acc05b 100644 --- a/deps/v8/test/cctest/heap/test-embedder-tracing.cc +++ b/deps/v8/test/cctest/heap/test-embedder-tracing.cc @@ -17,12 +17,6 @@ namespace v8 { -// See test below: TracedGlobalNoDestructor. -template <> -struct TracedGlobalTrait<v8::TracedGlobal<v8::Value>> { - static constexpr bool kRequiresExplicitDestruction = false; -}; - namespace internal { namespace heap { @@ -68,7 +62,7 @@ class TestEmbedderHeapTracer final : public v8::EmbedderHeapTracer { bool AdvanceTracing(double deadline_in_ms) final { for (auto global : to_register_with_v8_) { - RegisterEmbedderReference(global->As<v8::Value>()); + RegisterEmbedderReference(global->As<v8::Data>()); } to_register_with_v8_.clear(); return true; @@ -293,13 +287,14 @@ void ConstructJSObject(v8::Isolate* isolate, v8::Local<v8::Context> context, CHECK(!global->IsEmpty()); } +template <typename T> void ConstructJSApiObject(v8::Isolate* isolate, v8::Local<v8::Context> context, - v8::TracedGlobal<v8::Object>* global) { + T* global) { v8::HandleScope scope(isolate); v8::Local<v8::Object> object( ConstructTraceableJSApiObject(context, nullptr, nullptr)); CHECK(!object.IsEmpty()); - *global = v8::TracedGlobal<v8::Object>(isolate, object); + *global = T(isolate, object); CHECK(!global->IsEmpty()); } @@ -360,10 +355,6 @@ TEST(TracedGlobalCopyWithDestructor) { v8::HandleScope scope(isolate); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); - const size_t initial_count = global_handles->handles_count(); v8::TracedGlobal<v8::Object> global1; { @@ -401,18 +392,14 @@ TEST(TracedGlobalCopyNoDestructor) { v8::HandleScope scope(isolate); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); - const size_t initial_count = global_handles->handles_count(); - v8::TracedGlobal<v8::Value> global1; + v8::TracedReference<v8::Value> global1; { v8::HandleScope scope(isolate); global1.Reset(isolate, v8::Object::New(isolate)); } - v8::TracedGlobal<v8::Value> global2(global1); - v8::TracedGlobal<v8::Value> global3; + v8::TracedReference<v8::Value> global2(global1); + v8::TracedReference<v8::Value> global3; global3 = global2; CHECK_EQ(initial_count + 3, global_handles->handles_count()); CHECK(!global1.IsEmpty()); @@ -500,7 +487,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectSurvivesScavengePerDefault) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(true); TracedGlobalTest( - CcTest::isolate(), ConstructJSApiObject, + CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>, [](const TracedGlobal<v8::Object>& global) {}, InvokeScavenge, SurvivalMode::kSurvives); } @@ -513,7 +500,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectDiesOnScavengeWhenExcludedFromRoots) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(false); TracedGlobalTest( - CcTest::isolate(), ConstructJSApiObject, + CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>, [](const TracedGlobal<v8::Object>& global) {}, InvokeScavenge, SurvivalMode::kDies); } @@ -671,9 +658,6 @@ TEST(TracedGlobalWithDestructor) { CHECK(!traced->IsEmpty()); CHECK_EQ(initial_count + 1, global_handles->handles_count()); } - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); delete traced; CHECK_EQ(initial_count, global_handles->handles_count()); // GC should not need to clear the handle. @@ -691,21 +675,18 @@ TEST(TracedGlobalNoDestructor) { i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); const size_t initial_count = global_handles->handles_count(); - char* memory = new char[sizeof(v8::TracedGlobal<v8::Value>)]; - auto* traced = new (memory) v8::TracedGlobal<v8::Value>(); + char* memory = new char[sizeof(v8::TracedReference<v8::Value>)]; + auto* traced = new (memory) v8::TracedReference<v8::Value>(); { v8::HandleScope scope(isolate); v8::Local<v8::Value> object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), nullptr, nullptr)); CHECK(traced->IsEmpty()); - *traced = v8::TracedGlobal<v8::Value>(isolate, object); + *traced = v8::TracedReference<v8::Value>(isolate, object); CHECK(!traced->IsEmpty()); CHECK_EQ(initial_count + 1, global_handles->handles_count()); } - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); - traced->~TracedGlobal<v8::Value>(); + traced->~TracedReference<v8::Value>(); CHECK_EQ(initial_count + 1, global_handles->handles_count()); // GC should clear the handle. heap::InvokeMarkSweep(); @@ -759,18 +740,19 @@ class EmbedderHeapTracerNoDestructorNonTracingClearing final uint16_t class_id_to_optimize) : class_id_to_optimize_(class_id_to_optimize) {} - bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) final { + bool IsRootForNonTracingGC( + const v8::TracedReference<v8::Value>& handle) final { return handle.WrapperClassId() != class_id_to_optimize_; } void ResetHandleInNonTracingGC( - const v8::TracedGlobal<v8::Value>& handle) final { + const v8::TracedReference<v8::Value>& handle) final { if (handle.WrapperClassId() != class_id_to_optimize_) return; // Convention (for test): Objects that are optimized have their first field // set as a back pointer. - TracedGlobal<v8::Value>* original_handle = - reinterpret_cast<TracedGlobal<v8::Value>*>( + TracedReferenceBase<v8::Value>* original_handle = + reinterpret_cast<TracedReferenceBase<v8::Value>*>( v8::Object::GetAlignedPointerFromInternalField( handle.As<v8::Object>(), 0)); original_handle->Reset(); @@ -781,23 +763,23 @@ class EmbedderHeapTracerNoDestructorNonTracingClearing final }; template <typename T> -void SetupOptimizedAndNonOptimizedHandle( - v8::Isolate* isolate, uint16_t optimized_class_id, - v8::TracedGlobal<T>* optimized_handle, - v8::TracedGlobal<T>* non_optimized_handle) { +void SetupOptimizedAndNonOptimizedHandle(v8::Isolate* isolate, + uint16_t optimized_class_id, + T* optimized_handle, + T* non_optimized_handle) { v8::HandleScope scope(isolate); v8::Local<v8::Object> optimized_object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), optimized_handle, nullptr)); CHECK(optimized_handle->IsEmpty()); - *optimized_handle = v8::TracedGlobal<T>(isolate, optimized_object); + *optimized_handle = T(isolate, optimized_object); CHECK(!optimized_handle->IsEmpty()); optimized_handle->SetWrapperClassId(optimized_class_id); v8::Local<v8::Object> non_optimized_object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), nullptr, nullptr)); CHECK(non_optimized_handle->IsEmpty()); - *non_optimized_handle = v8::TracedGlobal<T>(isolate, non_optimized_object); + *non_optimized_handle = T(isolate, non_optimized_object); CHECK(!non_optimized_handle->IsEmpty()); } @@ -813,9 +795,6 @@ TEST(TracedGlobalDestructorReclaimedOnScavenge) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); const size_t initial_count = global_handles->handles_count(); auto* optimized_handle = new v8::TracedGlobal<v8::Object>(); auto* non_optimized_handle = new v8::TracedGlobal<v8::Object>(); @@ -841,12 +820,9 @@ TEST(TracedGlobalNoDestructorReclaimedOnScavenge) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); const size_t initial_count = global_handles->handles_count(); - auto* optimized_handle = new v8::TracedGlobal<v8::Value>(); - auto* non_optimized_handle = new v8::TracedGlobal<v8::Value>(); + auto* optimized_handle = new v8::TracedReference<v8::Value>(); + auto* non_optimized_handle = new v8::TracedReference<v8::Value>(); SetupOptimizedAndNonOptimizedHandle(isolate, kClassIdToOptimize, optimized_handle, non_optimized_handle); CHECK_EQ(initial_count + 2, global_handles->handles_count()); diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc index fd17c0f063..03f98c6453 100644 --- a/deps/v8/test/cctest/heap/test-heap.cc +++ b/deps/v8/test/cctest/heap/test-heap.cc @@ -1791,7 +1791,7 @@ TEST(HeapNumberAlignment) { AlignOldSpace(required_alignment, offset); Handle<Object> number_old = - factory->NewNumber(1.000321, AllocationType::kOld); + factory->NewNumber<AllocationType::kOld>(1.000321); CHECK(number_old->IsHeapNumber()); CHECK(heap->InOldSpace(*number_old)); CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_old).address(), @@ -3663,9 +3663,58 @@ TEST(DeferredHandles) { DeferredHandleScope deferred(isolate); DummyVisitor visitor; isolate->handle_scope_implementer()->Iterate(&visitor); - delete deferred.Detach(); + deferred.Detach(); } +static void TestFillersFromDeferredHandles(bool promote) { + // We assume that the fillers can only arise when left-trimming arrays. + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); + + const size_t n = 10; + Handle<FixedArray> array = isolate->factory()->NewFixedArray(n); + + if (promote) { + // Age the array so it's ready for promotion on next GC. + CcTest::CollectGarbage(NEW_SPACE); + } + CHECK(Heap::InYoungGeneration(*array)); + + DeferredHandleScope deferred_scope(isolate); + + // Trim the array three times to different sizes so all kinds of fillers are + // created and tracked by the deferred handles. + Handle<FixedArrayBase> filler_1 = Handle<FixedArrayBase>(*array, isolate); + Handle<FixedArrayBase> filler_2 = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_1, 1), isolate); + Handle<FixedArrayBase> filler_3 = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_2, 2), isolate); + Handle<FixedArrayBase> tail = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_3, 3), isolate); + + std::unique_ptr<DeferredHandles> deferred_handles(deferred_scope.Detach()); + + // GC should retain the trimmed array but drop all of the three fillers. + CcTest::CollectGarbage(NEW_SPACE); + if (promote) { + CHECK(heap->InOldSpace(*tail)); + } else { + CHECK(Heap::InYoungGeneration(*tail)); + } + CHECK_EQ(n - 6, (*tail).length()); + CHECK(!filler_1->IsHeapObject()); + CHECK(!filler_2->IsHeapObject()); + CHECK(!filler_3->IsHeapObject()); +} + +TEST(DoNotEvacuateFillersFromDeferredHandles) { + TestFillersFromDeferredHandles(false /*promote*/); +} + +TEST(DoNotPromoteFillersFromDeferredHandles) { + TestFillersFromDeferredHandles(true /*promote*/); +} TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { if (!FLAG_incremental_marking) return; @@ -5269,34 +5318,6 @@ TEST(ScriptIterator) { CHECK_EQ(0, script_count); } - -TEST(SharedFunctionInfoIterator) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Heap* heap = CcTest::heap(); - LocalContext context; - - CcTest::CollectAllGarbage(); - CcTest::CollectAllGarbage(); - - int sfi_count = 0; - { - HeapObjectIterator it(heap); - for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) { - if (!obj.IsSharedFunctionInfo()) continue; - sfi_count++; - } - } - - { - SharedFunctionInfo::GlobalIterator iterator(isolate); - while (!iterator.Next().is_null()) sfi_count--; - } - - CHECK_EQ(0, sfi_count); -} - // This is the same as Factory::NewByteArray, except it doesn't retry on // allocation failure. AllocationResult HeapTester::AllocateByteArrayForTest( @@ -5316,6 +5337,11 @@ AllocationResult HeapTester::AllocateByteArrayForTest( return result; } +bool HeapTester::CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes) { + return heap->code_space()->EnsureLinearAllocationArea( + size_in_bytes, AllocationOrigin::kRuntime); +} + HEAP_TEST(Regress587004) { ManualGCScope manual_gc_scope; #ifdef VERIFY_HEAP @@ -5995,6 +6021,173 @@ TEST(UncommitUnusedLargeObjectMemory) { CHECK_EQ(shrinked_size, chunk->CommittedPhysicalMemory()); } +template <RememberedSetType direction> +static size_t GetRememberedSetSize(HeapObject obj) { + size_t count = 0; + auto chunk = MemoryChunk::FromHeapObject(obj); + RememberedSet<direction>::Iterate( + chunk, + [&count](MaybeObjectSlot slot) { + count++; + return KEEP_SLOT; + }, + SlotSet::KEEP_EMPTY_BUCKETS); + return count; +} + +TEST(RememberedSet_InsertOnWriteBarrier) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in old space. + Handle<FixedArray> arr = factory->NewFixedArray(3, AllocationType::kOld); + + // Add into 'arr' references to young objects. + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + arr->set(1, *number); + arr->set(2, *number); + Handle<Object> number_other = factory->NewHeapNumber(24); + arr->set(2, *number_other); + } + // Remembered sets track *slots* pages with cross-generational pointers, so + // must have recorded three of them each exactly once. + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_InsertInLargePage) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in Large space. + const int count = Max(FixedArray::kMaxRegularLength + 1, 128 * KB); + Handle<FixedArray> arr = factory->NewFixedArray(count, AllocationType::kOld); + CHECK(heap->lo_space()->Contains(*arr)); + CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*arr)); + + // Create OLD_TO_NEW references from the large object so that the + // corresponding slots end up in different SlotSets. + { + HandleScope short_lived(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + arr->set(count - 1, *number); + } + CHECK_EQ(2, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_InsertOnPromotingObjectToOld) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Create a young object and age it one generation inside the new space. + Handle<FixedArray> arr = factory->NewFixedArray(1); + CcTest::CollectGarbage(i::NEW_SPACE); + CHECK(Heap::InYoungGeneration(*arr)); + + // Add into 'arr' a reference to an object one generation younger. + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + } + + // Promote 'arr' into old, its element is still in new, the old to new + // refs are inserted into the remembered sets during GC. + CcTest::CollectGarbage(i::NEW_SPACE); + + CHECK(heap->InOldSpace(*arr)); + CHECK_EQ(1, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_RemoveStaleOnScavenge) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in old space and add into it references to young. + Handle<FixedArray> arr = factory->NewFixedArray(3, AllocationType::kOld); + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); // will be trimmed away + arr->set(1, *number); // will be replaced with #undefined + arr->set(2, *number); // will be promoted into old + } + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr)); + + // Run scavenger once so the young object becomes ready for promotion on the + // next pass. + CcTest::CollectGarbage(i::NEW_SPACE); + arr->set(1, ReadOnlyRoots(CcTest::heap()).undefined_value()); + Handle<FixedArrayBase> tail = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*arr, 1), isolate); + + // None of the actions above should have updated the remembered set. + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*tail)); + + // Run GC to promote the remaining young object and fixup the stale entries in + // the remembered set. + CcTest::CollectGarbage(i::NEW_SPACE); + CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*tail)); +} + +// The OLD_TO_OLD remembered set is created temporary by GC and is cleared at +// the end of the pass. There is no way to observe it so the test only checks +// that compaction has happened and otherwise relies on code's self-validation. +TEST(RememberedSet_OldToOld) { + if (FLAG_stress_incremental_marking) return; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + Handle<FixedArray> arr = factory->NewFixedArray(10, AllocationType::kOld); + { + HandleScope short_lived(isolate); + factory->NewFixedArray(100, AllocationType::kOld); + } + Handle<Object> ref = factory->NewFixedArray(100, AllocationType::kOld); + arr->set(0, *ref); + + // To force compaction of the old space, fill it with garbage and start a new + // page (so that the page with 'arr' becomes subject to compaction). + { + HandleScope short_lived(isolate); + heap::SimulateFullSpace(heap->old_space()); + factory->NewFixedArray(100, AllocationType::kOld); + } + + FLAG_manual_evacuation_candidates_selection = true; + heap::ForceEvacuationCandidate(Page::FromHeapObject(*arr)); + const auto prev_location = *arr; + + // This GC pass will evacuate the page with 'arr'/'ref' so it will have to + // create OLD_TO_OLD remembered set to track the reference. + CcTest::CollectAllGarbage(); + CHECK_NE(prev_location, *arr); +} + TEST(RememberedSetRemoveRange) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -6016,59 +6209,64 @@ TEST(RememberedSetRemoveRange) { slots[chunk->area_end() - kTaggedSize] = true; for (auto x : slots) { - RememberedSet<OLD_TO_NEW>::Insert(chunk, x.first); + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(chunk, x.first); } - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + kTaggedSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start + kTaggedSize, start + Page::kPageSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start + kTaggedSize] = false; slots[start + Page::kPageSize - kTaggedSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + Page::kPageSize + kTaggedSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start + Page::kPageSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, chunk->area_end() - kTaggedSize, chunk->area_end(), SlotSet::FREE_EMPTY_BUCKETS); slots[chunk->area_end() - kTaggedSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); } HEAP_TEST(Regress670675) { @@ -6164,53 +6362,6 @@ HEAP_TEST(Regress5831) { CHECK(chunk->NeverEvacuate()); } -TEST(Regress6800) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope handle_scope(isolate); - - const int kRootLength = 1000; - Handle<FixedArray> root = - isolate->factory()->NewFixedArray(kRootLength, AllocationType::kOld); - { - HandleScope inner_scope(isolate); - Handle<FixedArray> new_space_array = isolate->factory()->NewFixedArray(1); - for (int i = 0; i < kRootLength; i++) { - root->set(i, *new_space_array); - } - for (int i = 0; i < kRootLength; i++) { - root->set(i, ReadOnlyRoots(CcTest::heap()).undefined_value()); - } - } - CcTest::CollectGarbage(NEW_SPACE); - CHECK_EQ(0, RememberedSet<OLD_TO_NEW>::NumberOfPreFreedEmptyBuckets( - MemoryChunk::FromHeapObject(*root))); -} - -TEST(Regress6800LargeObject) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope handle_scope(isolate); - - const int kRootLength = i::kMaxRegularHeapObjectSize / kTaggedSize; - Handle<FixedArray> root = - isolate->factory()->NewFixedArray(kRootLength, AllocationType::kOld); - CcTest::heap()->lo_space()->Contains(*root); - { - HandleScope inner_scope(isolate); - Handle<FixedArray> new_space_array = isolate->factory()->NewFixedArray(1); - for (int i = 0; i < kRootLength; i++) { - root->set(i, *new_space_array); - } - for (int i = 0; i < kRootLength; i++) { - root->set(i, ReadOnlyRoots(CcTest::heap()).undefined_value()); - } - } - CcTest::CollectGarbage(OLD_SPACE); - CHECK_EQ(0, RememberedSet<OLD_TO_NEW>::NumberOfPreFreedEmptyBuckets( - MemoryChunk::FromHeapObject(*root))); -} - HEAP_TEST(RegressMissingWriteBarrierInAllocate) { if (!FLAG_incremental_marking) return; ManualGCScope manual_gc_scope; @@ -6631,6 +6782,19 @@ HEAP_TEST(MemoryReducerActivationForSmallHeaps) { CHECK_EQ(heap->memory_reducer()->state_.action, MemoryReducer::Action::kWait); } +TEST(AllocateExternalBackingStore) { + ManualGCScope manual_gc_scope; + LocalContext env; + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + int initial_ms_count = heap->ms_count(); + void* result = + heap->AllocateExternalBackingStore([](size_t) { return nullptr; }, 10); + CHECK_NULL(result); + // At least two GCs should happen. + CHECK_LE(2, heap->ms_count() - initial_ms_count); +} + TEST(CodeObjectRegistry) { // We turn off compaction to ensure that code is not moving. FLAG_never_compact = true; @@ -6642,11 +6806,13 @@ TEST(CodeObjectRegistry) { HandleScope outer_scope(heap->isolate()); Address code2_address; { + // Ensure that both code objects end up on the same page. + CHECK(HeapTester::CodeEnsureLinearAllocationArea( + heap, kMaxRegularHeapObjectSize)); code1 = DummyOptimizedCode(isolate); Handle<Code> code2 = DummyOptimizedCode(isolate); code2_address = code2->address(); - // If this check breaks, change the allocation to ensure that both code - // objects are on the same page. + CHECK_EQ(MemoryChunk::FromHeapObject(*code1), MemoryChunk::FromHeapObject(*code2)); CHECK(MemoryChunk::FromHeapObject(*code1)->Contains(code1->address())); diff --git a/deps/v8/test/cctest/heap/test-invalidated-slots.cc b/deps/v8/test/cctest/heap/test-invalidated-slots.cc index af42503f86..861c48d69d 100644 --- a/deps/v8/test/cctest/heap/test-invalidated-slots.cc +++ b/deps/v8/test/cctest/heap/test-invalidated-slots.cc @@ -70,8 +70,7 @@ HEAP_TEST(InvalidatedSlotsSomeInvalidatedRanges) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register every second byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i += 2) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); for (size_t i = 0; i < byte_arrays.size(); i++) { @@ -95,8 +94,7 @@ HEAP_TEST(InvalidatedSlotsAllInvalidatedRanges) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); for (size_t i = 0; i < byte_arrays.size(); i++) { @@ -117,8 +115,7 @@ HEAP_TEST(InvalidatedSlotsAfterTrimming) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // Trim byte arrays and check that the slots outside the byte arrays are // considered invalid if the old space page was swept. @@ -145,8 +142,7 @@ HEAP_TEST(InvalidatedSlotsEvacuationCandidate) { // This should be no-op because the page is marked as evacuation // candidate. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // All slots must still be valid. InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); @@ -169,8 +165,7 @@ HEAP_TEST(InvalidatedSlotsResetObjectRegression) { heap->RightTrimFixedArray(byte_arrays[0], byte_arrays[0].length() - 8); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // All slots must still be invalid. InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); @@ -359,8 +354,7 @@ HEAP_TEST(InvalidatedSlotsCleanupFull) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i]); } // Mark full page as free @@ -379,8 +373,7 @@ HEAP_TEST(InvalidatedSlotsCleanupEachObject) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i]); } // Mark each object as free on page @@ -405,11 +398,9 @@ HEAP_TEST(InvalidatedSlotsCleanupRightTrim) { CHECK_GT(byte_arrays.size(), 1); ByteArray& invalidated = byte_arrays[1]; - int invalidated_size = invalidated.Size(); heap->RightTrimFixedArray(invalidated, invalidated.length() - 8); - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(invalidated, - invalidated_size); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(invalidated); // Free memory at end of invalidated object InvalidatedSlotsCleanup cleanup = InvalidatedSlotsCleanup::OldToNew(page); @@ -418,8 +409,6 @@ HEAP_TEST(InvalidatedSlotsCleanupRightTrim) { // After cleanup the invalidated object should be smaller InvalidatedSlots* invalidated_slots = page->invalidated_slots<OLD_TO_NEW>(); - CHECK_GE((*invalidated_slots)[HeapObject::FromAddress(invalidated.address())], - invalidated.Size()); CHECK_EQ(invalidated_slots->size(), 1); } diff --git a/deps/v8/test/cctest/heap/test-page-promotion.cc b/deps/v8/test/cctest/heap/test-page-promotion.cc index df6211826e..c31fc39c2e 100644 --- a/deps/v8/test/cctest/heap/test-page-promotion.cc +++ b/deps/v8/test/cctest/heap/test-page-promotion.cc @@ -43,8 +43,7 @@ v8::Isolate* NewIsolateForPagePromotion(int min_semi_space_size = 8, return isolate; } -Page* FindLastPageInNewSpace( - std::vector<Handle<FixedArray>>& handles) { // NOLINT(runtime/references) +Page* FindLastPageInNewSpace(const std::vector<Handle<FixedArray>>& handles) { for (auto rit = handles.rbegin(); rit != handles.rend(); ++rit) { // One deref gets the Handle, the second deref gets the FixedArray. Page* candidate = Page::FromHeapObject(**rit); @@ -146,8 +145,10 @@ UNINITIALIZED_TEST(PagePromotion_NewToNewJSArrayBuffer) { heap::FillCurrentPage(heap->new_space()); // Allocate a buffer we would like to check against. Handle<JSArrayBuffer> buffer = - i_isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - CHECK(JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, 100)); + i_isolate->factory() + ->NewJSArrayBufferAndBackingStore(100, + InitializedFlag::kZeroInitialized) + .ToHandleChecked(); std::vector<Handle<FixedArray>> handles; // Simulate a full space, filling the interesting page with live objects. heap::SimulateFullSpace(heap->new_space(), &handles); @@ -188,8 +189,10 @@ UNINITIALIZED_TEST(PagePromotion_NewToOldJSArrayBuffer) { heap::FillCurrentPage(heap->new_space()); // Allocate a buffer we would like to check against. Handle<JSArrayBuffer> buffer = - i_isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - CHECK(JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, 100)); + i_isolate->factory() + ->NewJSArrayBufferAndBackingStore(100, + InitializedFlag::kZeroInitialized) + .ToHandleChecked(); std::vector<Handle<FixedArray>> handles; // Simulate a full space, filling the interesting page with live objects. heap::SimulateFullSpace(heap->new_space(), &handles); diff --git a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc index 370c5d8131..a271df4f67 100644 --- a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc +++ b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc @@ -132,24 +132,24 @@ BytecodeExpectationsPrinter::GetBytecodeArrayOfCallee( } void BytecodeExpectationsPrinter::PrintEscapedString( - std::ostream& stream, const std::string& string) const { + std::ostream* stream, const std::string& string) const { for (char c : string) { switch (c) { case '"': - stream << "\\\""; + *stream << "\\\""; break; case '\\': - stream << "\\\\"; + *stream << "\\\\"; break; default: - stream << c; + *stream << c; break; } } } void BytecodeExpectationsPrinter::PrintBytecodeOperand( - std::ostream& stream, const BytecodeArrayIterator& bytecode_iterator, + std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, const Bytecode& bytecode, int op_index, int parameter_count) const { OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index); OperandSize op_size = Bytecodes::GetOperandSize( @@ -172,207 +172,207 @@ void BytecodeExpectationsPrinter::PrintBytecodeOperand( if (Bytecodes::IsRegisterOperandType(op_type)) { Register register_value = bytecode_iterator.GetRegisterOperand(op_index); - stream << 'R'; - if (op_size != OperandSize::kByte) stream << size_tag; + *stream << 'R'; + if (op_size != OperandSize::kByte) *stream << size_tag; if (register_value.is_current_context()) { - stream << "(context)"; + *stream << "(context)"; } else if (register_value.is_function_closure()) { - stream << "(closure)"; + *stream << "(closure)"; } else if (register_value.is_parameter()) { int parameter_index = register_value.ToParameterIndex(parameter_count); if (parameter_index == 0) { - stream << "(this)"; + *stream << "(this)"; } else { - stream << "(arg" << (parameter_index - 1) << ')'; + *stream << "(arg" << (parameter_index - 1) << ')'; } } else { - stream << '(' << register_value.index() << ')'; + *stream << '(' << register_value.index() << ')'; } } else { switch (op_type) { case OperandType::kFlag8: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetFlagOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetFlagOperand(op_index); break; case OperandType::kIdx: { - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetIndexOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetIndexOperand(op_index); break; } case OperandType::kUImm: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetUnsignedImmediateOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetUnsignedImmediateOperand(op_index); break; case OperandType::kImm: - stream << 'I' << size_tag << '('; - stream << bytecode_iterator.GetImmediateOperand(op_index); + *stream << 'I' << size_tag << '('; + *stream << bytecode_iterator.GetImmediateOperand(op_index); break; case OperandType::kRegCount: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetRegisterCountOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetRegisterCountOperand(op_index); break; case OperandType::kRuntimeId: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; Runtime::FunctionId id = bytecode_iterator.GetRuntimeIdOperand(op_index); - stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; + *stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; break; } case OperandType::kIntrinsicId: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; Runtime::FunctionId id = bytecode_iterator.GetIntrinsicIdOperand(op_index); - stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; + *stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; break; } case OperandType::kNativeContextIndex: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; uint32_t idx = bytecode_iterator.GetNativeContextIndexOperand(op_index); - stream << "%" << NameForNativeContextIntrinsicIndex(idx); + *stream << "%" << NameForNativeContextIntrinsicIndex(idx); break; } default: UNREACHABLE(); } - stream << ')'; + *stream << ')'; } } void BytecodeExpectationsPrinter::PrintBytecode( - std::ostream& stream, const BytecodeArrayIterator& bytecode_iterator, + std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, int parameter_count) const { Bytecode bytecode = bytecode_iterator.current_bytecode(); OperandScale operand_scale = bytecode_iterator.current_operand_scale(); if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); - stream << "B(" << Bytecodes::ToString(prefix) << "), "; + *stream << "B(" << Bytecodes::ToString(prefix) << "), "; } - stream << "B(" << Bytecodes::ToString(bytecode) << ')'; + *stream << "B(" << Bytecodes::ToString(bytecode) << ')'; int operands_count = Bytecodes::NumberOfOperands(bytecode); for (int op_index = 0; op_index < operands_count; ++op_index) { - stream << ", "; + *stream << ", "; PrintBytecodeOperand(stream, bytecode_iterator, bytecode, op_index, parameter_count); } } void BytecodeExpectationsPrinter::PrintSourcePosition( - std::ostream& stream, SourcePositionTableIterator& source_iterator, + std::ostream* stream, SourcePositionTableIterator* source_iterator, int bytecode_offset) const { static const size_t kPositionWidth = 4; - if (!source_iterator.done() && - source_iterator.code_offset() == bytecode_offset) { - stream << "/* " << std::setw(kPositionWidth) - << source_iterator.source_position().ScriptOffset(); - if (source_iterator.is_statement()) { - stream << " S> */ "; + if (!source_iterator->done() && + source_iterator->code_offset() == bytecode_offset) { + *stream << "/* " << std::setw(kPositionWidth) + << source_iterator->source_position().ScriptOffset(); + if (source_iterator->is_statement()) { + *stream << " S> */ "; } else { - stream << " E> */ "; + *stream << " E> */ "; } - source_iterator.Advance(); + source_iterator->Advance(); } else { - stream << " " << std::setw(kPositionWidth) << ' ' << " "; + *stream << " " << std::setw(kPositionWidth) << ' ' << " "; } } -void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream, +void BytecodeExpectationsPrinter::PrintV8String(std::ostream* stream, i::String string) const { - stream << '"'; + *stream << '"'; for (int i = 0, length = string.length(); i < length; ++i) { - stream << i::AsEscapedUC16ForJSON(string.Get(i)); + *stream << i::AsEscapedUC16ForJSON(string.Get(i)); } - stream << '"'; + *stream << '"'; } void BytecodeExpectationsPrinter::PrintConstant( - std::ostream& stream, i::Handle<i::Object> constant) const { + std::ostream* stream, i::Handle<i::Object> constant) const { if (constant->IsSmi()) { - stream << "Smi ["; - i::Smi::cast(*constant).SmiPrint(stream); - stream << "]"; + *stream << "Smi ["; + i::Smi::cast(*constant).SmiPrint(*stream); + *stream << "]"; } else { - stream << i::HeapObject::cast(*constant).map().instance_type(); + *stream << i::HeapObject::cast(*constant).map().instance_type(); if (constant->IsHeapNumber()) { - stream << " ["; - i::HeapNumber::cast(*constant).HeapNumberPrint(stream); - stream << "]"; + *stream << " ["; + i::HeapNumber::cast(*constant).HeapNumberPrint(*stream); + *stream << "]"; } else if (constant->IsString()) { - stream << " ["; + *stream << " ["; PrintV8String(stream, i::String::cast(*constant)); - stream << "]"; + *stream << "]"; } } } void BytecodeExpectationsPrinter::PrintFrameSize( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { int32_t frame_size = bytecode_array->frame_size(); DCHECK(IsAligned(frame_size, kSystemPointerSize)); - stream << "frame size: " << frame_size / kSystemPointerSize - << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; + *stream << "frame size: " << frame_size / kSystemPointerSize + << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; } void BytecodeExpectationsPrinter::PrintBytecodeSequence( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { - stream << "bytecode array length: " << bytecode_array->length() - << "\nbytecodes: [\n"; + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { + *stream << "bytecode array length: " << bytecode_array->length() + << "\nbytecodes: [\n"; SourcePositionTableIterator source_iterator( bytecode_array->SourcePositionTable()); BytecodeArrayIterator bytecode_iterator(bytecode_array); for (; !bytecode_iterator.done(); bytecode_iterator.Advance()) { - stream << kIndent; - PrintSourcePosition(stream, source_iterator, + *stream << kIndent; + PrintSourcePosition(stream, &source_iterator, bytecode_iterator.current_offset()); PrintBytecode(stream, bytecode_iterator, bytecode_array->parameter_count()); - stream << ",\n"; + *stream << ",\n"; } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintConstantPool( - std::ostream& stream, i::FixedArray constant_pool) const { - stream << "constant pool: [\n"; + std::ostream* stream, i::FixedArray constant_pool) const { + *stream << "constant pool: [\n"; int num_constants = constant_pool.length(); if (num_constants > 0) { for (int i = 0; i < num_constants; ++i) { - stream << kIndent; + *stream << kIndent; PrintConstant(stream, i::FixedArray::get(constant_pool, i, i_isolate())); - stream << ",\n"; + *stream << ",\n"; } } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintCodeSnippet( - std::ostream& stream, const std::string& body) const { - stream << "snippet: \"\n"; + std::ostream* stream, const std::string& body) const { + *stream << "snippet: \"\n"; std::stringstream body_stream(body); std::string body_line; while (std::getline(body_stream, body_line)) { - stream << kIndent; + *stream << kIndent; PrintEscapedString(stream, body_line); - stream << '\n'; + *stream << '\n'; } - stream << "\"\n"; + *stream << "\"\n"; } void BytecodeExpectationsPrinter::PrintHandlers( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { - stream << "handlers: [\n"; + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { + *stream << "handlers: [\n"; HandlerTable table(*bytecode_array); for (int i = 0, num_entries = table.NumberOfRangeEntries(); i < num_entries; ++i) { - stream << " [" << table.GetRangeStart(i) << ", " << table.GetRangeEnd(i) - << ", " << table.GetRangeHandler(i) << "],\n"; + *stream << " [" << table.GetRangeStart(i) << ", " << table.GetRangeEnd(i) + << ", " << table.GetRangeHandler(i) << "],\n"; } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintBytecodeArray( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { PrintFrameSize(stream, bytecode_array); PrintBytecodeSequence(stream, bytecode_array); PrintConstantPool(stream, bytecode_array->constant_pool()); @@ -380,7 +380,7 @@ void BytecodeExpectationsPrinter::PrintBytecodeArray( } void BytecodeExpectationsPrinter::PrintExpectation( - std::ostream& stream, const std::string& snippet) const { + std::ostream* stream, const std::string& snippet) const { std::string source_code = wrap_ ? WrapCodeInFunction(test_function_name_.c_str(), snippet) : snippet; @@ -404,10 +404,10 @@ void BytecodeExpectationsPrinter::PrintExpectation( } } - stream << "---\n"; + *stream << "---\n"; PrintCodeSnippet(stream, snippet); PrintBytecodeArray(stream, bytecode_array); - stream << '\n'; + *stream << '\n'; } } // namespace interpreter diff --git a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h index dc51e5fb7a..6a469461d5 100644 --- a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h +++ b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h @@ -36,8 +36,7 @@ class BytecodeExpectationsPrinter final { oneshot_opt_(false), test_function_name_(kDefaultTopFunctionName) {} - void PrintExpectation(std::ostream& stream, // NOLINT - const std::string& snippet) const; + void PrintExpectation(std::ostream* stream, const std::string& snippet) const; void set_module(bool module) { module_ = module; } bool module() const { return module_; } @@ -60,34 +59,30 @@ class BytecodeExpectationsPrinter final { std::string test_function_name() const { return test_function_name_; } private: - void PrintEscapedString(std::ostream& stream, // NOLINT + void PrintEscapedString(std::ostream* stream, const std::string& string) const; - void PrintBytecodeOperand(std::ostream& stream, // NOLINT + void PrintBytecodeOperand(std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, const Bytecode& bytecode, int op_index, int parameter_count) const; - void PrintBytecode(std::ostream& stream, // NOLINT + void PrintBytecode(std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, int parameter_count) const; - void PrintSourcePosition(std::ostream& stream, // NOLINT - SourcePositionTableIterator& - source_iterator, // NOLINT(runtime/references) + void PrintSourcePosition(std::ostream* stream, + SourcePositionTableIterator* source_iterator, int bytecode_offset) const; - void PrintV8String(std::ostream& stream, // NOLINT - i::String string) const; - void PrintConstant(std::ostream& stream, // NOLINT - i::Handle<i::Object> constant) const; - void PrintFrameSize(std::ostream& stream, // NOLINT + void PrintV8String(std::ostream* stream, i::String string) const; + void PrintConstant(std::ostream* stream, i::Handle<i::Object> constant) const; + void PrintFrameSize(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintBytecodeSequence(std::ostream& stream, // NOLINT + void PrintBytecodeSequence(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintConstantPool(std::ostream& stream, // NOLINT + void PrintConstantPool(std::ostream* stream, i::FixedArray constant_pool) const; - void PrintCodeSnippet(std::ostream& stream, // NOLINT - const std::string& body) const; - void PrintBytecodeArray(std::ostream& stream, // NOLINT + void PrintCodeSnippet(std::ostream* stream, const std::string& body) const; + void PrintBytecodeArray(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintHandlers(std::ostream& stream, // NOLINT + void PrintHandlers(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; v8::Local<v8::String> V8StringFromUTF8(const char* data) const; diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden index d6097e938d..7b1de53911 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden @@ -141,9 +141,9 @@ handlers: [ snippet: " var a = [ 1, 2 ]; return [ 0, ...a ]; " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 80 +bytecode array length: 68 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), @@ -152,11 +152,7 @@ bytecodes: [ B(Star), R(2), B(LdaConstant), U8(2), /* 67 S> */ B(Star), R(1), - B(GetIterator), R(0), U8(2), - B(Star), R(6), - B(CallProperty0), R(6), R(0), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(0), U8(2), U8(4), B(Star), R(4), B(LdaNamedProperty), R(4), U8(3), U8(6), B(Star), R(3), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden index 1dbb999371..0e7cac1ad9 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden @@ -214,7 +214,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 369 +bytecode array length: 357 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -238,11 +238,7 @@ bytecodes: [ B(JumpConstant), U8(15), /* 36 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), B(Star), R(10), - B(GetIterator), R(10), U8(1), - B(Star), R(11), - B(CallProperty0), R(11), R(10), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(10), U8(1), U8(3), B(Star), R(9), B(LdaNamedProperty), R(9), U8(5), U8(5), B(Star), R(8), @@ -376,7 +372,7 @@ bytecodes: [ ] constant pool: [ Smi [30], - Smi [148], + Smi [136], Smi [16], Smi [7], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, @@ -390,16 +386,16 @@ constant pool: [ Smi [6], Smi [9], SCOPE_INFO_TYPE, - Smi [274], + Smi [262], Smi [6], Smi [9], Smi [23], ] handlers: [ - [20, 315, 323], - [23, 279, 281], - [92, 179, 187], - [211, 244, 246], + [20, 303, 311], + [23, 267, 269], + [80, 167, 175], + [199, 232, 234], ] --- @@ -410,7 +406,7 @@ snippet: " " frame size: 17 parameter count: 1 -bytecode array length: 466 +bytecode array length: 467 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(5), B(Mov), R(closure), R(1), @@ -431,7 +427,7 @@ bytecodes: [ B(LdaSmi), I8(1), B(Star), R(1), B(Mov), R(5), R(2), - B(JumpConstant), U8(17), + B(JumpConstant), U8(18), /* 49 S> */ B(LdaGlobal), U8(7), U8(0), B(Star), R(9), /* 56 E> */ B(CallUndefinedReceiver0), R(9), U8(2), @@ -440,25 +436,25 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(11), B(CallProperty0), R(11), R(10), U8(6), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(10), U8(8), + B(LdaNamedProperty), R(10), U8(9), U8(8), B(Star), R(11), B(CallProperty0), R(11), R(10), U8(10), B(Star), R(11), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(11), U8(1), B(Star), R(7), - B(LdaNamedProperty), R(7), U8(9), U8(12), + B(LdaNamedProperty), R(7), U8(10), U8(12), B(Star), R(9), B(LdaUndefined), B(Star), R(8), B(LdaZero), B(Star), R(6), B(Ldar), R(6), - B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(1), + B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(1), B(CallProperty1), R(9), R(7), R(8), U8(14), B(Jump), U8(140), - B(LdaNamedProperty), R(7), U8(12), U8(16), + B(LdaNamedProperty), R(7), U8(13), U8(16), B(JumpIfUndefinedOrNull), U8(11), B(Star), R(10), B(CallProperty1), R(10), R(7), R(8), U8(18), @@ -480,12 +476,12 @@ bytecodes: [ B(Star), R(1), B(Mov), R(10), R(2), B(Jump), U8(241), - B(LdaNamedProperty), R(7), U8(13), U8(20), + B(LdaNamedProperty), R(7), U8(14), U8(20), B(JumpIfUndefinedOrNull), U8(11), B(Star), R(12), B(CallProperty1), R(12), R(7), R(8), U8(22), B(Jump), U8(66), - B(LdaNamedProperty), R(7), U8(12), U8(24), + B(LdaNamedProperty), R(7), U8(13), U8(24), B(JumpIfUndefinedOrNull), U8(55), B(Star), R(12), B(CallProperty0), R(12), R(7), U8(26), @@ -525,9 +521,9 @@ bytecodes: [ B(Mov), R(12), R(5), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), - B(LdaNamedProperty), R(5), U8(14), U8(28), + B(LdaNamedProperty), R(5), U8(15), U8(28), B(JumpIfToBooleanTrue), U8(38), - B(LdaNamedProperty), R(5), U8(15), U8(30), + B(LdaNamedProperty), R(5), U8(16), U8(30), B(Star), R(15), B(LdaFalse), B(Star), R(16), @@ -539,7 +535,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), B(Star), R(6), B(JumpLoop), U8(236), I8(0), - B(LdaNamedProperty), R(5), U8(15), U8(32), + B(LdaNamedProperty), R(5), U8(16), U8(32), B(Star), R(7), B(LdaSmi), I8(1), B(TestReferenceEqual), R(6), @@ -551,7 +547,7 @@ bytecodes: [ B(Ldar), R(7), B(Jump), U8(36), B(Star), R(5), - B(CreateCatchContext), R(5), U8(16), + B(CreateCatchContext), R(5), U8(17), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -580,7 +576,7 @@ bytecodes: [ B(Ldar), R(3), B(SetPendingMessage), B(Ldar), R(1), - B(SwitchOnSmiNoFeedback), U8(18), U8(3), I8(0), + B(SwitchOnSmiNoFeedback), U8(19), U8(3), I8(0), B(Jump), U8(22), B(Ldar), R(2), B(ReThrow), @@ -597,14 +593,15 @@ bytecodes: [ ] constant pool: [ Smi [30], - Smi [157], - Smi [229], - Smi [279], - Smi [338], + Smi [158], + Smi [230], + Smi [280], + Smi [339], Smi [16], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], Smi [11], Smi [70], @@ -613,13 +610,13 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], SCOPE_INFO_TYPE, - Smi [371], + Smi [372], Smi [6], Smi [9], Smi [23], ] handlers: [ - [20, 412, 420], - [23, 374, 378], + [20, 413, 421], + [23, 375, 379], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden new file mode 100644 index 0000000000..7cbe661b94 --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden @@ -0,0 +1,349 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: no +module: yes +top level: yes +top level await: yes + +--- +snippet: " + await 42; +" +frame size: 8 +parameter count: 2 +bytecode array length: 142 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(3), + B(Mov), R(arg0), R(2), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(2), + B(PushContext), R(2), + B(Mov), R(closure), R(3), + B(Mov), R(this), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(3), U8(2), + B(Star), R(0), + /* 0 E> */ B(StackCheck), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(3), U8(0), + B(ResumeGenerator), R(0), R(0), U8(3), + B(Star), R(3), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(3), + /* 0 E> */ B(Throw), + B(Ldar), R(3), + /* 10 S> */ B(Return), + B(Mov), R(3), R(1), + B(Ldar), R(1), + B(Mov), R(context), R(3), + /* 0 S> */ B(LdaSmi), I8(42), + B(Star), R(5), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(4), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(1), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(5), + B(LdaZero), + B(TestReferenceEqual), R(5), + B(JumpIfTrue), U8(5), + B(Ldar), R(4), + B(ReThrow), + B(LdaUndefined), + B(Star), R(5), + B(LdaTrue), + B(Star), R(6), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3), + /* 10 S> */ B(Return), + B(Star), R(4), + B(CreateCatchContext), R(4), U8(5), + B(Star), R(3), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(3), + B(PushContext), R(4), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3), + /* 10 S> */ B(Return), +] +constant pool: [ + Smi [36], + Smi [80], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + SCOPE_INFO_TYPE, +] +handlers: [ + [64, 114, 114], +] + +--- +snippet: " + await import(\"foo\"); +" +frame size: 8 +parameter count: 2 +bytecode array length: 152 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(3), + B(Mov), R(arg0), R(2), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(2), + B(PushContext), R(2), + B(Mov), R(closure), R(3), + B(Mov), R(this), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(3), U8(2), + B(Star), R(0), + /* 0 E> */ B(StackCheck), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(3), U8(0), + B(ResumeGenerator), R(0), R(0), U8(3), + B(Star), R(3), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(3), + /* 0 E> */ B(Throw), + B(Ldar), R(3), + /* 21 S> */ B(Return), + B(Mov), R(3), R(1), + B(Ldar), R(1), + B(Mov), R(context), R(3), + /* 0 S> */ B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(closure), R(4), + B(CallRuntime), U16(Runtime::kDynamicImportCall), R(4), U8(2), + B(Star), R(5), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(4), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(1), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(5), + B(LdaZero), + B(TestReferenceEqual), R(5), + B(JumpIfTrue), U8(5), + B(Ldar), R(4), + B(ReThrow), + B(LdaUndefined), + B(Star), R(5), + B(LdaTrue), + B(Star), R(6), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3), + /* 21 S> */ B(Return), + B(Star), R(4), + B(CreateCatchContext), R(4), U8(6), + B(Star), R(3), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(3), + B(PushContext), R(4), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3), + /* 21 S> */ B(Return), +] +constant pool: [ + Smi [36], + Smi [90], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + ONE_BYTE_INTERNALIZED_STRING_TYPE ["foo"], + SCOPE_INFO_TYPE, +] +handlers: [ + [64, 124, 124], +] + +--- +snippet: " + await 42; + async function foo() { + await 42; + } + foo(); +" +frame size: 9 +parameter count: 2 +bytecode array length: 153 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(Mov), R(arg0), R(3), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(2), + B(PushContext), R(3), + B(Mov), R(closure), R(4), + B(Mov), R(this), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(4), U8(2), + B(Star), R(0), + B(CreateClosure), U8(3), U8(0), U8(0), + B(Star), R(1), + /* 0 E> */ B(StackCheck), + B(Ldar), R(0), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(0), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(4), U8(2), I8(0), + B(Ldar), R(4), + /* 0 E> */ B(Throw), + B(Ldar), R(4), + /* 54 S> */ B(Return), + B(Mov), R(4), R(2), + B(Ldar), R(2), + B(Mov), R(context), R(4), + /* 0 S> */ B(LdaSmi), I8(42), + B(Star), R(6), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(5), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(5), U8(1), + B(ResumeGenerator), R(0), R(0), U8(5), + B(Star), R(5), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(6), + B(LdaZero), + B(TestReferenceEqual), R(6), + B(JumpIfTrue), U8(5), + B(Ldar), R(5), + B(ReThrow), + /* 47 S> */ B(CallUndefinedReceiver0), R(1), U8(0), + B(LdaUndefined), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), + /* 54 S> */ B(Return), + B(Star), R(5), + B(CreateCatchContext), R(5), U8(6), + B(Star), R(4), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(4), + B(PushContext), R(5), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(7), + B(LdaTrue), + B(Star), R(8), + B(Mov), R(0), R(6), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3), + /* 54 S> */ B(Return), +] +constant pool: [ + Smi [44], + Smi [88], + SCOPE_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + Smi [10], + Smi [7], + SCOPE_INFO_TYPE, +] +handlers: [ + [72, 125, 125], +] + +--- +snippet: " + import * as foo from \"bar\"; + await import(\"goo\"); +" +frame size: 9 +parameter count: 2 +bytecode array length: 164 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(Mov), R(arg0), R(3), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(2), + B(PushContext), R(3), + B(Mov), R(closure), R(4), + B(Mov), R(this), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(4), U8(2), + B(Star), R(0), + B(LdaZero), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kGetModuleNamespace), R(4), U8(1), + B(Star), R(1), + /* 0 E> */ B(StackCheck), + B(Ldar), R(0), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(0), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(4), + /* 0 E> */ B(Throw), + B(Ldar), R(4), + /* 49 S> */ B(Return), + B(Mov), R(4), R(2), + B(Ldar), R(2), + B(Mov), R(context), R(4), + /* 28 S> */ B(LdaConstant), U8(5), + B(Star), R(6), + B(Mov), R(closure), R(5), + B(CallRuntime), U16(Runtime::kDynamicImportCall), R(5), U8(2), + B(Star), R(6), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(5), U8(2), + /* 28 E> */ B(SuspendGenerator), R(0), R(0), U8(5), U8(1), + B(ResumeGenerator), R(0), R(0), U8(5), + B(Star), R(5), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(6), + B(LdaZero), + B(TestReferenceEqual), R(6), + B(JumpIfTrue), U8(5), + B(Ldar), R(5), + B(ReThrow), + B(LdaUndefined), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), + /* 49 S> */ B(Return), + B(Star), R(5), + B(CreateCatchContext), R(5), U8(6), + B(Star), R(4), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(4), + B(PushContext), R(5), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(7), + B(LdaTrue), + B(Star), R(8), + B(Mov), R(0), R(6), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3), + /* 49 S> */ B(Return), +] +constant pool: [ + Smi [48], + Smi [102], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + ONE_BYTE_INTERNALIZED_STRING_TYPE ["goo"], + SCOPE_INFO_TYPE, +] +handlers: [ + [76, 136, 136], +] + diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden index 963cbee018..b86d4e61b1 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden @@ -65,9 +65,9 @@ handlers: [ snippet: " Math.max(0, ...[1, 2, 3], 4); " -frame size: 9 +frame size: 8 parameter count: 1 -bytecode array length: 106 +bytecode array length: 94 bytecodes: [ /* 30 E> */ B(StackCheck), /* 34 S> */ B(LdaGlobal), U8(0), U8(0), @@ -80,14 +80,10 @@ bytecodes: [ B(Star), R(3), /* 49 S> */ B(CreateArrayLiteral), U8(4), U8(5), U8(37), B(Star), R(7), - B(GetIterator), R(7), U8(6), - B(Star), R(8), - B(CallProperty0), R(8), R(7), U8(8), - B(Mov), R(0), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(7), U8(6), U8(8), B(Star), R(6), B(LdaNamedProperty), R(6), U8(5), U8(10), + B(Mov), R(0), R(2), B(Star), R(5), B(CallProperty0), R(5), R(6), U8(19), B(Star), R(7), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden index be635a2ed0..cd439d5d14 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden @@ -12,27 +12,26 @@ snippet: " speak() { console.log(this.name + ' is speaking.'); } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 44 +bytecode array length: 41 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 149 S> */ B(Return), ] @@ -52,27 +51,26 @@ snippet: " speak() { console.log(this.name + ' is speaking.'); } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 44 +bytecode array length: 41 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 149 S> */ B(Return), ] @@ -94,43 +92,42 @@ snippet: " static [n1]() { return n1; } } " -frame size: 12 +frame size: 11 parameter count: 1 -bytecode array length: 87 +bytecode array length: 84 bytecodes: [ B(CreateFunctionContext), U8(0), U8(2), - B(PushContext), R(2), + B(PushContext), R(1), /* 30 E> */ B(StackCheck), /* 43 S> */ B(LdaConstant), U8(1), /* 43 E> */ B(StaCurrentContextSlot), U8(4), /* 57 S> */ B(LdaConstant), U8(2), /* 57 E> */ B(StaCurrentContextSlot), U8(5), B(CreateBlockContext), U8(3), - B(PushContext), R(3), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(7), + B(Star), R(6), B(CreateClosure), U8(5), U8(0), U8(2), - B(Star), R(4), + B(Star), R(3), B(LdaConstant), U8(4), - B(Star), R(5), - /* 75 S> */ B(LdaImmutableContextSlot), R(3), U8(4), U8(0), - B(ToName), R(8), + B(Star), R(4), + /* 75 S> */ B(LdaImmutableContextSlot), R(2), U8(4), U8(0), + B(ToName), R(7), B(CreateClosure), U8(6), U8(1), U8(2), - B(Star), R(9), - /* 106 S> */ B(LdaImmutableContextSlot), R(3), U8(5), U8(0), - B(ToName), R(10), + B(Star), R(8), + /* 106 S> */ B(LdaImmutableContextSlot), R(2), U8(5), U8(0), + B(ToName), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(4), R(6), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(7), - B(Star), R(5), - B(Mov), R(4), R(1), - B(PopContext), R(3), - B(Mov), R(1), R(0), + B(Star), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(7), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(3), R(0), B(LdaUndefined), /* 129 S> */ B(Return), ] @@ -154,29 +151,28 @@ snippet: " class C { constructor() { count++; }} return new C(); " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 52 +bytecode array length: 49 bytecodes: [ B(CreateFunctionContext), U8(0), U8(1), - B(PushContext), R(2), + B(PushContext), R(1), /* 30 E> */ B(StackCheck), /* 46 S> */ B(LdaZero), /* 46 E> */ B(StaCurrentContextSlot), U8(4), B(CreateBlockContext), U8(1), - B(PushContext), R(3), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(7), + B(Star), R(6), B(CreateClosure), U8(3), U8(0), U8(2), - B(Star), R(4), + B(Star), R(3), B(LdaConstant), U8(2), - B(Star), R(5), - B(Mov), R(4), R(6), - B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), - B(Star), R(5), - B(Mov), R(6), R(1), - B(PopContext), R(3), - B(Mov), R(1), R(0), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), /* 87 S> */ B(Ldar), R(0), /* 94 E> */ B(Construct), R(0), R(0), U8(0), U8(0), /* 102 S> */ B(Return), @@ -195,39 +191,38 @@ snippet: " (class {}) class E { static name () {}} " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 73 +bytecode array length: 70 bytecodes: [ /* 30 E> */ B(StackCheck), /* 34 S> */ B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(PopContext), R(2), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), B(CreateBlockContext), U8(3), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(5), U8(1), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(4), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 74 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden index e26b79a9fb..b4c9a75ef1 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden @@ -12,21 +12,17 @@ snippet: " " frame size: 14 parameter count: 1 -bytecode array length: 172 +bytecode array length: 160 bytecodes: [ /* 30 E> */ B(StackCheck), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(1), - /* 60 S> */ B(GetIterator), R(1), U8(1), - B(Star), R(6), - B(CallProperty0), R(6), R(1), U8(3), - B(Mov), R(1), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 60 S> */ B(GetIterator), R(1), U8(1), U8(3), B(Star), R(4), B(LdaNamedProperty), R(4), U8(1), U8(5), B(Star), R(3), B(LdaFalse), + B(Mov), R(1), R(2), B(Star), R(5), B(Mov), R(context), R(8), /* 57 S> */ B(Ldar), R(5), @@ -101,8 +97,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [40, 82, 90], - [114, 147, 149], + [28, 70, 78], + [102, 135, 137], ] --- @@ -112,21 +108,17 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(2), - /* 69 S> */ B(GetIterator), R(2), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(2), U8(3), - B(Mov), R(2), R(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 69 S> */ B(GetIterator), R(2), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(1), U8(5), B(Star), R(4), B(LdaFalse), + B(Mov), R(2), R(3), B(Star), R(6), B(Mov), R(context), R(9), B(Ldar), R(6), @@ -235,8 +227,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [40, 168, 176], - [200, 233, 235], + [28, 156, 164], + [188, 221, 223], ] --- @@ -246,23 +238,19 @@ snippet: " " frame size: 16 parameter count: 1 -bytecode array length: 223 +bytecode array length: 211 bytecodes: [ /* 30 E> */ B(StackCheck), /* 40 S> */ B(CreateEmptyObjectLiteral), B(Star), R(0), /* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(2), - /* 68 S> */ B(GetIterator), R(2), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(2), U8(3), - B(Mov), R(2), R(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 68 S> */ B(GetIterator), R(2), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(1), U8(5), B(Star), R(4), B(LdaFalse), + B(Mov), R(2), R(3), B(Star), R(6), B(Mov), R(context), R(9), /* 59 S> */ B(Ldar), R(6), @@ -357,8 +345,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [43, 133, 141], - [165, 198, 200], + [31, 121, 129], + [153, 186, 188], ] --- diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden index f60e591040..43b6c0ed22 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden @@ -16,7 +16,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 320 +bytecode array length: 321 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -31,15 +31,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -64,9 +64,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(23), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -87,7 +87,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(17), + B(LdaNamedProperty), R(6), U8(8), U8(17), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -95,7 +95,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -139,7 +139,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 57 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(9), + B(CreateCatchContext), R(5), U8(10), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -154,10 +154,11 @@ bytecodes: [ /* 57 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [224], + Smi [96], + Smi [225], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -166,9 +167,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 292, 292], - [74, 154, 162], - [186, 255, 257], + [20, 293, 293], + [75, 155, 163], + [187, 256, 258], ] --- @@ -180,7 +181,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 341 +bytecode array length: 342 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -195,15 +196,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -228,9 +229,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(27), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -253,7 +254,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(17), + B(LdaNamedProperty), R(6), U8(8), U8(17), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -261,7 +262,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -293,7 +294,7 @@ bytecodes: [ B(Ldar), R(10), B(SetPendingMessage), B(Ldar), R(8), - B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0), + B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0), B(Jump), U8(19), B(Ldar), R(9), B(ReThrow), @@ -311,7 +312,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 68 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(11), + B(CreateCatchContext), R(5), U8(12), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -326,10 +327,11 @@ bytecodes: [ /* 68 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [228], + Smi [96], + Smi [229], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -340,9 +342,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 313, 313], - [74, 158, 166], - [190, 259, 261], + [20, 314, 314], + [75, 159, 167], + [191, 260, 262], ] --- @@ -357,7 +359,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 336 +bytecode array length: 337 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -372,15 +374,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -405,9 +407,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(39), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -435,7 +437,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(19), + B(LdaNamedProperty), R(6), U8(8), U8(19), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -443,7 +445,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -487,7 +489,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 114 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(9), + B(CreateCatchContext), R(5), U8(10), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -502,10 +504,11 @@ bytecodes: [ /* 114 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [240], + Smi [96], + Smi [241], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -514,9 +517,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 308, 308], - [74, 170, 178], - [202, 271, 273], + [20, 309, 309], + [75, 171, 179], + [203, 272, 274], ] --- @@ -529,7 +532,7 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(Mov), R(closure), R(2), B(Mov), R(this), R(3), @@ -541,11 +544,7 @@ bytecodes: [ B(Star), R(1), /* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), B(Star), R(5), - B(GetIterator), R(5), U8(2), - B(Star), R(6), - B(CallProperty0), R(6), R(5), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(5), U8(2), U8(4), B(Star), R(4), B(LdaNamedProperty), R(4), U8(2), U8(6), B(Star), R(3), @@ -657,8 +656,8 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [16, 230, 230], - [58, 111, 119], - [143, 176, 178], + [16, 218, 218], + [46, 99, 107], + [131, 164, 166], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden index 1557e8d2a8..6c599df00c 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden @@ -11,16 +11,12 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 170 +bytecode array length: 158 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(4), - B(GetIterator), R(4), U8(1), - B(Star), R(5), - B(CallProperty0), R(5), R(4), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(4), U8(1), U8(3), B(Star), R(3), B(LdaNamedProperty), R(3), U8(1), U8(5), B(Star), R(2), @@ -98,8 +94,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [37, 80, 88], - [112, 145, 147], + [25, 68, 76], + [100, 133, 135], ] --- @@ -109,16 +105,12 @@ snippet: " " frame size: 14 parameter count: 1 -bytecode array length: 178 +bytecode array length: 166 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(LdaConstant), U8(0), B(Star), R(0), - /* 68 S> */ B(GetIterator), R(0), U8(0), - B(Star), R(6), - B(CallProperty0), R(6), R(0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 68 S> */ B(GetIterator), R(0), U8(0), U8(2), B(Star), R(4), B(LdaNamedProperty), R(4), U8(1), U8(4), B(Star), R(3), @@ -202,8 +194,8 @@ constant pool: [ Smi [9], ] handlers: [ - [35, 82, 90], - [114, 147, 149], + [23, 70, 78], + [102, 135, 137], ] --- @@ -215,16 +207,12 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 186 +bytecode array length: 174 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(4), - B(GetIterator), R(4), U8(1), - B(Star), R(5), - B(CallProperty0), R(5), R(4), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(4), U8(1), U8(3), B(Star), R(3), B(LdaNamedProperty), R(3), U8(1), U8(5), B(Star), R(2), @@ -309,8 +297,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [37, 96, 104], - [128, 161, 163], + [25, 84, 92], + [116, 149, 151], ] --- @@ -320,18 +308,14 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 192 +bytecode array length: 180 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), B(Star), R(0), /* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), B(Star), R(3), - B(GetIterator), R(3), U8(2), - B(Star), R(4), - B(CallProperty0), R(4), R(3), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(3), U8(2), U8(4), B(Star), R(2), B(LdaNamedProperty), R(2), U8(2), U8(6), B(Star), R(1), @@ -419,7 +403,7 @@ constant pool: [ Smi [9], ] handlers: [ - [43, 96, 104], - [128, 161, 163], + [31, 84, 92], + [116, 149, 151], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden index f50891172e..c643232d4b 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden @@ -15,14 +15,10 @@ snippet: " " frame size: 15 parameter count: 2 -bytecode array length: 167 +bytecode array length: 155 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 34 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(0), U8(4), B(Star), R(4), @@ -100,8 +96,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 77, 85], - [109, 142, 144], + [19, 65, 73], + [97, 130, 132], ] --- @@ -113,7 +109,7 @@ snippet: " " frame size: 20 parameter count: 2 -bytecode array length: 251 +bytecode array length: 239 bytecodes: [ B(CreateFunctionContext), U8(0), U8(4), B(PushContext), R(2), @@ -132,11 +128,7 @@ bytecodes: [ B(StaCurrentContextSlot), U8(4), /* 34 S> */ B(LdaContextSlot), R(3), U8(4), U8(0), B(Star), R(6), - B(GetIterator), R(6), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(2), U8(4), B(Star), R(4), @@ -241,8 +233,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [64, 159, 167], - [191, 224, 226], + [52, 147, 155], + [179, 212, 214], ] --- @@ -254,14 +246,10 @@ snippet: " " frame size: 14 parameter count: 2 -bytecode array length: 184 +bytecode array length: 172 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 34 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(5), - B(CallProperty0), R(5), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(3), B(LdaNamedProperty), R(3), U8(0), U8(4), B(Star), R(2), @@ -349,8 +337,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 94, 102], - [126, 159, 161], + [19, 82, 90], + [114, 147, 149], ] --- @@ -362,14 +350,10 @@ snippet: " " frame size: 17 parameter count: 2 -bytecode array length: 178 +bytecode array length: 166 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 41 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(9), - B(CallProperty0), R(9), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 41 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(7), B(LdaNamedProperty), R(7), U8(0), U8(4), B(Star), R(6), @@ -453,8 +437,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 88, 96], - [120, 153, 155], + [19, 76, 84], + [108, 141, 143], ] --- @@ -466,7 +450,7 @@ snippet: " " frame size: 16 parameter count: 2 -bytecode array length: 208 +bytecode array length: 196 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(Mov), R(closure), R(5), @@ -483,11 +467,7 @@ bytecodes: [ /* 11 E> */ B(Throw), B(Ldar), R(5), /* 55 S> */ B(Return), - /* 35 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(8), - B(CallProperty0), R(8), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(6), B(LdaNamedProperty), R(6), U8(3), U8(4), B(Star), R(5), @@ -568,8 +548,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [72, 118, 126], - [150, 183, 185], + [60, 106, 114], + [138, 171, 173], ] --- @@ -581,7 +561,7 @@ snippet: " " frame size: 15 parameter count: 2 -bytecode array length: 252 +bytecode array length: 240 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -598,11 +578,7 @@ bytecodes: [ /* 11 E> */ B(Throw), B(Ldar), R(4), /* 49 S> */ B(Return), - /* 35 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(4), U8(4), B(Star), R(4), @@ -690,7 +666,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [125], + Smi [113], Smi [10], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], @@ -704,8 +680,8 @@ constant pool: [ Smi [9], ] handlers: [ - [72, 156, 164], - [188, 221, 223], + [60, 144, 152], + [176, 209, 211], ] --- @@ -717,7 +693,7 @@ snippet: " " frame size: 17 parameter count: 2 -bytecode array length: 222 +bytecode array length: 210 bytecodes: [ B(Mov), R(closure), R(5), B(Mov), R(this), R(6), @@ -725,11 +701,7 @@ bytecodes: [ B(Star), R(0), /* 16 E> */ B(StackCheck), B(Mov), R(context), R(5), - /* 40 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(9), - B(CallProperty0), R(9), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(7), B(LdaNamedProperty), R(7), U8(0), U8(4), B(Star), R(6), @@ -827,9 +799,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [16, 194, 194], - [46, 92, 100], - [124, 157, 159], + [16, 182, 182], + [34, 80, 88], + [112, 145, 147], ] --- @@ -841,7 +813,7 @@ snippet: " " frame size: 16 parameter count: 2 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(Mov), R(closure), R(4), @@ -850,11 +822,7 @@ bytecodes: [ B(Star), R(0), /* 16 E> */ B(StackCheck), B(Mov), R(context), R(4), - /* 40 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(8), - B(CallProperty0), R(8), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(6), B(LdaNamedProperty), R(6), U8(1), U8(4), B(Star), R(5), @@ -956,7 +924,7 @@ bytecodes: [ /* 54 S> */ B(Return), ] constant pool: [ - Smi [103], + Smi [91], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -965,8 +933,8 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 230, 230], - [50, 128, 136], - [160, 193, 195], + [20, 218, 218], + [38, 116, 124], + [148, 181, 183], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden index 157b58d81d..ca3ef0bef3 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden @@ -100,7 +100,7 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -119,11 +119,7 @@ bytecodes: [ /* 44 S> */ B(Return), /* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), B(Star), R(6), - B(GetIterator), R(6), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(5), U8(5), B(Star), R(4), @@ -211,7 +207,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [131], + Smi [119], Smi [10], Smi [7], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, @@ -226,8 +222,8 @@ constant pool: [ Smi [9], ] handlers: [ - [78, 162, 170], - [194, 227, 229], + [66, 150, 158], + [182, 215, 217], ] --- @@ -236,9 +232,9 @@ snippet: " function* f() { yield* g() } f(); " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 210 +bytecode array length: 198 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(1), @@ -259,11 +255,7 @@ bytecodes: [ B(Star), R(5), /* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2), B(Star), R(6), - B(GetIterator), R(6), U8(4), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(6), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(4), U8(6), B(Star), R(3), B(LdaNamedProperty), R(3), U8(5), U8(8), B(Star), R(5), @@ -320,7 +312,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [178], + Smi [166], Smi [10], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden index dce8d7ac8c..c29b74c0e2 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden @@ -10,29 +10,28 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(...[1, 2, 3]); " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 51 +bytecode array length: 48 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), - /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), + /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), + B(Star), R(2), B(Ldar), R(0), - /* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(1), U8(1), + /* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(1), U8(1), B(LdaUndefined), /* 110 S> */ B(Return), ] @@ -50,31 +49,30 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(0, ...[1, 2, 3]); " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 54 +bytecode array length: 51 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), - /* 89 S> */ B(LdaZero), B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), + /* 89 S> */ B(LdaZero), + B(Star), R(2), B(CreateArrayLiteral), U8(3), U8(0), U8(37), - B(Star), R(4), + B(Star), R(3), B(Ldar), R(0), - /* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(2), U8(1), + /* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(2), U8(1), B(LdaUndefined), /* 113 S> */ B(Return), ] @@ -92,56 +90,51 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(0, ...[1, 2, 3], 4); " -frame size: 9 +frame size: 7 parameter count: 1 -bytecode array length: 130 +bytecode array length: 115 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), - B(Star), R(4), - B(LdaConstant), U8(4), B(Star), R(3), + B(LdaConstant), U8(4), + B(Star), R(2), /* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37), - B(Star), R(7), - B(GetIterator), R(7), U8(2), - B(Star), R(8), - B(CallProperty0), R(8), R(7), U8(4), - B(Mov), R(5), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(6), U8(6), + B(GetIterator), R(6), U8(2), U8(4), B(Star), R(5), - B(CallProperty0), R(5), R(6), U8(15), - B(Star), R(7), + B(LdaNamedProperty), R(5), U8(6), U8(6), + B(Star), R(4), + B(Mov), R(0), R(1), + B(CallProperty0), R(4), R(5), U8(15), + B(Star), R(6), B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1), - B(LdaNamedProperty), R(7), U8(7), U8(17), + B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), + B(LdaNamedProperty), R(6), U8(7), U8(17), B(JumpIfToBooleanTrue), U8(19), - B(LdaNamedProperty), R(7), U8(8), U8(8), - B(StaInArrayLiteral), R(4), R(3), U8(13), - B(Ldar), R(3), + B(LdaNamedProperty), R(6), U8(8), U8(8), + B(StaInArrayLiteral), R(3), R(2), U8(13), + B(Ldar), R(2), B(Inc), U8(12), - B(Star), R(3), + B(Star), R(2), B(JumpLoop), U8(33), I8(0), B(LdaSmi), I8(4), - B(StaInArrayLiteral), R(4), R(3), U8(13), - B(Mov), R(4), R(3), - B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2), + B(StaInArrayLiteral), R(3), R(2), U8(13), + B(Mov), R(3), R(2), + B(CallJSRuntime), U8(%reflect_construct), R(1), U8(2), B(LdaUndefined), /* 116 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden index aceee552b5..2c0af93787 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden @@ -15,45 +15,44 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 68 +bytecode array length: 65 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(5), U8(2), U8(2), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 101 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -66,44 +65,43 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 65 +bytecode array length: 62 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(6), + B(Star), R(5), B(LdaNull), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 81 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["B"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -116,44 +114,43 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 65 +bytecode array length: 62 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(LdaNull), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 74 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -172,74 +169,72 @@ snippet: " } } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 133 +bytecode array length: 127 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), - B(LdaConstant), U8(1), - B(Star), R(6), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(3), - B(LdaConstant), U8(3), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), + B(LdaConstant), U8(1), + B(Star), R(5), + B(Mov), R(3), R(6), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(5), U8(2), U8(2), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), - /* 118 E> */ B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(5), - B(LdaConstant), U8(7), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(9), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(PushContext), R(2), + B(LdaConstant), U8(8), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 118 E> */ B(CreateClosure), U8(9), U8(3), U8(2), + B(Star), R(3), + B(LdaConstant), U8(7), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(10), U8(4), U8(2), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(11), U8(5), U8(2), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), B(LdaUndefined), /* 175 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -254,52 +249,50 @@ snippet: " new C(); } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 119 +bytecode array length: 113 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), - /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), - B(LdaConstant), U8(5), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(7), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), + /* 38 E> */ B(CreateBlockContext), U8(4), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 77 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), + B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(8), - B(Ldar), R(6), - B(StaNamedProperty), R(8), U8(9), U8(0), + B(Star), R(6), + B(Ldar), R(5), + B(StaNamedProperty), R(6), U8(9), U8(0), B(LdaNull), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 122 S> */ B(Ldar), R(1), /* 122 E> */ B(Construct), R(1), R(0), U8(0), U8(2), B(LdaUndefined), @@ -312,9 +305,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, ] handlers: [ @@ -330,52 +323,50 @@ snippet: " new C(); } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 119 +bytecode array length: 113 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), - /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 80 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), - B(LdaConstant), U8(5), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(7), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), + /* 38 E> */ B(CreateBlockContext), U8(4), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 80 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), + B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(LdaNull), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(9), - B(Ldar), R(6), - B(StaNamedProperty), R(9), U8(9), U8(0), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(Ldar), R(5), + B(StaNamedProperty), R(7), U8(9), U8(0), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 126 S> */ B(Ldar), R(1), /* 126 E> */ B(Construct), R(1), R(0), U8(0), U8(2), B(LdaUndefined), @@ -388,9 +379,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, ] handlers: [ diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden index dbe688f814..62603a93f8 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden @@ -22,70 +22,68 @@ snippet: " new B; } " -frame size: 10 +frame size: 7 parameter count: 1 -bytecode array length: 137 +bytecode array length: 131 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), - B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), - B(LdaConstant), U8(1), - B(Star), R(6), - B(LdaConstant), U8(3), - B(Star), R(9), - B(LdaConstant), U8(3), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), + B(LdaTheHole), B(Star), R(6), - B(Mov), R(7), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), + B(LdaConstant), U8(1), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(0), - B(PopContext), R(4), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(0), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(7), - B(Star), R(6), - B(LdaConstant), U8(3), - B(Star), R(9), - B(LdaConstant), U8(3), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), B(CreateClosure), U8(9), U8(3), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(2), - B(PopContext), R(4), - B(Mov), R(2), R(1), - /* 136 S> */ B(Ldar), R(3), - /* 136 E> */ B(Construct), R(3), R(0), U8(0), U8(4), - /* 145 S> */ B(Ldar), R(2), - /* 145 E> */ B(Construct), R(2), R(0), U8(0), U8(6), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(2), + B(PopContext), R(2), + B(Mov), R(3), R(1), + /* 136 S> */ B(Ldar), R(0), + /* 136 E> */ B(Construct), R(0), R(0), U8(0), U8(4), + /* 145 S> */ B(Ldar), R(1), + /* 145 E> */ B(Construct), R(1), R(0), U8(0), U8(6), B(LdaUndefined), /* 154 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, @@ -130,129 +128,126 @@ snippet: " new C; }; " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 277 +bytecode array length: 268 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), - B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), - B(Star), R(11), + B(PushContext), R(3), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), - B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(LdaConstant), U8(1), - B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), B(StaCurrentContextSlot), U8(4), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3), + B(LdaTheHole), + B(Star), R(11), + B(CreateClosure), U8(4), U8(0), U8(2), B(Star), R(8), - B(Mov), R(9), R(5), - B(CreateClosure), U8(6), U8(2), U8(2), + B(LdaConstant), U8(3), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(0), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(CreateClosure), U8(5), U8(1), U8(2), + B(Star), R(4), + B(LdaConstant), U8(1), + B(Star), R(5), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(6), U8(2), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(0), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(8), - B(PushContext), R(6), + B(PushContext), R(3), + B(LdaConstant), U8(2), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(4), + B(LdaConstant), U8(10), + B(Star), R(5), + B(LdaConstant), U8(10), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(11), U8(3), U8(2), B(Star), R(11), - B(LdaConstant), U8(10), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), - B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), - B(LdaConstant), U8(9), + B(CreateClosure), U8(12), U8(3), U8(2), B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(4), - B(LdaConstant), U8(13), - B(Star), R(11), - B(LdaConstant), U8(13), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(5), + B(LdaConstant), U8(11), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), + B(CreateClosure), U8(13), U8(4), U8(2), + B(Star), R(4), + B(LdaConstant), U8(9), + B(Star), R(5), B(CreateClosure), U8(14), U8(5), U8(2), - B(Star), R(11), - B(CreateClosure), U8(15), U8(6), U8(2), - B(Star), R(12), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), B(Star), R(8), - B(Mov), R(9), R(4), - B(CreateClosure), U8(16), U8(7), U8(2), + B(CreateClosure), U8(15), U8(6), U8(2), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(2), - B(PopContext), R(6), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), + B(CreateClosure), U8(16), U8(7), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(2), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 140 E> */ B(CreateBlockContext), U8(17), - B(PushContext), R(6), + B(PushContext), R(3), + B(LdaConstant), U8(2), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(4), /* 356 E> */ B(CreateClosure), U8(19), U8(8), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(18), - B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(7), R(9), - B(Mov), R(4), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3), - B(Star), R(8), - B(Mov), R(9), R(3), + B(Star), R(5), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(20), U8(9), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(4), - B(PopContext), R(6), - B(Mov), R(3), R(2), - /* 430 S> */ B(Ldar), R(5), - /* 430 E> */ B(Construct), R(5), R(0), U8(0), U8(6), - /* 439 S> */ B(Ldar), R(4), - /* 439 E> */ B(Construct), R(4), R(0), U8(0), U8(8), - /* 448 S> */ B(Ldar), R(3), - /* 448 E> */ B(Construct), R(3), R(0), U8(0), U8(10), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(4), + B(PopContext), R(3), + B(Mov), R(4), R(2), + /* 430 S> */ B(Ldar), R(0), + /* 430 E> */ B(Construct), R(0), R(0), U8(0), U8(6), + /* 439 S> */ B(Ldar), R(1), + /* 439 E> */ B(Construct), R(1), R(0), U8(0), U8(8), + /* 448 S> */ B(Ldar), R(2), + /* 448 E> */ B(Construct), R(2), R(0), U8(0), U8(10), B(LdaUndefined), /* 458 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], FIXED_ARRAY_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], FIXED_ARRAY_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden index d1aab34fda..6456245741 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden @@ -16,38 +16,37 @@ snippet: " " frame size: 7 parameter count: 1 -bytecode array length: 55 +bytecode array length: 52 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(CreateClosure), U8(3), U8(1), U8(2), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(4), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(CreateClosure), U8(4), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(5), R(0), B(LdaUndefined), /* 77 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], ] handlers: [ ] @@ -63,64 +62,62 @@ snippet: " } } " -frame size: 9 +frame size: 8 parameter count: 1 -bytecode array length: 107 +bytecode array length: 101 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(7), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), - B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(4), U8(1), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(3), - B(LdaConstant), U8(4), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(4), - B(Mov), R(3), R(0), + B(PopContext), R(2), + B(Mov), R(6), R(0), /* 38 E> */ B(CreateBlockContext), U8(5), - B(PushContext), R(4), - /* 93 E> */ B(CreateClosure), U8(7), U8(2), U8(2), - B(Star), R(5), + B(PushContext), R(2), + B(LdaConstant), U8(7), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), + /* 93 E> */ B(CreateClosure), U8(8), U8(2), U8(2), + B(Star), R(3), B(LdaConstant), U8(6), - B(Star), R(6), - B(CreateClosure), U8(8), U8(3), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(9), U8(3), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(9), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(6), R(1), B(LdaUndefined), /* 126 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], ] handlers: [ ] @@ -134,50 +131,47 @@ snippet: " } } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 106 +bytecode array length: 98 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), + B(Star), R(7), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), + /* 77 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), B(LdaConstant), U8(5), - B(Star), R(6), - B(CreateClosure), U8(7), U8(3), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(8), U8(3), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(8), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(LdaCurrentContextSlot), U8(4), - B(Star), R(8), - B(Ldar), R(6), - B(StaNamedProperty), R(8), U8(9), U8(0), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(Ldar), R(5), + B(StaNamedProperty), R(6), U8(9), U8(0), + B(PopContext), R(2), + B(Mov), R(3), R(1), B(LdaUndefined), /* 118 S> */ B(Return), ] @@ -188,9 +182,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SYMBOL_TYPE, ] handlers: [ diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden index c91e7b06aa..4b893861bf 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden @@ -21,59 +21,57 @@ snippet: " new B; } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 125 +bytecode array length: 119 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), /* 60 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(CreateClosure), U8(4), U8(1), U8(2), B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(0), - B(PopContext), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(CreateClosure), U8(4), U8(1), U8(2), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(0), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(7), - B(Star), R(6), + B(Star), R(4), /* 99 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(2), - B(CreateClosure), U8(9), U8(3), U8(2), B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(2), - B(PopContext), R(4), - B(Mov), R(2), R(1), - /* 120 S> */ B(Ldar), R(3), - /* 120 E> */ B(Construct), R(3), R(0), U8(0), U8(4), - /* 129 S> */ B(Ldar), R(2), - /* 129 E> */ B(Construct), R(2), R(0), U8(0), U8(6), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(CreateClosure), U8(9), U8(3), U8(2), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(2), + B(PopContext), R(2), + B(Mov), R(3), R(1), + /* 120 S> */ B(Ldar), R(0), + /* 120 E> */ B(Construct), R(0), R(0), U8(0), U8(4), + /* 129 S> */ B(Ldar), R(1), + /* 129 E> */ B(Construct), R(1), R(0), U8(0), U8(6), B(LdaUndefined), /* 138 S> */ B(Return), ] @@ -122,100 +120,97 @@ snippet: " new C; } " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 238 +bytecode array length: 229 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), B(Star), R(11), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(8), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(1), - B(Star), R(8), + B(Star), R(5), /* 77 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4), B(Star), R(8), - B(Mov), R(9), R(5), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4), + B(Star), R(5), B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(0), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(0), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(8), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(11), U8(3), U8(2), B(Star), R(11), + B(CreateClosure), U8(11), U8(3), U8(2), + B(Star), R(8), B(LdaConstant), U8(10), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(9), - B(Star), R(8), + B(Star), R(5), /* 133 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(CreateClosure), U8(13), U8(5), U8(2), - B(Star), R(12), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), B(Star), R(8), - B(Mov), R(9), R(4), - B(CreateClosure), U8(14), U8(6), U8(2), + B(CreateClosure), U8(13), U8(5), U8(2), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(2), - B(PopContext), R(6), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), + B(CreateClosure), U8(14), U8(6), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(2), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 90 E> */ B(CreateBlockContext), U8(15), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), /* 236 E> */ B(CreateClosure), U8(17), U8(7), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(16), - B(Star), R(8), + B(Star), R(5), /* 256 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(Mov), R(7), R(9), - B(Mov), R(4), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4), B(Star), R(8), - B(Mov), R(9), R(3), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4), + B(Star), R(5), B(CreateClosure), U8(18), U8(8), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(4), - B(PopContext), R(6), - B(Mov), R(3), R(2), - /* 329 S> */ B(Ldar), R(5), - /* 329 E> */ B(Construct), R(5), R(0), U8(0), U8(6), - /* 338 S> */ B(Ldar), R(4), - /* 338 E> */ B(Construct), R(4), R(0), U8(0), U8(8), - /* 347 S> */ B(Ldar), R(3), - /* 347 E> */ B(Construct), R(3), R(0), U8(0), U8(10), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(4), + B(PopContext), R(3), + B(Mov), R(4), R(2), + /* 329 S> */ B(Ldar), R(0), + /* 329 E> */ B(Construct), R(0), R(0), U8(0), U8(6), + /* 338 S> */ B(Ldar), R(1), + /* 338 E> */ B(Construct), R(1), R(0), U8(0), U8(8), + /* 347 S> */ B(Ldar), R(2), + /* 347 E> */ B(Construct), R(2), R(0), U8(0), U8(10), B(LdaUndefined), /* 356 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden index f03337e4aa..f47a701358 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden @@ -25,85 +25,83 @@ snippet: " new B; } " -frame size: 11 +frame size: 9 parameter count: 1 -bytecode array length: 191 +bytecode array length: 185 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), /* 60 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), + B(Star), R(7), /* 92 S> */ B(LdaConstant), U8(4), - B(Star), R(10), + B(Star), R(8), B(LdaConstant), U8(5), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(5), R(7), + B(TestEqualStrict), R(8), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(10), + B(Ldar), R(8), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5), - B(Star), R(6), - B(Mov), R(5), R(3), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5), + B(Star), R(4), B(CreateClosure), U8(6), U8(1), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(7), U8(1), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(7), U8(1), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(9), - B(CallProperty0), R(9), R(3), U8(3), - B(PopContext), R(4), + B(Star), R(7), + B(CallProperty0), R(7), R(3), U8(3), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(9), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(11), U8(3), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(10), - B(Star), R(6), + B(Star), R(4), /* 131 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), + B(Star), R(7), /* 176 S> */ B(LdaConstant), U8(4), - B(Star), R(10), + B(Star), R(8), B(LdaConstant), U8(5), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(5), R(7), + B(TestEqualStrict), R(8), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(10), + B(Ldar), R(8), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5), - B(Star), R(6), - B(Mov), R(5), R(2), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5), + B(Star), R(4), B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(7), U8(5), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(7), U8(5), B(CreateClosure), U8(13), U8(5), U8(2), - B(Star), R(9), - B(CallProperty0), R(9), R(2), U8(7), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(Star), R(7), + B(CallProperty0), R(7), R(3), U8(7), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 197 S> */ B(Ldar), R(0), /* 197 E> */ B(Construct), R(0), R(0), U8(0), U8(9), - /* 206 S> */ B(Ldar), R(2), - /* 206 E> */ B(Construct), R(2), R(0), U8(0), U8(11), + /* 206 S> */ B(Ldar), R(1), + /* 206 E> */ B(Construct), R(1), R(0), U8(0), U8(11), B(LdaUndefined), /* 215 S> */ B(Return), ] @@ -162,141 +160,138 @@ snippet: " new C; } " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 343 +bytecode array length: 334 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), B(Star), R(11), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(8), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(1), - B(Star), R(8), + B(Star), R(5), /* 77 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 109 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(13), R(10), - B(Mov), R(7), R(9), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(10), R(7), + B(Mov), R(4), R(6), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), - B(Star), R(8), - B(Mov), R(7), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(1), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(1), B(CreateClosure), U8(10), U8(3), U8(2), - B(Star), R(11), - B(CallProperty0), R(11), R(5), U8(3), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(Star), R(8), + B(CallProperty0), R(8), R(4), U8(3), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(11), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(14), U8(4), U8(2), B(Star), R(11), + B(CreateClosure), U8(14), U8(4), U8(2), + B(Star), R(8), B(LdaConstant), U8(13), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(15), U8(5), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(12), - B(Star), R(8), + B(Star), R(5), /* 165 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 210 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(16), U8(6), U8(2), - B(Star), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(6), - B(Star), R(8), - B(Mov), R(7), R(4), + B(Star), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(6), + B(Star), R(5), B(CreateClosure), U8(17), U8(7), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(5), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(5), B(CreateClosure), U8(18), U8(8), U8(2), - B(Star), R(11), - B(CallProperty0), R(11), R(4), U8(7), - B(PopContext), R(6), + B(Star), R(8), + B(CallProperty0), R(8), R(4), U8(7), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 122 E> */ B(CreateBlockContext), U8(19), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), /* 313 E> */ B(CreateClosure), U8(21), U8(9), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(20), - B(Star), R(8), + B(Star), R(5), /* 333 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 378 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(4), R(10), - B(Mov), R(7), R(9), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), - B(Star), R(8), - B(Mov), R(7), R(3), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), B(CreateClosure), U8(22), U8(10), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(9), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(9), B(CreateClosure), U8(23), U8(11), U8(2), - B(Star), R(11), - B(Ldar), R(3), - B(StaNamedProperty), R(11), U8(24), U8(11), - B(CallProperty0), R(11), R(3), U8(13), - B(PopContext), R(6), - B(Mov), R(3), R(2), + B(Star), R(8), + B(Ldar), R(4), + B(StaNamedProperty), R(8), U8(24), U8(11), + B(CallProperty0), R(8), R(4), U8(13), + B(PopContext), R(3), + B(Mov), R(4), R(2), /* 456 S> */ B(Ldar), R(0), /* 456 E> */ B(Construct), R(0), R(0), U8(0), U8(15), /* 465 S> */ B(Ldar), R(1), /* 465 E> */ B(Construct), R(1), R(0), U8(0), U8(17), - /* 474 S> */ B(Ldar), R(3), - /* 474 E> */ B(Construct), R(3), R(0), U8(0), U8(19), + /* 474 S> */ B(Ldar), R(2), + /* 474 E> */ B(Construct), R(2), R(0), U8(0), U8(19), B(LdaUndefined), /* 483 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden new file mode 100644 index 0000000000..888fca1cf8 --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden @@ -0,0 +1,290 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: no +test function name: test +private methods: yes + +--- +snippet: " + class A { + static #a() { return 1; } + static test() { return this.#a(); } + } + + var test = A.test; + test(); +" +frame size: 4 +parameter count: 1 +bytecode array length: 36 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(LdaCurrentContextSlot), U8(5), + B(TestReferenceEqual), R(this), + B(Mov), R(this), R(1), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(LdaCurrentContextSlot), U8(4), + B(Star), R(0), + /* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0), + /* 73 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], +] +handlers: [ +] + +--- +snippet: " + class B { + static #b() { return 1; } + static test() { this.#b = 1; } + } + + var test = B.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(Wide), B(LdaSmi), I16(261), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + /* 64 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], +] +handlers: [ +] + +--- +snippet: " + class C { + static #c() { return 1; } + static test() { this.#c++; } + } + + var test = C.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(Wide), B(LdaSmi), I16(261), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#c"], +] +handlers: [ +] + +--- +snippet: " + class D { + static get #d() { return 1; } + static set #d(val) { } + + static test() { + this.#d++; + this.#d = 1; + return this.#d; + } + } + + var test = D.test; + test(); +" +frame size: 5 +parameter count: 1 +bytecode array length: 143 +bytecodes: [ + /* 81 E> */ B(StackCheck), + /* 90 S> */ B(LdaCurrentContextSlot), U8(4), + B(Star), R(1), + B(LdaCurrentContextSlot), U8(5), + /* 94 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(0), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1), + B(Star), R(2), + B(CallProperty0), R(2), R(0), U8(0), + B(Inc), U8(2), + B(Star), R(2), + /* 97 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(1), U8(1), + B(Star), R(3), + B(CallProperty1), R(3), R(0), R(2), U8(3), + /* 105 S> */ B(LdaSmi), I8(1), + B(Star), R(0), + B(LdaCurrentContextSlot), U8(4), + B(Star), R(2), + B(LdaCurrentContextSlot), U8(5), + /* 109 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(1), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(260), + B(Star), R(3), + B(LdaConstant), U8(0), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1), + B(Star), R(3), + B(CallProperty1), R(3), R(1), R(0), U8(5), + /* 122 S> */ B(LdaCurrentContextSlot), U8(4), + B(Star), R(1), + B(LdaCurrentContextSlot), U8(5), + /* 133 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(0), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1), + B(Star), R(2), + B(CallProperty0), R(2), R(0), U8(7), + /* 137 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"], +] +handlers: [ +] + +--- +snippet: " + class E { + static get #e() { return 1; } + static test() { this.#e++; } + } + var test = E.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 55 E> */ B(StackCheck), + /* 60 S> */ B(Wide), B(LdaSmi), I16(263), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#e"], +] +handlers: [ +] + +--- +snippet: " + class F { + static set #f(val) { } + static test() { this.#f++; } + } + var test = F.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 48 E> */ B(StackCheck), + /* 53 S> */ B(Wide), B(LdaSmi), I16(262), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#f"], +] +handlers: [ +] + +--- +snippet: " + class G { + static get #d() { return 1; } + static test() { this.#d = 1; } + } + var test = G.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 55 E> */ B(StackCheck), + /* 60 S> */ B(Wide), B(LdaSmi), I16(263), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + /* 68 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"], +] +handlers: [ +] + +--- +snippet: " + class H { + set #h(val) { } + static test() { this.#h; } + } + var test = H.test; + test(); +" +frame size: 3 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 41 E> */ B(StackCheck), + /* 46 S> */ B(Wide), B(LdaSmi), I16(262), + B(Star), R(1), + B(LdaConstant), U8(0), + B(Star), R(2), + B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#h"], +] +handlers: [ +] + diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden new file mode 100644 index 0000000000..fda73f08d2 --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden @@ -0,0 +1,231 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: yes +private methods: yes + +--- +snippet: " + { + class A { + static #a() { return 1; } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 41 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(4), R(0), + B(LdaUndefined), + /* 84 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static get #a() { return 1; } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 51 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(4), + B(LdaNull), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 88 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static set #a(val) { } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 51 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(LdaNull), + B(Star), R(4), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 81 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static get #a() { return 1; } + static set #a(val) { } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 54 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(4), + B(CreateClosure), U8(4), U8(2), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 115 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static #a() { } + #b() { } + } + } +" +frame size: 7 +parameter count: 1 +bytecode array length: 58 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(6), + B(LdaTheHole), + B(Star), R(6), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(4), + B(Mov), R(2), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), + B(CreateClosure), U8(4), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(CreateClosure), U8(5), U8(2), U8(2), + B(StaCurrentContextSlot), U8(5), + B(PopContext), R(1), + B(Mov), R(5), R(0), + B(LdaUndefined), + /* 87 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden index e3eed68138..2ec0a8baa5 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden @@ -91,9 +91,9 @@ snippet: " test = new B(1, 2, 3).constructor; })(); " -frame size: 12 +frame size: 11 parameter count: 1 -bytecode array length: 124 +bytecode array length: 112 bytecodes: [ B(CreateRestParameter), B(Star), R(3), @@ -111,15 +111,11 @@ bytecodes: [ B(Ldar), R(6), B(Inc), U8(3), /* 152 S> */ B(Star), R(6), - B(GetIterator), R(3), U8(4), - B(Star), R(11), - B(CallProperty0), R(11), R(3), U8(6), - B(Mov), R(1), R(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(3), U8(4), U8(6), B(Star), R(9), B(LdaNamedProperty), R(9), U8(0), U8(8), B(Star), R(8), + B(Mov), R(1), R(4), B(CallProperty0), R(8), R(9), U8(14), B(Star), R(10), B(JumpIfJSReceiver), U8(7), diff --git a/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc b/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc index 746c554087..2fe3658813 100644 --- a/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc +++ b/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc @@ -47,11 +47,12 @@ class ProgramOptions final { oneshot_opt_(false), async_iteration_(false), private_methods_(false), + top_level_await_(false), verbose_(false) {} bool Validate() const; - void UpdateFromHeader(std::istream& stream); // NOLINT - void PrintHeader(std::ostream& stream) const; // NOLINT + void UpdateFromHeader(std::istream* stream); + void PrintHeader(std::ostream* stream) const; bool parsing_failed() const { return parsing_failed_; } bool print_help() const { return print_help_; } @@ -70,6 +71,7 @@ class ProgramOptions final { bool oneshot_opt() const { return oneshot_opt_; } bool async_iteration() const { return async_iteration_; } bool private_methods() const { return private_methods_; } + bool top_level_await() const { return top_level_await_; } bool verbose() const { return verbose_; } bool suppress_runtime_errors() const { return baseline() && !verbose_; } std::vector<std::string> input_filenames() const { return input_filenames_; } @@ -90,6 +92,7 @@ class ProgramOptions final { bool oneshot_opt_; bool async_iteration_; bool private_methods_; + bool top_level_await_; bool verbose_; std::vector<std::string> input_filenames_; std::string output_filename_; @@ -196,6 +199,8 @@ ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) { options.async_iteration_ = true; } else if (strcmp(argv[i], "--private-methods") == 0) { options.private_methods_ = true; + } else if (strcmp(argv[i], "--harmony-top-level-await") == 0) { + options.top_level_await_ = true; } else if (strcmp(argv[i], "--verbose") == 0) { options.verbose_ = true; } else if (strncmp(argv[i], "--output=", 9) == 0) { @@ -291,17 +296,17 @@ bool ProgramOptions::Validate() const { return true; } -void ProgramOptions::UpdateFromHeader(std::istream& stream) { +void ProgramOptions::UpdateFromHeader(std::istream* stream) { std::string line; const char* kPrintCallee = "print callee: "; const char* kOneshotOpt = "oneshot opt: "; // Skip to the beginning of the options header - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "---") break; } - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line.compare(0, 8, "module: ") == 0) { module_ = ParseBoolean(line.c_str() + 8); } else if (line.compare(0, 6, "wrap: ") == 0) { @@ -318,6 +323,8 @@ void ProgramOptions::UpdateFromHeader(std::istream& stream) { async_iteration_ = ParseBoolean(line.c_str() + 17); } else if (line.compare(0, 17, "private methods: ") == 0) { private_methods_ = ParseBoolean(line.c_str() + 17); + } else if (line.compare(0, 17, "top level await: ") == 0) { + top_level_await_ = ParseBoolean(line.c_str() + 17); } else if (line == "---") { break; } else if (line.empty()) { @@ -328,22 +335,23 @@ void ProgramOptions::UpdateFromHeader(std::istream& stream) { } } -void ProgramOptions::PrintHeader(std::ostream& stream) const { // NOLINT - stream << "---" - << "\nwrap: " << BooleanToString(wrap_); +void ProgramOptions::PrintHeader(std::ostream* stream) const { + *stream << "---" + << "\nwrap: " << BooleanToString(wrap_); if (!test_function_name_.empty()) { - stream << "\ntest function name: " << test_function_name_; + *stream << "\ntest function name: " << test_function_name_; } - if (module_) stream << "\nmodule: yes"; - if (top_level_) stream << "\ntop level: yes"; - if (print_callee_) stream << "\nprint callee: yes"; - if (oneshot_opt_) stream << "\noneshot opt: yes"; - if (async_iteration_) stream << "\nasync iteration: yes"; - if (private_methods_) stream << "\nprivate methods: yes"; + if (module_) *stream << "\nmodule: yes"; + if (top_level_) *stream << "\ntop level: yes"; + if (print_callee_) *stream << "\nprint callee: yes"; + if (oneshot_opt_) *stream << "\noneshot opt: yes"; + if (async_iteration_) *stream << "\nasync iteration: yes"; + if (private_methods_) *stream << "\nprivate methods: yes"; + if (top_level_await_) *stream << "\ntop level await: yes"; - stream << "\n\n"; + *stream << "\n\n"; } V8InitializationScope::V8InitializationScope(const char* exec_path) @@ -370,17 +378,17 @@ V8InitializationScope::~V8InitializationScope() { v8::V8::ShutdownPlatform(); } -std::string ReadRawJSSnippet(std::istream& stream) { // NOLINT +std::string ReadRawJSSnippet(std::istream* stream) { std::stringstream body_buffer; - CHECK(body_buffer << stream.rdbuf()); + CHECK(body_buffer << stream->rdbuf()); return body_buffer.str(); } -bool ReadNextSnippet(std::istream& stream, std::string* string_out) { // NOLINT +bool ReadNextSnippet(std::istream* stream, std::string* string_out) { std::string line; bool found_begin_snippet = false; string_out->clear(); - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "snippet: \"") { found_begin_snippet = true; continue; @@ -420,8 +428,7 @@ std::string UnescapeString(const std::string& escaped_string) { } void ExtractSnippets(std::vector<std::string>* snippet_list, - std::istream& body_stream, // NOLINT - bool read_raw_js_snippet) { + std::istream* body_stream, bool read_raw_js_snippet) { if (read_raw_js_snippet) { snippet_list->push_back(ReadRawJSSnippet(body_stream)); } else { @@ -432,7 +439,7 @@ void ExtractSnippets(std::vector<std::string>* snippet_list, } } -void GenerateExpectationsFile(std::ostream& stream, // NOLINT +void GenerateExpectationsFile(std::ostream* stream, const std::vector<std::string>& snippet_list, const V8InitializationScope& platform, const ProgramOptions& options) { @@ -452,14 +459,16 @@ void GenerateExpectationsFile(std::ostream& stream, // NOLINT } if (options.private_methods()) i::FLAG_harmony_private_methods = true; + if (options.top_level_await()) i::FLAG_harmony_top_level_await = true; - stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; + *stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; options.PrintHeader(stream); for (const std::string& snippet : snippet_list) { printer.PrintExpectation(stream, snippet); } i::FLAG_harmony_private_methods = false; + i::FLAG_harmony_top_level_await = false; } bool WriteExpectationsFile(const std::vector<std::string>& snippet_list, @@ -477,7 +486,7 @@ bool WriteExpectationsFile(const std::vector<std::string>& snippet_list, std::ostream& output_stream = options.write_to_stdout() ? std::cout : output_file_handle; - GenerateExpectationsFile(output_stream, snippet_list, platform, options); + GenerateExpectationsFile(&output_stream, snippet_list, platform, options); return true; } @@ -487,7 +496,7 @@ std::string WriteExpectationsToString( const V8InitializationScope& platform, const ProgramOptions& options) { std::stringstream output_string; - GenerateExpectationsFile(output_string, snippet_list, platform, options); + GenerateExpectationsFile(&output_string, snippet_list, platform, options); return output_string.str(); } @@ -520,6 +529,7 @@ void PrintUsage(const char* exec_path) { "Specify the name of the test function.\n" " --top-level Process top level code, not the top-level function.\n" " --private-methods Enable harmony_private_methods flag.\n" + " --top-level-await Enable await at the module level.\n" " --output=file.name\n" " Specify the output file. If not specified, output goes to " "stdout.\n" @@ -612,7 +622,7 @@ int main(int argc, char** argv) { // Rebaseline will never get here, so we will always take the // GenerateExpectationsFile at the end of this function. DCHECK(!options.rebaseline() && !options.check_baseline()); - ExtractSnippets(&snippet_list, std::cin, options.read_raw_js_snippet()); + ExtractSnippets(&snippet_list, &std::cin, options.read_raw_js_snippet()); } else { bool check_failed = false; for (const std::string& input_filename : options.input_filenames()) { @@ -628,11 +638,11 @@ int main(int argc, char** argv) { ProgramOptions updated_options = options; if (options.baseline()) { - updated_options.UpdateFromHeader(input_stream); + updated_options.UpdateFromHeader(&input_stream); CHECK(updated_options.Validate()); } - ExtractSnippets(&snippet_list, input_stream, + ExtractSnippets(&snippet_list, &input_stream, options.read_raw_js_snippet()); input_stream.close(); diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc index fda02933aa..be0b129418 100644 --- a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc +++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc @@ -95,10 +95,10 @@ class InitializedIgnitionHandleScope : public InitializedHandleScope { } }; -void SkipGoldenFileHeader(std::istream& stream) { // NOLINT +void SkipGoldenFileHeader(std::istream* stream) { std::string line; int separators_seen = 0; - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "---") separators_seen += 1; if (separators_seen == 2) return; } @@ -107,7 +107,7 @@ void SkipGoldenFileHeader(std::istream& stream) { // NOLINT std::string LoadGolden(const std::string& golden_filename) { std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str()); CHECK(expected_file.is_open()); - SkipGoldenFileHeader(expected_file); + SkipGoldenFileHeader(&expected_file); std::ostringstream expected_stream; // Restore the first separator, which was consumed by SkipGoldenFileHeader expected_stream << "---\n" << expected_file.rdbuf(); @@ -125,31 +125,30 @@ std::string BuildActual(const BytecodeExpectationsPrinter& printer, if (prologue) source_code += prologue; source_code += snippet; if (epilogue) source_code += epilogue; - printer.PrintExpectation(actual_stream, source_code); + printer.PrintExpectation(&actual_stream, source_code); } return actual_stream.str(); } // inplace left trim -static inline void ltrim(std::string& str) { // NOLINT(runtime/references) - str.erase(str.begin(), - std::find_if(str.begin(), str.end(), - [](unsigned char ch) { return !std::isspace(ch); })); +static inline void ltrim(std::string* str) { + str->erase(str->begin(), + std::find_if(str->begin(), str->end(), + [](unsigned char ch) { return !std::isspace(ch); })); } // inplace right trim -static inline void rtrim(std::string& str) { // NOLINT(runtime/references) - str.erase(std::find_if(str.rbegin(), str.rend(), - [](unsigned char ch) { return !std::isspace(ch); }) - .base(), - str.end()); +static inline void rtrim(std::string* str) { + str->erase(std::find_if(str->rbegin(), str->rend(), + [](unsigned char ch) { return !std::isspace(ch); }) + .base(), + str->end()); } -static inline std::string trim( - std::string& str) { // NOLINT(runtime/references) +static inline std::string trim(std::string* str) { ltrim(str); rtrim(str); - return str; + return *str; } bool CompareTexts(const std::string& generated, const std::string& expected) { @@ -181,7 +180,7 @@ bool CompareTexts(const std::string& generated, const std::string& expected) { return false; } - if (trim(generated_line) != trim(expected_line)) { + if (trim(&generated_line) != trim(&expected_line)) { std::cerr << "Inputs differ at line " << line_number << "\n"; std::cerr << " Generated: '" << generated_line << "'\n"; std::cerr << " Expected: '" << expected_line << "'\n"; @@ -2885,6 +2884,130 @@ TEST(PrivateAccessorAccess) { i::FLAG_harmony_private_methods = old_methods_flag; } +TEST(StaticPrivateMethodDeclaration) { + bool old_methods_flag = i::FLAG_harmony_private_methods; + i::FLAG_harmony_private_methods = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + + const char* snippets[] = { + "{\n" + " class A {\n" + " static #a() { return 1; }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static get #a() { return 1; }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static set #a(val) { }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static get #a() { return 1; }\n" + " static set #a(val) { }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static #a() { }\n" + " #b() { }\n" + " }\n" + "}\n"}; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("StaticPrivateMethodDeclaration.golden"))); + i::FLAG_harmony_private_methods = old_methods_flag; +} + +TEST(StaticPrivateMethodAccess) { + bool old_methods_flag = i::FLAG_harmony_private_methods; + i::FLAG_harmony_private_methods = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + printer.set_wrap(false); + printer.set_test_function_name("test"); + + const char* snippets[] = { + "class A {\n" + " static #a() { return 1; }\n" + " static test() { return this.#a(); }\n" + "}\n" + "\n" + "var test = A.test;\n" + "test();\n", + + "class B {\n" + " static #b() { return 1; }\n" + " static test() { this.#b = 1; }\n" + "}\n" + "\n" + "var test = B.test;\n" + "test();\n", + + "class C {\n" + " static #c() { return 1; }\n" + " static test() { this.#c++; }\n" + "}\n" + "\n" + "var test = C.test;\n" + "test();\n", + + "class D {\n" + " static get #d() { return 1; }\n" + " static set #d(val) { }\n" + "\n" + " static test() {\n" + " this.#d++;\n" + " this.#d = 1;\n" + " return this.#d;\n" + " }\n" + "}\n" + "\n" + "var test = D.test;\n" + "test();\n", + + "class E {\n" + " static get #e() { return 1; }\n" + " static test() { this.#e++; }\n" + "}\n" + "var test = E.test;\n" + "test();\n", + + "class F {\n" + " static set #f(val) { }\n" + " static test() { this.#f++; }\n" + "}\n" + "var test = F.test;\n" + "test();\n", + + "class G {\n" + " static get #d() { return 1; }\n" + " static test() { this.#d = 1; }\n" + "}\n" + "var test = G.test;\n" + "test();\n", + + "class H {\n" + " set #h(val) { }\n" + " static test() { this.#h; }\n" + "}\n" + "var test = H.test;\n" + "test();\n"}; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("StaticPrivateMethodAccess.golden"))); + i::FLAG_harmony_private_methods = old_methods_flag; +} + TEST(PrivateAccessorDeclaration) { bool old_methods_flag = i::FLAG_harmony_private_methods; i::FLAG_harmony_private_methods = true; @@ -3099,6 +3222,35 @@ TEST(Modules) { LoadGolden("Modules.golden"))); } +TEST(AsyncModules) { + bool previous_top_level_await_flag = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + printer.set_wrap(false); + printer.set_module(true); + printer.set_top_level(true); + + const char* snippets[] = { + "await 42;\n", + + "await import(\"foo\");\n", + + "await 42;\n" + "async function foo() {\n" + " await 42;\n" + "}\n" + "foo();\n", + + "import * as foo from \"bar\";\n" + "await import(\"goo\");\n", + }; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("AsyncModules.golden"))); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag; +} + TEST(SuperCallAndSpread) { InitializedIgnitionHandleScope scope; BytecodeExpectationsPrinter printer(CcTest::isolate()); diff --git a/deps/v8/test/cctest/interpreter/test-interpreter.cc b/deps/v8/test/cctest/interpreter/test-interpreter.cc index 466e768d7d..0ddc8fe608 100644 --- a/deps/v8/test/cctest/interpreter/test-interpreter.cc +++ b/deps/v8/test/cctest/interpreter/test-interpreter.cc @@ -1485,19 +1485,20 @@ TEST(InterpreterCall) { } } -static BytecodeArrayBuilder& SetRegister( - BytecodeArrayBuilder& builder, // NOLINT(runtime/references) - Register reg, int value, Register scratch) { - return builder.StoreAccumulatorInRegister(scratch) +static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder* builder, + Register reg, int value, + Register scratch) { + return builder->StoreAccumulatorInRegister(scratch) .LoadLiteral(Smi::FromInt(value)) .StoreAccumulatorInRegister(reg) .LoadAccumulatorWithRegister(scratch); } -static BytecodeArrayBuilder& IncrementRegister( - BytecodeArrayBuilder& builder, // NOLINT(runtime/references) - Register reg, int value, Register scratch, int slot_index) { - return builder.StoreAccumulatorInRegister(scratch) +static BytecodeArrayBuilder& IncrementRegister(BytecodeArrayBuilder* builder, + Register reg, int value, + Register scratch, + int slot_index) { + return builder->StoreAccumulatorInRegister(scratch) .LoadLiteral(Smi::FromInt(value)) .BinaryOperation(Token::Value::ADD, reg, slot_index) .StoreAccumulatorInRegister(reg) @@ -1525,13 +1526,13 @@ TEST(InterpreterJumps) { builder.LoadLiteral(Smi::zero()) .StoreAccumulatorInRegister(reg) .Jump(&label[0]); - SetRegister(builder, reg, 1024, scratch).Bind(&loop_header); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[1]); - SetRegister(builder, reg, 2048, scratch).Bind(&label[0]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot1)) + SetRegister(&builder, reg, 1024, scratch).Bind(&loop_header); + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[1]); + SetRegister(&builder, reg, 2048, scratch).Bind(&label[0]); + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot1)) .JumpLoop(&loop_header, 0); - SetRegister(builder, reg, 4096, scratch).Bind(&label[1]); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot2)) + SetRegister(&builder, reg, 4096, scratch).Bind(&label[1]); + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot2)) .LoadAccumulatorWithRegister(reg) .Return(); @@ -1566,19 +1567,19 @@ TEST(InterpreterConditionalJumps) { .StoreAccumulatorInRegister(reg) .LoadFalse() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]); - IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) + IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot)) .Bind(&label[0]) .LoadTrue() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1)) .LoadTrue() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]); - IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) + IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2)) .Bind(&label[1]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3)) .LoadFalse() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4)) .LoadAccumulatorWithRegister(reg) .Bind(&done) .Bind(&done1) @@ -1616,19 +1617,19 @@ TEST(InterpreterConditionalJumps2) { .StoreAccumulatorInRegister(reg) .LoadFalse() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]); - IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) + IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot)) .Bind(&label[0]) .LoadTrue() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1)) .LoadTrue() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]); - IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) + IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2)) .Bind(&label[1]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3)) .LoadFalse() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4)) .LoadAccumulatorWithRegister(reg) .Bind(&done) .Bind(&done1) diff --git a/deps/v8/test/cctest/libplatform/DEPS b/deps/v8/test/cctest/libplatform/DEPS index b2bee408ab..54415e157b 100644 --- a/deps/v8/test/cctest/libplatform/DEPS +++ b/deps/v8/test/cctest/libplatform/DEPS @@ -1,3 +1,3 @@ include_rules = [ - "+perfetto", + "+protos/perfetto", ] diff --git a/deps/v8/test/cctest/libplatform/test-tracing.cc b/deps/v8/test/cctest/libplatform/test-tracing.cc index a98445be97..1f1cb55f9b 100644 --- a/deps/v8/test/cctest/libplatform/test-tracing.cc +++ b/deps/v8/test/cctest/libplatform/test-tracing.cc @@ -10,11 +10,11 @@ #include "test/cctest/cctest.h" #ifdef V8_USE_PERFETTO -#include "perfetto/trace/chrome/chrome_trace_event.pb.h" -#include "perfetto/trace/chrome/chrome_trace_event.pbzero.h" -#include "perfetto/trace/chrome/chrome_trace_packet.pb.h" -#include "perfetto/trace/trace.pb.h" #include "perfetto/tracing.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pb.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" +#include "protos/perfetto/trace/chrome/chrome_trace_packet.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #include "src/libplatform/tracing/json-trace-event-listener.h" #include "src/libplatform/tracing/trace-event-listener.h" #endif // V8_USE_PERFETTO @@ -157,7 +157,7 @@ void PopulateJSONWriter(TraceWriter* writer) { std::unique_ptr<v8::Platform> default_platform( v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -242,7 +242,7 @@ TEST(TestTracingController) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -301,8 +301,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = - base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) @@ -424,7 +423,7 @@ TEST(TracingObservers) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -517,7 +516,7 @@ TEST(AddTraceEventMultiThreaded) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -576,8 +575,7 @@ class TracingTestHarness { default_platform_ = v8::platform::NewDefaultPlatform(); i::V8::SetPlatformForTesting(default_platform_.get()); - auto tracing = - base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); tracing_controller_ = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform_.get()) ->SetTracingController(std::move(tracing)); diff --git a/deps/v8/test/cctest/manually-externalized-buffer.h b/deps/v8/test/cctest/manually-externalized-buffer.h new file mode 100644 index 0000000000..b5eeed7382 --- /dev/null +++ b/deps/v8/test/cctest/manually-externalized-buffer.h @@ -0,0 +1,34 @@ +// Copyright 2019 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. + +#ifndef V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ +#define V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ + +#include "src/api/api-inl.h" + +namespace v8 { +namespace internal { +namespace testing { + +// Utility to free the allocated memory for a buffer that is manually +// externalized in a test. +struct ManuallyExternalizedBuffer { + Handle<JSArrayBuffer> buffer_; + v8::ArrayBuffer::Contents contents_; + + explicit ManuallyExternalizedBuffer(Handle<JSArrayBuffer> buffer) + : buffer_(buffer), + contents_(v8::Utils::ToLocal(buffer_)->Externalize()) {} + ~ManuallyExternalizedBuffer() { + contents_.Deleter()(contents_.Data(), contents_.ByteLength(), + contents_.DeleterData()); + } + void* backing_store() { return contents_.Data(); } +}; + +} // namespace testing +} // namespace internal +} // namespace v8 + +#endif // V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ diff --git a/deps/v8/test/cctest/test-accessor-assembler.cc b/deps/v8/test/cctest/test-accessor-assembler.cc index c88c85b586..6183ef970c 100644 --- a/deps/v8/test/cctest/test-accessor-assembler.cc +++ b/deps/v8/test/cctest/test-accessor-assembler.cc @@ -18,7 +18,6 @@ namespace internal { using compiler::CodeAssemblerTester; using compiler::FunctionTester; using compiler::Node; -using compiler::TNode; namespace { diff --git a/deps/v8/test/cctest/test-api-accessors.cc b/deps/v8/test/cctest/test-api-accessors.cc index 8c2f92d665..5f82d78711 100644 --- a/deps/v8/test/cctest/test-api-accessors.cc +++ b/deps/v8/test/cctest/test-api-accessors.cc @@ -287,21 +287,30 @@ TEST(AccessorSetHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetAccessor(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetAccessor(context, v8_str("foo"), Getter, nullptr, v8::MaybeLocal<v8::Value>(), v8::AccessControl::DEFAULT, v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -323,12 +332,16 @@ TEST(SetAccessorSetSideEffectReceiverCheck1) { v8::SideEffectType::kHasNoSideEffect, v8::SideEffectType::kHasSideEffectToReceiver) .ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked() ->Equals(env.local(), v8_str("return value")) .FromJust()); v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); CHECK_EQ(0, set_accessor_call_count); @@ -357,11 +370,15 @@ TEST(SetAccessorSetSideEffectReceiverCheck2) { ->Set(env.local(), v8_str("f"), templ->GetFunction(env.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f().bar"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked() ->Equals(env.local(), v8_str("return value")) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar = 1"), true) + v8::debug::EvaluateGlobal( + isolate, v8_str("new f().bar = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); CHECK_EQ(1, set_accessor_call_count); } @@ -377,20 +394,29 @@ TEST(AccessorSetNativeDataPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetNativeDataProperty(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetNativeDataProperty( context, v8_str("foo"), Getter, nullptr, v8::Local<v8::Value>(), v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -407,20 +433,29 @@ TEST(AccessorSetLazyDataPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetLazyDataProperty(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetLazyDataProperty(context, v8_str("foo"), Getter, v8::Local<v8::Value>(), v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -440,15 +475,24 @@ TEST(ObjectTemplateSetAccessorHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -468,15 +512,24 @@ TEST(ObjectTemplateSetNativePropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -495,15 +548,24 @@ TEST(ObjectTemplateSetLazyPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc index 5b8433a6a2..508604aa41 100644 --- a/deps/v8/test/cctest/test-api-array-buffer.cc +++ b/deps/v8/test/cctest/test-api-array-buffer.cc @@ -13,43 +13,6 @@ using ::v8::Value; namespace { -class ScopedArrayBufferContents { - public: - explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::ArrayBuffer::Contents contents_; -}; - -class ScopedSharedArrayBufferContents { - public: - explicit ScopedSharedArrayBufferContents( - const v8::SharedArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedSharedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::SharedArrayBuffer::Contents contents_; -}; - void CheckDataViewIsDetached(v8::Local<v8::DataView> dv) { CHECK_EQ(0, static_cast<int>(dv->ByteLength())); CHECK_EQ(0, static_cast<int>(dv->ByteOffset())); @@ -83,6 +46,20 @@ Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, int byteOffset, return ta; } +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::ArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::SharedArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + } // namespace THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { @@ -92,15 +69,14 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); + CHECK_EQ(1024, backing_store->ByteLength()); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -133,10 +109,9 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -152,8 +127,8 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -172,7 +147,7 @@ THREADED_TEST(ArrayBuffer_External) { Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(isolate, my_data.begin(), 100); CheckInternalFieldsAreZero(ab3); - CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); + CHECK_EQ(100, ab3->ByteLength()); CHECK(ab3->IsExternal()); CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust()); @@ -242,12 +217,12 @@ THREADED_TEST(ArrayBuffer_DetachingApi) { v8::Local<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); - CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); - CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); + CHECK_EQ(1, dv->ByteOffset()); + CHECK_EQ(1023, dv->ByteLength()); - ScopedArrayBufferContents contents(buffer->Externalize()); + Externalize(buffer); buffer->Detach(); - CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); + CHECK_EQ(0, buffer->ByteLength()); CheckIsDetached(u8a); CheckIsDetached(u8c); CheckIsDetached(i8a); @@ -283,9 +258,9 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { v8::Local<v8::DataView> dv = v8::Local<v8::DataView>::Cast(CompileRun("dv")); - ScopedArrayBufferContents contents(ab->Externalize()); + Externalize(ab); ab->Detach(); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(0, ab->ByteLength()); CHECK_EQ(0, v8_run_int32value(v8_compile("ab.byteLength"))); CheckIsTypedArrayVarDetached("u8a"); @@ -302,6 +277,7 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { CheckDataViewIsDetached(dv); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(ArrayBuffer_AllocationInformation) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -309,7 +285,7 @@ THREADED_TEST(ArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, ab_size); - ScopedArrayBufferContents contents(ab->Externalize()); + v8::ArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -329,13 +305,13 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 0); + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 2); CheckInternalFieldsAreZero(ab); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(2, ab->ByteLength()); CHECK(!ab->IsExternal()); // Externalize the buffer (taking ownership of the backing store memory). - ScopedArrayBufferContents ab_contents(ab->Externalize()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); Local<v8::Uint8Array> u8a = v8::Uint8Array::New(ab, 0, 0); // Calling Buffer() will materialize the ArrayBuffer (transitioning it from @@ -344,6 +320,7 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { USE(u8a->Buffer()); CHECK(ab->IsExternal()); + CHECK_EQ(2, backing_store->ByteLength()); } THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { @@ -354,15 +331,14 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedSharedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + CHECK_EQ(1024, backing_store->ByteLength()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -383,6 +359,35 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +THREADED_TEST(ArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + ab1->Detach(); + Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + +THREADED_TEST(SharedArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::SharedArrayBuffer> ab1 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + Local<v8::SharedArrayBuffer> ab2 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -396,10 +401,9 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -415,8 +419,8 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -458,6 +462,7 @@ THREADED_TEST(SharedArrayBuffer_External) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(SharedArrayBuffer_AllocationInformation) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -467,7 +472,7 @@ THREADED_TEST(SharedArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, ab_size); - ScopedSharedArrayBufferContents contents(ab->Externalize()); + v8::SharedArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -500,7 +505,7 @@ THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) { CcTest::CollectAllGarbage(); // Should not move the pointer - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); } THREADED_TEST(SkipArrayBufferDuringScavenge) { @@ -525,5 +530,16 @@ THREADED_TEST(SkipArrayBufferDuringScavenge) { CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now // Use `ab` to silence compiler warning - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); +} + +THREADED_TEST(Regress1006600) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + Local<v8::Value> ab = CompileRunChecked(isolate, "new ArrayBuffer()"); + for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) { + CHECK_NULL(ab.As<v8::Object>()->GetAlignedPointerFromInternalField(i)); + } } diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc index e331d1a26a..cbf9f75be5 100644 --- a/deps/v8/test/cctest/test-api-interceptors.cc +++ b/deps/v8/test/cctest/test-api-interceptors.cc @@ -2712,16 +2712,26 @@ THREADED_TEST(NoSideEffectPropertyHandler) { templ->NewInstance(context.local()).ToLocalChecked(); context->Global()->Set(context.local(), v8_str("obj"), object).FromJust(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.x"), true).IsEmpty()); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("obj.x = 1"), true).IsEmpty()); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("'x' in obj"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("delete obj.x"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.x = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("'x' in obj"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("delete obj.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); // Wrap the variable declaration since declaring globals is a side effect. CHECK(v8::debug::EvaluateGlobal( - isolate, v8_str("(function() { for (var p in obj) ; })()"), true) + isolate, v8_str("(function() { for (var p in obj) ; })()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); // Side-effect-free version. @@ -2734,15 +2744,25 @@ THREADED_TEST(NoSideEffectPropertyHandler) { templ2->NewInstance(context.local()).ToLocalChecked(); context->Global()->Set(context.local(), v8_str("obj2"), object2).FromJust(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj2.x"), true).ToLocalChecked(); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("obj2.x = 1"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("'x' in obj2"), true) + v8::debug::EvaluateGlobal( + isolate, v8_str("obj2.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj2.x = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("'x' in obj2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("delete obj2.x"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("delete obj2.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); v8::debug::EvaluateGlobal( - isolate, v8_str("(function() { for (var p in obj2) ; })()"), true) + isolate, v8_str("(function() { for (var p in obj2) ; })()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); } diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 345ee0bfc9..1daa19402e 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -46,6 +46,7 @@ #include "src/execution/arguments.h" #include "src/execution/execution.h" #include "src/execution/futex-emulation.h" +#include "src/execution/protectors-inl.h" #include "src/execution/vm-state.h" #include "src/handles/global-handles.h" #include "src/heap/heap-inl.h" @@ -2955,11 +2956,8 @@ THREADED_TEST(SetAlignedPointerInInternalFields) { obj->SetAlignedPointerInInternalFields(2, indices, values); CcTest::CollectAllGarbage(); - { - v8::SealHandleScope no_handle_leak(isolate); - CHECK_EQ(heap_allocated_1, obj->GetAlignedPointerFromInternalField(0)); - CHECK_EQ(heap_allocated_2, obj->GetAlignedPointerFromInternalField(1)); - } + CHECK_EQ(heap_allocated_1, obj->GetAlignedPointerFromInternalField(0)); + CHECK_EQ(heap_allocated_2, obj->GetAlignedPointerFromInternalField(1)); indices[0] = 1; indices[1] = 0; @@ -3012,7 +3010,6 @@ THREADED_TEST(EmbedderDataAlignedPointers) { } CcTest::CollectAllGarbage(); for (int i = 0; i < 100; i++) { - v8::SealHandleScope no_handle_leak(env->GetIsolate()); CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i)); } } @@ -7064,7 +7061,7 @@ static const char* kSimpleExtensionSource = TEST(SimpleExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("simpletest", kSimpleExtensionSource)); + std::make_unique<Extension>("simpletest", kSimpleExtensionSource)); const char* extension_names[] = {"simpletest"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7086,7 +7083,7 @@ static const char* kStackTraceFromExtensionSource = TEST(StackTraceInExtension) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( + v8::RegisterExtension(std::make_unique<Extension>( "stacktracetest", kStackTraceFromExtensionSource)); const char* extension_names[] = {"stacktracetest"}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7104,7 +7101,7 @@ TEST(StackTraceInExtension) { TEST(NullExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>("nulltest", nullptr)); + v8::RegisterExtension(std::make_unique<Extension>("nulltest", nullptr)); const char* extension_names[] = {"nulltest"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7122,8 +7119,8 @@ static const int kEmbeddedExtensionSourceValidLen = 34; TEST(ExtensionMissingSourceLength) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "srclentest_fail", kEmbeddedExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("srclentest_fail", kEmbeddedExtensionSource)); const char* extension_names[] = {"srclentest_fail"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7137,9 +7134,9 @@ TEST(ExtensionWithSourceLength) { v8::HandleScope handle_scope(CcTest::isolate()); i::ScopedVector<char> extension_name(32); i::SNPrintF(extension_name, "ext #%d", source_len); - v8::RegisterExtension(v8::base::make_unique<Extension>( - extension_name.begin(), kEmbeddedExtensionSource, 0, nullptr, - source_len)); + v8::RegisterExtension(std::make_unique<Extension>(extension_name.begin(), + kEmbeddedExtensionSource, + 0, nullptr, source_len)); const char* extension_names[1] = {extension_name.begin()}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7177,9 +7174,9 @@ static const char* kEvalExtensionSource2 = TEST(UseEvalFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("evaltest1", kEvalExtensionSource1)); + std::make_unique<Extension>("evaltest1", kEvalExtensionSource1)); v8::RegisterExtension( - v8::base::make_unique<Extension>("evaltest2", kEvalExtensionSource2)); + std::make_unique<Extension>("evaltest2", kEvalExtensionSource2)); const char* extension_names[] = {"evaltest1", "evaltest2"}; v8::ExtensionConfiguration extensions(2, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7213,9 +7210,9 @@ static const char* kWithExtensionSource2 = TEST(UseWithFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("withtest1", kWithExtensionSource1)); + std::make_unique<Extension>("withtest1", kWithExtensionSource1)); v8::RegisterExtension( - v8::base::make_unique<Extension>("withtest2", kWithExtensionSource2)); + std::make_unique<Extension>("withtest2", kWithExtensionSource2)); const char* extension_names[] = {"withtest1", "withtest2"}; v8::ExtensionConfiguration extensions(2, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7232,7 +7229,7 @@ TEST(UseWithFromExtension) { TEST(AutoExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); auto extension = - v8::base::make_unique<Extension>("autotest", kSimpleExtensionSource); + std::make_unique<Extension>("autotest", kSimpleExtensionSource); extension->set_auto_enable(true); v8::RegisterExtension(std::move(extension)); v8::Local<Context> context = Context::New(CcTest::isolate()); @@ -7250,7 +7247,7 @@ static const char* kSyntaxErrorInExtensionSource = "["; // error but results in an empty context. TEST(SyntaxErrorExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( + v8::RegisterExtension(std::make_unique<Extension>( "syntaxerror", kSyntaxErrorInExtensionSource)); const char* extension_names[] = {"syntaxerror"}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7266,8 +7263,8 @@ static const char* kExceptionInExtensionSource = "throw 42"; // a fatal error but results in an empty context. TEST(ExceptionExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "exception", kExceptionInExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("exception", kExceptionInExtensionSource)); const char* extension_names[] = {"exception"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7285,8 +7282,8 @@ static const char* kNativeCallTest = // Test that a native runtime calls are supported in extensions. TEST(NativeCallInExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "nativecall", kNativeCallInExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("nativecall", kNativeCallInExtensionSource)); const char* extension_names[] = {"nativecall"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7320,7 +7317,7 @@ class NativeFunctionExtension : public Extension { TEST(NativeFunctionDeclaration) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedecl"; - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "native function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7336,7 +7333,7 @@ TEST(NativeFunctionDeclarationError) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerr"; // Syntax error in extension code. - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "native\nfunction foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7350,7 +7347,7 @@ TEST(NativeFunctionDeclarationErrorEscape) { const char* name = "nativedeclerresc"; // Syntax error in extension code - escape code in "native" means that // it's not treated as a keyword. - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "nativ\\u0065 function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7382,17 +7379,17 @@ static void CheckDependencies(const char* name, const char* expected) { THREADED_TEST(ExtensionDependency) { static const char* kEDeps[] = {"D"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("E", "this.loaded += 'E';", 1, kEDeps)); + std::make_unique<Extension>("E", "this.loaded += 'E';", 1, kEDeps)); static const char* kDDeps[] = {"B", "C"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("D", "this.loaded += 'D';", 2, kDDeps)); + std::make_unique<Extension>("D", "this.loaded += 'D';", 2, kDDeps)); static const char* kBCDeps[] = {"A"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("B", "this.loaded += 'B';", 1, kBCDeps)); + std::make_unique<Extension>("B", "this.loaded += 'B';", 1, kBCDeps)); v8::RegisterExtension( - v8::base::make_unique<Extension>("C", "this.loaded += 'C';", 1, kBCDeps)); + std::make_unique<Extension>("C", "this.loaded += 'C';", 1, kBCDeps)); v8::RegisterExtension( - v8::base::make_unique<Extension>("A", "this.loaded += 'A';")); + std::make_unique<Extension>("A", "this.loaded += 'A';")); CheckDependencies("A", "undefinedA"); CheckDependencies("B", "undefinedAB"); CheckDependencies("C", "undefinedAC"); @@ -7464,7 +7461,7 @@ v8::Local<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( THREADED_TEST(FunctionLookup) { - v8::RegisterExtension(v8::base::make_unique<FunctionExtension>()); + v8::RegisterExtension(std::make_unique<FunctionExtension>()); v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = {"functiontest"}; v8::ExtensionConfiguration config(1, exts); @@ -7483,7 +7480,7 @@ THREADED_TEST(FunctionLookup) { THREADED_TEST(NativeFunctionConstructCall) { - v8::RegisterExtension(v8::base::make_unique<FunctionExtension>()); + v8::RegisterExtension(std::make_unique<FunctionExtension>()); v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = {"functiontest"}; v8::ExtensionConfiguration config(1, exts); @@ -7520,9 +7517,9 @@ void StoringErrorCallback(const char* location, const char* message) { TEST(ErrorReporting) { CcTest::isolate()->SetFatalErrorHandler(StoringErrorCallback); static const char* aDeps[] = {"B"}; - v8::RegisterExtension(v8::base::make_unique<Extension>("A", "", 1, aDeps)); + v8::RegisterExtension(std::make_unique<Extension>("A", "", 1, aDeps)); static const char* bDeps[] = {"A"}; - v8::RegisterExtension(v8::base::make_unique<Extension>("B", "", 1, bDeps)); + v8::RegisterExtension(std::make_unique<Extension>("B", "", 1, bDeps)); last_location = nullptr; v8::ExtensionConfiguration config(1, bDeps); v8::Local<Context> context = Context::New(CcTest::isolate(), &config); @@ -10625,7 +10622,6 @@ THREADED_TEST(ShadowObjectAndDataProperty) { i::FeedbackSlot slot = i::FeedbackVector::ToSlot(0); i::FeedbackNexus nexus(foo->feedback_vector(), slot); CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind()); - CHECK_EQ(i::PREMONOMORPHIC, nexus.ic_state()); CompileRun("foo(1)"); CHECK_EQ(i::MONOMORPHIC, nexus.ic_state()); // We go a bit further, checking that the form of monomorphism is @@ -10676,7 +10672,6 @@ THREADED_TEST(ShadowObjectAndDataPropertyTurbo) { i::FeedbackSlot slot = i::FeedbackVector::ToSlot(0); i::FeedbackNexus nexus(foo->feedback_vector(), slot); CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind()); - CHECK_EQ(i::PREMONOMORPHIC, nexus.ic_state()); CompileRun("%OptimizeFunctionOnNextCall(foo); foo(1)"); CHECK_EQ(i::MONOMORPHIC, nexus.ic_state()); i::HeapObject heap_object; @@ -12310,8 +12305,14 @@ TEST(CallHandlerHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(isolate); @@ -12321,8 +12322,14 @@ TEST(CallHandlerHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionTemplateNewHasNoSideEffect) { @@ -12337,8 +12344,14 @@ TEST(FunctionTemplateNewHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New( @@ -12348,8 +12361,14 @@ TEST(FunctionTemplateNewHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { @@ -12366,8 +12385,14 @@ TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::NewWithCache( @@ -12377,8 +12402,14 @@ TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionNewHasNoSideEffect) { @@ -12390,8 +12421,14 @@ TEST(FunctionNewHasNoSideEffect) { Local<Function> func = Function::New(context.local(), EmptyHandler).ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<Function> func2 = @@ -12401,8 +12438,14 @@ TEST(FunctionNewHasNoSideEffect) { .ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f2"), func2).FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } // These handlers instantiate a function the embedder considers safe in some @@ -12461,7 +12504,10 @@ TEST(FunctionNewInstanceHasNoSideEffect) { v8::SideEffectType::kHasNoSideEffect) .ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func0).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // A whitelisted function that creates a new object. Should throw. Local<Function> func = @@ -12470,7 +12516,10 @@ TEST(FunctionNewInstanceHasNoSideEffect) { v8::SideEffectType::kHasNoSideEffect) .ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // A whitelisted function that creates a new object with explicit intent to // have no side-effects (e.g. building an "object wrapper"). Should not throw. @@ -12481,18 +12530,26 @@ TEST(FunctionNewInstanceHasNoSideEffect) { .ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f2"), func2).FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that side effect skipping did not leak outside to future evaluations. Local<Function> func3 = Function::New(context.local(), EmptyHandler).ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f3"), func3).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f3()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f3()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Check that using side effect free NewInstance works in normal evaluation // (without throwOnSideEffect). - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), false).ToLocalChecked(); + v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDefault) + .ToLocalChecked(); } TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { @@ -12505,7 +12562,10 @@ TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { templ->SetCallAsFunctionHandler(EmptyHandler); Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version is not supported. i::FunctionTemplateInfo cons = i::FunctionTemplateInfo::cast( @@ -12516,7 +12576,10 @@ TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { CHECK(!handler_info.IsSideEffectFreeCallHandlerInfo()); handler_info.set_map( i::ReadOnlyRoots(heap).side_effect_free_call_handler_info_map()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); } static void IsConstructHandler( @@ -18192,10 +18255,10 @@ static void BreakArrayGuarantees(const char* script) { v8::Context::Scope context_scope(context); v8::internal::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate1); - CHECK(i_isolate->IsNoElementsProtectorIntact()); + CHECK(v8::internal::Protectors::IsNoElementsIntact(i_isolate)); // Run something in new isolate. CompileRun(script); - CHECK(!i_isolate->IsNoElementsProtectorIntact()); + CHECK(!v8::internal::Protectors::IsNoElementsIntact(i_isolate)); } isolate1->Exit(); isolate1->Dispose(); @@ -23170,7 +23233,7 @@ void RunStreamingTest(const char** chunks, v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), encoding); + std::make_unique<TestSourceStream>(chunks), encoding); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23441,7 +23504,7 @@ TEST(StreamingWithDebuggingEnabledLate) { v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), + std::make_unique<TestSourceStream>(chunks), v8::ScriptCompiler::StreamedSource::ONE_BYTE); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23549,7 +23612,7 @@ TEST(StreamingWithHarmonyScopes) { v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), + std::make_unique<TestSourceStream>(chunks), v8::ScriptCompiler::StreamedSource::ONE_BYTE); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23658,9 +23721,7 @@ v8::MaybeLocal<Value> SyntheticModuleEvaluationStepsCallbackFail( v8::MaybeLocal<Value> SyntheticModuleEvaluationStepsCallbackSetExport( Local<Context> context, Local<Module> module) { - Maybe<bool> set_export_result = module->SetSyntheticModuleExport( - context->GetIsolate(), v8_str("test_export"), v8_num(42)); - CHECK(set_export_result.FromJust()); + module->SetSyntheticModuleExport(v8_str("test_export"), v8_num(42)); return v8::Undefined(reinterpret_cast<v8::Isolate*>(context->GetIsolate())); } @@ -23771,7 +23832,13 @@ TEST(ModuleCodeCache) { // Evaluate for possible lazy compilation. Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } // Now create the cache. Note that it is freed, obscurely, when // ScriptCompiler::Source goes out of scope below. @@ -23802,7 +23869,13 @@ TEST(ModuleCodeCache) { Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } isolate->Dispose(); } @@ -23867,9 +23940,7 @@ TEST(SyntheticModuleSetExports) { // undefined. CHECK(foo_cell->value().IsUndefined()); - Maybe<bool> set_export_result = - module->SetSyntheticModuleExport(isolate, foo_string, bar_string); - CHECK(set_export_result.FromJust()); + module->SetSyntheticModuleExport(foo_string, bar_string); // After setting the export the Cell should still have the same idenitity. CHECK_EQ(exports->Lookup(v8::Utils::OpenHandle(*foo_string)), *foo_cell); @@ -23880,34 +23951,6 @@ TEST(SyntheticModuleSetExports) { ->Equals(*v8::Utils::OpenHandle(*bar_string))); } -TEST(SyntheticModuleSetMissingExport) { - LocalContext env; - v8::Isolate* isolate = env->GetIsolate(); - auto i_isolate = reinterpret_cast<i::Isolate*>(isolate); - v8::Isolate::Scope iscope(isolate); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope cscope(context); - - Local<String> foo_string = v8_str("foo"); - Local<String> bar_string = v8_str("bar"); - - Local<Module> module = CreateAndInstantiateSyntheticModule( - isolate, v8_str("SyntheticModuleSetExports-TestSyntheticModule"), context, - std::vector<v8::Local<v8::String>>(), - UnexpectedSyntheticModuleEvaluationStepsCallback); - - i::Handle<i::SyntheticModule> i_module = - i::Handle<i::SyntheticModule>::cast(v8::Utils::OpenHandle(*module)); - i::Handle<i::ObjectHashTable> exports(i_module->exports(), i_isolate); - - TryCatch try_catch(isolate); - Maybe<bool> set_export_result = - module->SetSyntheticModuleExport(isolate, foo_string, bar_string); - CHECK(set_export_result.IsNothing()); - CHECK(try_catch.HasCaught()); -} - TEST(SyntheticModuleEvaluationStepsNoThrow) { synthetic_module_callback_count = 0; LocalContext env; @@ -24011,7 +24054,13 @@ TEST(ImportFromSyntheticModule) { .ToChecked(); Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } TEST(ImportFromSyntheticModuleThrow) { @@ -24041,7 +24090,15 @@ TEST(ImportFromSyntheticModuleThrow) { CHECK_EQ(module->GetStatus(), Module::kInstantiated); TryCatch try_catch(isolate); v8::MaybeLocal<Value> completion_value = module->Evaluate(context); - CHECK(completion_value.IsEmpty()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise( + Local<v8::Promise>::Cast(completion_value.ToLocalChecked())); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK_EQ(promise->Result(), try_catch.Exception()); + } else { + CHECK(completion_value.IsEmpty()); + } + CHECK_EQ(module->GetStatus(), Module::kErrored); CHECK(try_catch.HasCaught()); } @@ -24074,7 +24131,13 @@ TEST(CodeCacheModuleScriptMismatch) { // Evaluate for possible lazy compilation. Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } // Now create the cache. Note that it is freed, obscurely, when // ScriptCompiler::Source goes out of scope below. @@ -24170,7 +24233,13 @@ TEST(CodeCacheScriptModuleMismatch) { Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } isolate->Dispose(); } @@ -24206,10 +24275,14 @@ TEST(InvalidCodeCacheDataInCompileModule) { .ToChecked(); CHECK(cached_data->rejected); - CHECK_EQ(42, module->Evaluate(context) - .ToLocalChecked() - ->Int32Value(context) - .FromJust()); + Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) { @@ -24403,280 +24476,6 @@ TEST(SealHandleScopeNested) { } } - -static void ExtrasBindingTestRuntimeFunction( - const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ( - 3, - args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust()); - args.GetReturnValue().Set(v8_num(7)); -} - -TEST(ExtrasFunctionSource) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - LocalContext env; - - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - // Functions defined in extras do not expose source code. - auto func = binding->Get(env.local(), v8_str("testFunctionToString")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::String>(); - CHECK(result->StrictEquals(v8_str("function foo() { [native code] }"))); - - // Functions defined in extras do not show up in the stack trace. - auto wrapper = binding->Get(env.local(), v8_str("testStackTrace")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("wrapper"), wrapper).FromJust()); - ExpectString( - "function f(x) { return wrapper(x) }" - "function g() { return new Error().stack; }" - "f(g)", - "Error\n" - " at g (<anonymous>:1:58)\n" - " at f (<anonymous>:1:24)\n" - " at <anonymous>:1:78"); -} - -TEST(ExtrasBindingObject) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - LocalContext env; - - // standalone.gypi ensures we include the test-extra.js file, which should - // export the tested functions. - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testExtraShouldReturnFive")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Number>(); - CHECK_EQ(5, result->Int32Value(env.local()).FromJust()); - - v8::Local<v8::FunctionTemplate> runtimeFunction = - v8::FunctionTemplate::New(isolate, ExtrasBindingTestRuntimeFunction); - binding->Set(env.local(), v8_str("runtime"), - runtimeFunction->GetFunction(env.local()).ToLocalChecked()) - .FromJust(); - func = binding->Get(env.local(), v8_str("testExtraShouldCallToRuntime")) - .ToLocalChecked() - .As<v8::Function>(); - result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Number>(); - CHECK_EQ(7, result->Int32Value(env.local()).FromJust()); -} - - -TEST(ExtrasCreatePromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testCreatePromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto promise = CompileRun( - "%PrepareFunctionForOptimization(func);\n" - "func();\n" - "func();\n" - "%OptimizeFunctionOnNextCall(func);\n" - "func()\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, promise->State()); -} - -TEST(ExtrasCreatePromiseWithParent) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testCreatePromiseWithParent")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto promise = CompileRun( - "var parent = new Promise((a, b) => {});\n" - "%PrepareFunctionForOptimization(func);\n" - "func(parent);\n" - "func(parent);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "func(parent)\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, promise->State()); -} - -TEST(ExtrasRejectPromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testRejectPromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto rejected_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), 1);\n" - "func(newPromise(), 1);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, 1);\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kRejected, rejected_promise->State()); - CHECK_EQ(1, rejected_promise->Result()->Int32Value(env.local()).FromJust()); -} - -TEST(ExtrasResolvePromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testResolvePromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto pending_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), newPromise());\n" - "func(newPromise(), newPromise());\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, newPromise());\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, pending_promise->State()); - - auto fulfilled_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), 1);\n" - "func(newPromise(), 1);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, 1);\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kFulfilled, fulfilled_promise->State()); - CHECK_EQ(1, fulfilled_promise->Result()->Int32Value(env.local()).FromJust()); -} - -TEST(ExtrasUtilsObject) { - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testExtraCanUseUtils")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Object>(); - - auto private_symbol = result->Get(env.local(), v8_str("privateSymbol")) - .ToLocalChecked() - .As<v8::Symbol>(); - i::Handle<i::Symbol> ips = v8::Utils::OpenHandle(*private_symbol); - CHECK(ips->IsPrivate()); - - CompileRun("var result = 0; function store(x) { result = x; }"); - auto store = CompileRun("store").As<v8::Function>(); - - auto fulfilled_promise = result->Get(env.local(), v8_str("fulfilledPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - fulfilled_promise->Then(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(1, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto fulfilled_promise_2 = - result->Get(env.local(), v8_str("fulfilledPromise2")) - .ToLocalChecked() - .As<v8::Promise>(); - fulfilled_promise_2->Then(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(2, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto rejected_promise = result->Get(env.local(), v8_str("rejectedPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - rejected_promise->Catch(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(3, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto rejected_but_handled_promise = - result->Get(env.local(), v8_str("rejectedButHandledPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - CHECK(rejected_but_handled_promise->HasHandler()); - - auto promise_states = result->Get(env.local(), v8_str("promiseStates")) - .ToLocalChecked() - .As<v8::String>(); - String::Utf8Value promise_states_string(isolate, promise_states); - CHECK_EQ(0, strcmp(*promise_states_string, "pending fulfilled rejected")); - - auto promise_is_promise = result->Get(env.local(), v8_str("promiseIsPromise")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(true, promise_is_promise->Value()); - - auto thenable_is_promise = - result->Get(env.local(), v8_str("thenableIsPromise")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(false, thenable_is_promise->Value()); - - auto uncurry_this = result->Get(env.local(), v8_str("uncurryThis")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(true, uncurry_this->Value()); -} - - TEST(Map) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); @@ -25854,7 +25653,14 @@ TEST(ImportMeta) { module->InstantiateModule(context.local(), UnexpectedModuleResolveCallback) .ToChecked(); Local<Value> result = module->Evaluate(context.local()).ToLocalChecked(); - CHECK(result->StrictEquals(Local<v8::Value>::Cast(v8::Utils::ToLocal(meta)))); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(result)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK( + result->StrictEquals(Local<v8::Value>::Cast(v8::Utils::ToLocal(meta)))); + } } TEST(GetModuleNamespace) { @@ -26180,7 +25986,7 @@ void AtomicsWaitCallbackForTesting( wake_handle->Wake(); break; case AtomicsWaitCallbackAction::StopFromThreadAndThrow: - info->stop_thread = v8::base::make_unique<StopAtomicsWaitThread>(info); + info->stop_thread = std::make_unique<StopAtomicsWaitThread>(info); CHECK(info->stop_thread->Start()); break; case AtomicsWaitCallbackAction::KeepWaiting: diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index c96a0199bb..bae39ba2ad 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -3391,7 +3391,9 @@ TEST(ARMv8_vminmax_f32) { template <typename T, typename Inputs, typename Results> static GeneratedCode<F_ppiii> GenerateMacroFloatMinMax( - MacroAssembler& assm) { // NOLINT(runtime/references) + MacroAssembler* assm_ptr) { + MacroAssembler& assm = *assm_ptr; + T a = T::from_code(0); // d0/s0 T b = T::from_code(1); // d1/s1 T c = T::from_code(2); // d2/s2 @@ -3509,7 +3511,7 @@ TEST(macro_float_minmax_f64) { double max_aba_; }; - auto f = GenerateMacroFloatMinMax<DwVfpRegister, Inputs, Results>(assm); + auto f = GenerateMacroFloatMinMax<DwVfpRegister, Inputs, Results>(&assm); #define CHECK_MINMAX(left, right, min, max) \ do { \ @@ -3574,7 +3576,7 @@ TEST(macro_float_minmax_f32) { float max_aba_; }; - auto f = GenerateMacroFloatMinMax<SwVfpRegister, Inputs, Results>(assm); + auto f = GenerateMacroFloatMinMax<SwVfpRegister, Inputs, Results>(&assm); #define CHECK_MINMAX(left, right, min, max) \ do { \ diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc index 4fdf30ef64..44ee286587 100644 --- a/deps/v8/test/cctest/test-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-assembler-arm64.cc @@ -2019,17 +2019,19 @@ TEST(far_branch_backward) { START(); Label done, fail; - Label near, far, in_range, out_of_range; + // Avoid using near and far as variable name because both are defined as + // macro in minwindef.h from Windows SDK. + Label near_label, far_label, in_range, out_of_range; __ Mov(x0, 0); __ Mov(x1, 1); __ Mov(x10, 0); - __ B(&near); + __ B(&near_label); __ Bind(&in_range); __ Orr(x0, x0, 1 << 0); - __ B(&far); + __ B(&far_label); __ Bind(&out_of_range); __ Orr(x0, x0, 1 << 1); @@ -2053,19 +2055,19 @@ TEST(far_branch_backward) { // close to the limit. GenerateLandingNops(&masm, budget - kSlack, &fail); - __ Bind(&near); + __ Bind(&near_label); switch (type) { case TestBranchType: __ Tbz(x10, 3, &in_range); // This should be: // TBZ <in_range> - CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; case CompareBranchType: __ Cbz(x10, &in_range); // This should be: // CBZ <in_range> - CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; case CondBranchType: __ Cmp(x10, 0); @@ -2073,7 +2075,7 @@ TEST(far_branch_backward) { // This should be: // CMP // B.EQ <in_range> - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; default: UNREACHABLE(); @@ -2083,7 +2085,7 @@ TEST(far_branch_backward) { // Now go past the limit so that branches are now out of range. GenerateLandingNops(&masm, kSlack * 2, &fail); - __ Bind(&far); + __ Bind(&far_label); switch (type) { case TestBranchType: __ Tbz(x10, 5, &out_of_range); @@ -2091,7 +2093,7 @@ TEST(far_branch_backward) { // TBNZ <skip> // B <out_of_range> // skip: - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; case CompareBranchType: __ Cbz(x10, &out_of_range); @@ -2099,7 +2101,7 @@ TEST(far_branch_backward) { // CBNZ <skip> // B <out_of_range> // skip: - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; case CondBranchType: __ Cmp(x10, 0); @@ -2109,7 +2111,7 @@ TEST(far_branch_backward) { // B.NE <skip> // B <out_of_range> // skip: - CHECK_EQ(3 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(3 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; default: UNREACHABLE(); diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index 1cc1aa3213..dd0c056369 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -3206,7 +3206,7 @@ TEST(jump_tables3) { Handle<Object> values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { double value = isolate->random_number_generator()->NextDouble(); - values[i] = isolate->factory()->NewHeapNumber(value, AllocationType::kOld); + values[i] = isolate->factory()->NewHeapNumber<AllocationType::kOld>(value); } Label labels[kNumCases]; Object obj; @@ -4825,9 +4825,10 @@ TEST(r6_beqzc) { } } -void load_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - const uint64_t elements[], MSARegister w, Register t0, Register t1) { +void load_elements_of_vector(MacroAssembler* assm_ptr, + const uint64_t elements[], MSARegister w, + Register t0, Register t1) { + MacroAssembler& assm = *assm_ptr; __ li(t0, static_cast<uint32_t>(elements[0] & 0xFFFFFFFF)); __ li(t1, static_cast<uint32_t>((elements[0] >> 32) & 0xFFFFFFFF)); __ insert_w(w, 0, t0); @@ -4838,9 +4839,9 @@ void load_elements_of_vector( __ insert_w(w, 3, t1); } -inline void store_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - MSARegister w, Register a) { +inline void store_elements_of_vector(MacroAssembler* assm_ptr, MSARegister w, + Register a) { + MacroAssembler& assm = *assm_ptr; __ st_d(w, MemOperand(a, 0)); } @@ -4876,15 +4877,15 @@ void run_bz_bnz(TestCaseMsaBranch* input, Branch GenerateBranch, msa_reg_t res; Label do_not_move_w0_to_w2; - load_elements_of_vector(assm, &t.ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t.wd_lo, w2, t0, t1); - load_elements_of_vector(assm, &input->wt_lo, w1, t0, t1); + load_elements_of_vector(&assm, &t.ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t.wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &input->wt_lo, w1, t0, t1); GenerateBranch(assm, do_not_move_w0_to_w2); __ nop(); __ move_v(w2, w0); __ bind(&do_not_move_w0_to_w2); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -5841,7 +5842,7 @@ void run_msa_insert(int32_t rs_value, int n, msa_reg_t* w) { UNREACHABLE(); } - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -5937,10 +5938,10 @@ TEST(MSA_move_v) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); __ move_v(w2, w0); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -5981,10 +5982,10 @@ void run_msa_sldi(OperFunc GenerateOperation, for (unsigned i = 0; i < arraysize(t); ++i) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); GenerateOperation(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6175,7 +6176,7 @@ void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi, UNREACHABLE(); } - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6460,11 +6461,11 @@ void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext, int32_t i5 = i5_sign_ext ? static_cast<int32_t>(input->i5 << 27) >> 27 : input->i5; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); GenerateI5InstructionFunc(assm, i5); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6880,10 +6881,10 @@ void run_msa_2r(const struct TestCaseMsa2R* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, reinterpret_cast<const uint64_t*>(input), w0, + load_elements_of_vector(&assm, reinterpret_cast<const uint64_t*>(input), w0, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7926,13 +7927,13 @@ void run_msa_vector(struct TestCaseMsaVector* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wt_lo), w2, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w4, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w4, t0, t1); GenerateVectorInstructionFunc(assm); - store_elements_of_vector(assm, w4, a0); + store_elements_of_vector(&assm, w4, a0); __ jr(ra); __ nop(); @@ -8014,12 +8015,12 @@ void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateInstructionFunc(assm, input->m); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -8491,7 +8492,7 @@ void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc, GenerateVectorInstructionFunc(assm, input); - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -8640,13 +8641,13 @@ void run_msa_3r(struct TestCaseMsa3R* input, InstFunc GenerateI5InstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->wt_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->ws_lo), w1, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w1, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateI5InstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -9645,13 +9646,13 @@ void run_msa_3rf(const struct TestCaseMsa3RF* input, msa_reg_t res; load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc index f337fdfcac..35e81cb46f 100644 --- a/deps/v8/test/cctest/test-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-assembler-mips64.cc @@ -3330,7 +3330,7 @@ TEST(jump_tables3) { Handle<Object> values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { double value = isolate->random_number_generator()->NextDouble(); - values[i] = isolate->factory()->NewHeapNumber(value, AllocationType::kOld); + values[i] = isolate->factory()->NewHeapNumber<AllocationType::kOld>(value); } Label labels[kNumCases]; Object obj; @@ -5430,9 +5430,10 @@ TEST(r6_beqzc) { } } -void load_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - const uint64_t elements[], MSARegister w, Register t0, Register t1) { +void load_elements_of_vector(MacroAssembler* assm_ptr, + const uint64_t elements[], MSARegister w, + Register t0, Register t1) { + MacroAssembler& assm = *assm_ptr; __ li(t0, static_cast<uint32_t>(elements[0] & 0xFFFFFFFF)); __ li(t1, static_cast<uint32_t>((elements[0] >> 32) & 0xFFFFFFFF)); __ insert_w(w, 0, t0); @@ -5443,9 +5444,9 @@ void load_elements_of_vector( __ insert_w(w, 3, t1); } -inline void store_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - MSARegister w, Register a) { +inline void store_elements_of_vector(MacroAssembler* assm_ptr, MSARegister w, + Register a) { + MacroAssembler& assm = *assm_ptr; __ st_d(w, MemOperand(a, 0)); } @@ -5481,15 +5482,15 @@ void run_bz_bnz(TestCaseMsaBranch* input, Branch GenerateBranch, msa_reg_t res; Label do_not_move_w0_to_w2; - load_elements_of_vector(assm, &t.ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t.wd_lo, w2, t0, t1); - load_elements_of_vector(assm, &input->wt_lo, w1, t0, t1); + load_elements_of_vector(&assm, &t.ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t.wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &input->wt_lo, w1, t0, t1); GenerateBranch(assm, do_not_move_w0_to_w2); __ nop(); __ move_v(w2, w0); __ bind(&do_not_move_w0_to_w2); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6799,7 +6800,7 @@ void run_msa_insert(int64_t rs_value, int n, msa_reg_t* w) { UNREACHABLE(); } - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -6953,10 +6954,10 @@ TEST(MSA_move_v) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); __ move_v(w2, w0); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6997,10 +6998,10 @@ void run_msa_sldi(OperFunc GenerateOperation, for (unsigned i = 0; i < arraysize(t); ++i) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); GenerateOperation(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7157,7 +7158,7 @@ void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi, UNREACHABLE(); } - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7358,11 +7359,11 @@ void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext, int32_t i5 = i5_sign_ext ? static_cast<int32_t>(input->i5 << 27) >> 27 : input->i5; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); GenerateI5InstructionFunc(assm, i5); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7784,10 +7785,10 @@ void run_msa_2r(const struct TestCaseMsa2R* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, reinterpret_cast<const uint64_t*>(input), w0, + load_elements_of_vector(&assm, reinterpret_cast<const uint64_t*>(input), w0, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -8830,13 +8831,13 @@ void run_msa_vector(struct TestCaseMsaVector* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wt_lo), w2, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w4, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w4, t0, t1); GenerateVectorInstructionFunc(assm); - store_elements_of_vector(assm, w4, a0); + store_elements_of_vector(&assm, w4, a0); __ jr(ra); __ nop(); @@ -8918,12 +8919,12 @@ void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateInstructionFunc(assm, input->m); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -9395,7 +9396,7 @@ void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc, GenerateVectorInstructionFunc(assm, input); - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -9544,13 +9545,13 @@ void run_msa_3r(struct TestCaseMsa3R* input, InstFunc GenerateI5InstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->wt_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->ws_lo), w1, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w1, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateI5InstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -10548,13 +10549,13 @@ void run_msa_3rf(const struct TestCaseMsa3RF* input, msa_reg_t res; load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); diff --git a/deps/v8/test/cctest/test-backing-store.cc b/deps/v8/test/cctest/test-backing-store.cc new file mode 100644 index 0000000000..f8010d3031 --- /dev/null +++ b/deps/v8/test/cctest/test-backing-store.cc @@ -0,0 +1,85 @@ +// Copyright 2019 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. + +#include "src/api/api-inl.h" +#include "src/objects/backing-store.h" +#include "src/wasm/wasm-objects.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/manually-externalized-buffer.h" + +namespace v8 { +namespace internal { + +using testing::ManuallyExternalizedBuffer; + +TEST(Run_WasmModule_Buffer_Externalized_Detach) { + { + // Regression test for + // https://bugs.chromium.org/p/chromium/issues/detail?id=731046 + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + MaybeHandle<JSArrayBuffer> result = + isolate->factory()->NewJSArrayBufferAndBackingStore( + wasm::kWasmPageSize, InitializedFlag::kZeroInitialized); + Handle<JSArrayBuffer> buffer = result.ToHandleChecked(); + + // Embedder requests contents. + ManuallyExternalizedBuffer external(buffer); + + buffer->Detach(); + CHECK(buffer->was_detached()); + + // Make sure we can write to the buffer without crashing + uint32_t* int_buffer = + reinterpret_cast<uint32_t*>(external.backing_store()); + int_buffer[0] = 0; + // Embedder frees contents. + } + CcTest::CollectAllAvailableGarbage(); +} + +TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) { + { + // Regression test for https://crbug.com/813876 + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + MaybeHandle<WasmMemoryObject> result = + WasmMemoryObject::New(isolate, 1, 1, SharedFlag::kNotShared); + Handle<WasmMemoryObject> memory_object = result.ToHandleChecked(); + Handle<JSArrayBuffer> buffer(memory_object->array_buffer(), isolate); + + { + // Embedder requests contents. + ManuallyExternalizedBuffer external(buffer); + + // Growing (even by 0) detaches the old buffer. + WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK(buffer->was_detached()); + + // Embedder frees contents. + } + + // Make sure the memory object has a new buffer that can be written to. + uint32_t* int_buffer = reinterpret_cast<uint32_t*>( + memory_object->array_buffer().backing_store()); + int_buffer[0] = 0; + } + CcTest::CollectAllAvailableGarbage(); +} + +#if V8_TARGET_ARCH_64_BIT +TEST(BackingStore_Reclaim) { + // Make sure we can allocate memories without running out of address space. + Isolate* isolate = CcTest::InitIsolateOnce(); + for (int i = 0; i < 256; ++i) { + auto backing_store = + BackingStore::AllocateWasmMemory(isolate, 1, 1, SharedFlag::kNotShared); + CHECK(backing_store); + } +} +#endif + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc index 3a4f11e126..45512eaf56 100644 --- a/deps/v8/test/cctest/test-code-stub-assembler.cc +++ b/deps/v8/test/cctest/test-code-stub-assembler.cc @@ -123,6 +123,62 @@ TEST(CallCFunctionWithCallerSavedRegisters) { CHECK_EQ(3, Handle<Smi>::cast(result)->value()); } +TEST(NumberToString) { + Isolate* isolate(CcTest::InitIsolateOnce()); + Factory* factory = isolate->factory(); + + const int kNumParams = 1; + CodeAssemblerTester asm_tester(isolate, kNumParams); + CodeStubAssembler m(asm_tester.state()); + + { + TNode<Number> input = m.CAST(m.Parameter(0)); + + Label bailout(&m); + m.Return(m.NumberToString(input, &bailout)); + + m.BIND(&bailout); + m.Return(m.UndefinedConstant()); + } + + FunctionTester ft(asm_tester.GenerateCode(), kNumParams); + + // clang-format off + double inputs[] = { + 1, 2, 42, 153, -1, -100, 0, 51095154, -1241950, + std::nan("-1"), std::nan("1"), std::nan("2"), + -std::numeric_limits<double>::infinity(), + std::numeric_limits<double>::infinity(), + -0.0, -0.001, -0.5, -0.999, -1.0, + 0.0, 0.001, 0.5, 0.999, 1.0, + -2147483647.9, -2147483648.0, -2147483648.5, -2147483648.9, // SmiMin. + 2147483646.9, 2147483647.0, 2147483647.5, 2147483647.9, // SmiMax. + -4294967295.9, -4294967296.0, -4294967296.5, -4294967297.0, // - 2^32. + 4294967295.9, 4294967296.0, 4294967296.5, 4294967297.0, // 2^32. + }; + // clang-format on + + const int kFullCacheSize = isolate->heap()->MaxNumberToStringCacheSize(); + const int test_count = arraysize(inputs); + for (int i = 0; i < test_count; i++) { + int cache_length_before_addition = factory->number_string_cache()->length(); + Handle<Object> input = factory->NewNumber(inputs[i]); + Handle<String> expected = factory->NumberToString(input); + + Handle<Object> result = ft.Call(input).ToHandleChecked(); + if (result->IsUndefined(isolate)) { + // Query may fail if cache was resized, in which case the entry is not + // added to the cache. + CHECK_LT(cache_length_before_addition, kFullCacheSize); + CHECK_EQ(factory->number_string_cache()->length(), kFullCacheSize); + expected = factory->NumberToString(input); + result = ft.Call(input).ToHandleChecked(); + } + CHECK(!result->IsUndefined(isolate)); + CHECK_EQ(*expected, *result); + } +} + namespace { void CheckToUint32Result(uint32_t expected, Handle<Object> result) { @@ -439,7 +495,7 @@ TEST(TryToName) { Label if_keyisindex(&m), if_keyisunique(&m), if_bailout(&m); { TYPED_VARIABLE_DEF(IntPtrT, var_index, &m); - TYPED_VARIABLE_DEF(Object, var_unique, &m); + TYPED_VARIABLE_DEF(Name, var_unique, &m); m.TryToName(key, &if_keyisindex, &var_index, &if_keyisunique, &var_unique, &if_bailout); @@ -1568,8 +1624,8 @@ TEST(TryLookupElement) { v8::ArrayBuffer::Contents contents = buffer->Externalize(); buffer->Detach(); - isolate->array_buffer_allocator()->Free(contents.Data(), - contents.ByteLength()); + contents.Deleter()(contents.Data(), contents.ByteLength(), + contents.DeleterData()); CHECK_ABSENT(object, 0); CHECK_ABSENT(object, 1); @@ -1809,7 +1865,7 @@ TEST(OneToTwoByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1841,7 +1897,7 @@ TEST(OneToOneByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1873,7 +1929,7 @@ TEST(OneToOneByteStringCopyNonZeroStart) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(3), m.IntPtrConstant(2), @@ -1902,7 +1958,7 @@ TEST(TwoToTwoByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1941,12 +1997,9 @@ TEST(Arguments) { CodeStubArguments arguments(&m, m.IntPtrConstant(3)); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(0), m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(1), m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(2), m.SmiConstant(Smi::FromInt(14)))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(0), m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(1), m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(2), m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -1966,21 +2019,14 @@ TEST(ArgumentsWithSmiConstantIndices) { CodeAssemblerTester asm_tester(isolate, kNumParams); CodeStubAssembler m(asm_tester.state()); - CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr, - CodeStubAssembler::SMI_PARAMETERS); - - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(0), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(1), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(2), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(14)))); + CodeStubArguments arguments(&m, m.SmiConstant(3)); + + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(0)), + m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(1)), + m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(2)), + m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -2019,21 +2065,14 @@ TEST(ArgumentsWithSmiIndices) { CodeAssemblerTester asm_tester(isolate, kNumParams); CodeStubAssembler m(asm_tester.state()); - CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr, - CodeStubAssembler::SMI_PARAMETERS); - - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 0), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 1), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 2), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(14)))); + CodeStubArguments arguments(&m, m.SmiConstant(3)); + + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 0)), + m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 1)), + m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 2)), + m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -2060,7 +2099,7 @@ TEST(ArgumentsForEach) { sum = m.SmiConstant(0); - arguments.ForEach(list, [&m, &sum](Node* arg) { + arguments.ForEach(list, [&](TNode<Object> arg) { sum = m.SmiAdd(sum.value(), m.CAST(arg)); }); @@ -2130,8 +2169,8 @@ class AppendJSArrayCodeStubAssembler : public CodeStubAssembler { TVariable<IntPtrT> arg_index(this); Label bailout(this); arg_index = IntPtrConstant(0); - Node* length = BuildAppendJSArray(kind_, HeapConstant(array), &args, - &arg_index, &bailout); + TNode<Smi> length = BuildAppendJSArray(kind_, HeapConstant(array), &args, + &arg_index, &bailout); Return(length); BIND(&bailout); @@ -2281,7 +2320,7 @@ TEST(AllocateAndInitJSPromise) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = m.AllocateAndInitJSPromise(context); + TNode<JSPromise> const promise = m.AllocateAndInitJSPromise(m.CAST(context)); m.Return(promise); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2298,8 +2337,8 @@ TEST(AllocateAndSetJSPromise) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = m.AllocateAndSetJSPromise( - context, v8::Promise::kRejected, m.SmiConstant(1)); + TNode<JSPromise> const promise = m.AllocateAndSetJSPromise( + m.CAST(context), v8::Promise::kRejected, m.SmiConstant(1)); m.Return(promise); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2361,8 +2400,8 @@ TEST(PromiseHasHandler) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); + TNode<JSPromise> const promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); m.Return(m.SelectBooleanConstant(m.PromiseHasHandler(promise))); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2380,10 +2419,11 @@ TEST(CreatePromiseResolvingFunctionsContext) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); - Node* const promise_context = m.CreatePromiseResolvingFunctionsContext( - promise, m.BooleanConstant(false), native_context); + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); + TNode<Context> const promise_context = + m.CreatePromiseResolvingFunctionsContext( + promise, m.BooleanConstant(false), native_context); m.Return(promise_context); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2408,8 +2448,8 @@ TEST(CreatePromiseResolvingFunctions) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); Node *resolve, *reject; std::tie(resolve, reject) = m.CreatePromiseResolvingFunctions( promise, m.BooleanConstant(false), native_context); @@ -2498,17 +2538,17 @@ TEST(AllocateFunctionWithMapAndContext) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); - Node* promise_context = m.CreatePromiseResolvingFunctionsContext( + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); + TNode<Context> promise_context = m.CreatePromiseResolvingFunctionsContext( promise, m.BooleanConstant(false), native_context); TNode<Object> resolve_info = m.LoadContextElement( native_context, Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX); TNode<Object> const map = m.LoadContextElement( native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - Node* const resolve = - m.AllocateFunctionWithMapAndContext(map, resolve_info, promise_context); + TNode<JSFunction> const resolve = m.AllocateFunctionWithMapAndContext( + m.CAST(map), m.CAST(resolve_info), promise_context); m.Return(resolve); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3122,7 +3162,7 @@ TEST(CloneEmptyFixedArray) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3139,7 +3179,7 @@ TEST(CloneFixedArray) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3161,7 +3201,7 @@ TEST(CloneFixedArrayCOW) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3542,37 +3582,6 @@ TEST(TestCallBuiltinIndirectLoad) { Handle<String>::cast(result.ToHandleChecked()))); } -TEST(TestGotoIfDebugExecutionModeChecksSideEffects) { - Isolate* isolate(CcTest::InitIsolateOnce()); - CodeAssemblerTester asm_tester(isolate, 0); - { - CodeStubAssembler m(asm_tester.state()); - Label is_true(&m), is_false(&m); - m.GotoIfDebugExecutionModeChecksSideEffects(&is_true); - m.Goto(&is_false); - m.BIND(&is_false); - m.Return(m.BooleanConstant(false)); - - m.BIND(&is_true); - m.Return(m.BooleanConstant(true)); - } - - FunctionTester ft(asm_tester.GenerateCode(), 0); - - CHECK(isolate->debug_execution_mode() != DebugInfo::kSideEffects); - - Handle<Object> result = ft.Call().ToHandleChecked(); - CHECK(result->IsBoolean()); - CHECK_EQ(false, result->BooleanValue(isolate)); - - isolate->debug()->StartSideEffectCheckMode(); - CHECK(isolate->debug_execution_mode() == DebugInfo::kSideEffects); - - result = ft.Call().ToHandleChecked(); - CHECK(result->IsBoolean()); - CHECK_EQ(true, result->BooleanValue(isolate)); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index b961da9437..bd2766518b 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -907,7 +907,7 @@ TEST(DeepEagerCompilationPeakMemory) { " }" "}"); v8::ScriptCompiler::Source script_source(source); - CcTest::i_isolate()->compilation_cache()->Disable(); + CcTest::i_isolate()->compilation_cache()->DisableScriptAndEval(); v8::HeapStatistics heap_statistics; CcTest::isolate()->GetHeapStatistics(&heap_statistics); diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index 6d0ee0e512..c0d43b21a1 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -54,8 +54,8 @@ #include "src/tracing/trace-event.h" #ifdef V8_USE_PERFETTO -#include "perfetto/trace/chrome/chrome_trace_event.pb.h" -#include "perfetto/trace/trace.pb.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #endif namespace v8 { diff --git a/deps/v8/test/cctest/test-debug-helper.cc b/deps/v8/test/cctest/test-debug-helper.cc index 67236e5a31..560db1b0d2 100644 --- a/deps/v8/test/cctest/test-debug-helper.cc +++ b/deps/v8/test/cctest/test-debug-helper.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "src/api/api-inl.h" +#include "src/flags/flags.h" #include "src/heap/spaces.h" #include "test/cctest/cctest.h" #include "tools/debug_helper/debug-helper.h" @@ -61,6 +62,10 @@ void CheckProp(const d::ObjectProperty& property, const char* expected_type, CHECK(*reinterpret_cast<TValue*>(property.address) == expected_value); } +bool StartsWith(std::string full_string, std::string prefix) { + return full_string.substr(0, prefix.size()) == prefix; +} + } // namespace TEST(GetObjectProperties) { @@ -68,12 +73,13 @@ TEST(GetObjectProperties) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext context; - d::Roots roots{0, 0, 0, 0}; // We don't know the heap roots. + // Claim we don't know anything about the heap layout. + d::HeapAddresses heap_addresses{0, 0, 0, 0}; v8::Local<v8::Value> v = CompileRun("42"); Handle<Object> o = v8::Utils::OpenHandle(*v); d::ObjectPropertiesResultPtr props = - d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kSmi); CHECK(props->brief == std::string("42 (0x2a)")); CHECK(props->type == std::string("v8::internal::Smi")); @@ -81,7 +87,7 @@ TEST(GetObjectProperties) { v = CompileRun("[\"a\", \"bc\"]"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::JSArray")); CHECK_EQ(props->num_properties, 4); @@ -92,9 +98,9 @@ TEST(GetObjectProperties) { CheckProp(*props->properties[3], "v8::internal::Object", "length", static_cast<i::Tagged_t>(IntToSmi(2))); - // We need to supply a root address for decompression before reading the + // We need to supply some valid address for decompression before reading the // elements from the JSArray. - roots.any_heap_pointer = o->ptr(); + heap_addresses.any_heap_pointer = o->ptr(); i::Tagged_t properties_or_hash = *reinterpret_cast<i::Tagged_t*>(props->properties[1]->address); @@ -106,32 +112,39 @@ TEST(GetObjectProperties) { // any ability to read memory. { MemoryFailureRegion failure(0, UINTPTR_MAX); - props = d::GetObjectProperties(properties_or_hash, &ReadMemory, roots); + props = + d::GetObjectProperties(properties_or_hash, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kObjectPointerValidButInaccessible); CHECK(props->type == std::string("v8::internal::HeapObject")); CHECK_EQ(props->num_properties, 1); CheckProp(*props->properties[0], "v8::internal::Map", "map"); - CHECK(std::string(props->brief).substr(0, 21) == - std::string("maybe EmptyFixedArray")); + // "maybe" prefix indicates that GetObjectProperties recognized the offset + // within the page as matching a known object, but didn't know whether the + // object is on the right page. This response can only happen in builds + // without pointer compression, because otherwise heap addresses would be at + // deterministic locations within the heap reservation. + CHECK(COMPRESS_POINTERS_BOOL + ? StartsWith(props->brief, "EmptyFixedArray") + : StartsWith(props->brief, "maybe EmptyFixedArray")); - // Provide a heap root so the API can be more sure. - roots.read_only_space = + // Provide a heap first page so the API can be more sure. + heap_addresses.read_only_space_first_page = reinterpret_cast<uintptr_t>(reinterpret_cast<i::Isolate*>(isolate) ->heap() ->read_only_space() ->first_page()); - props = d::GetObjectProperties(properties_or_hash, &ReadMemory, roots); + props = + d::GetObjectProperties(properties_or_hash, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kObjectPointerValidButInaccessible); CHECK(props->type == std::string("v8::internal::HeapObject")); CHECK_EQ(props->num_properties, 1); CheckProp(*props->properties[0], "v8::internal::Map", "map"); - CHECK(std::string(props->brief).substr(0, 15) == - std::string("EmptyFixedArray")); + CHECK(StartsWith(props->brief, "EmptyFixedArray")); } - props = d::GetObjectProperties(elements, &ReadMemory, roots); + props = d::GetObjectProperties(elements, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::FixedArray")); CHECK_EQ(props->num_properties, 3); @@ -142,9 +155,10 @@ TEST(GetObjectProperties) { d::PropertyKind::kArrayOfKnownSize, 2); // Get the second string value from the FixedArray. - i::Tagged_t second_string_address = *reinterpret_cast<i::Tagged_t*>( - props->properties[2]->address + sizeof(i::Tagged_t)); - props = d::GetObjectProperties(second_string_address, &ReadMemory, roots); + i::Tagged_t second_string_address = + reinterpret_cast<i::Tagged_t*>(props->properties[2]->address)[1]; + props = d::GetObjectProperties(second_string_address, &ReadMemory, + heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::SeqOneByteString")); CHECK_EQ(props->num_properties, 4); @@ -162,18 +176,38 @@ TEST(GetObjectProperties) { // its properties should match what we read last time. d::ObjectPropertiesResultPtr props2; { + heap_addresses.read_only_space_first_page = 0; uintptr_t map_address = d::GetObjectProperties( *reinterpret_cast<i::Tagged_t*>(props->properties[0]->address), - &ReadMemory, roots) + &ReadMemory, heap_addresses) ->properties[0] ->address; MemoryFailureRegion failure(map_address, map_address + i::Map::kSize); - props2 = d::GetObjectProperties(second_string_address, &ReadMemory, roots, - "v8::internal::String"); - CHECK(props2->type_check_result == d::TypeCheckResult::kUsedTypeHint); - CHECK(props2->type == std::string("v8::internal::String")); - CHECK_EQ(props2->num_properties, 3); + props2 = d::GetObjectProperties(second_string_address, &ReadMemory, + heap_addresses, "v8::internal::String"); + if (COMPRESS_POINTERS_BOOL) { + // The first page of each heap space can be automatically detected when + // pointer compression is active, so we expect to use known maps instead + // of the type hint. + CHECK_EQ(props2->type_check_result, d::TypeCheckResult::kKnownMapPointer); + CHECK(props2->type == std::string("v8::internal::SeqOneByteString")); + CHECK_EQ(props2->num_properties, 4); + CheckProp(*props2->properties[3], "char", "chars", + d::PropertyKind::kArrayOfKnownSize, 2); + CHECK_EQ(props2->num_guessed_types, 0); + } else { + CHECK_EQ(props2->type_check_result, d::TypeCheckResult::kUsedTypeHint); + CHECK(props2->type == std::string("v8::internal::String")); + CHECK_EQ(props2->num_properties, 3); + + // The type hint we provided was the abstract class String, but + // GetObjectProperties should have recognized that the Map pointer looked + // like the right value for a SeqOneByteString. + CHECK_EQ(props2->num_guessed_types, 1); + CHECK(std::string(props2->guessed_types[0]) == + std::string("v8::internal::SeqOneByteString")); + } CheckProp(*props2->properties[0], "v8::internal::Map", "map", *reinterpret_cast<i::Tagged_t*>(props->properties[0]->address)); CheckProp(*props2->properties[1], "uint32_t", "hash_field", @@ -183,7 +217,7 @@ TEST(GetObjectProperties) { // Try a weak reference. props2 = d::GetObjectProperties(second_string_address | kWeakHeapObjectMask, - &ReadMemory, roots); + &ReadMemory, heap_addresses); std::string weak_ref_prefix = "weak ref to "; CHECK(weak_ref_prefix + props->brief == props2->brief); CHECK(props2->type_check_result == d::TypeCheckResult::kUsedMap); @@ -201,9 +235,8 @@ TEST(GetObjectProperties) { const alphabet = "abcdefghijklmnopqrstuvwxyz"; alphabet.substr(3,20) + alphabet.toUpperCase().substr(5,15) + "7")"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); - CHECK(std::string(props->brief).substr(0, 38) == - std::string("\"defghijklmnopqrstuvwFGHIJKLMNOPQRST7\"")); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); + CHECK(StartsWith(props->brief, "\"defghijklmnopqrstuvwFGHIJKLMNOPQRST7\"")); // Cause a failure when reading the "second" pointer within the top-level // ConsString. @@ -211,15 +244,15 @@ TEST(GetObjectProperties) { CheckProp(*props->properties[4], "v8::internal::String", "second"); uintptr_t second_address = props->properties[4]->address; MemoryFailureRegion failure(second_address, second_address + 4); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); - CHECK(std::string(props->brief).substr(0, 40) == - std::string("\"defghijklmnopqrstuvwFGHIJKLMNOPQRST...\"")); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); + CHECK( + StartsWith(props->brief, "\"defghijklmnopqrstuvwFGHIJKLMNOPQRST...\"")); } // Build a very long string. v = CompileRun("'a'.repeat(1000)"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(std::string(props->brief).substr(79, 7) == std::string("aa...\" ")); } diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 4ad55ef6b5..c76f922d86 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -893,7 +893,6 @@ TEST(BreakPointInlineBoundBuiltin) { TEST(BreakPointInlinedConstructorBuiltin) { i::FLAG_allow_natives_syntax = true; - i::FLAG_experimental_inline_promise_constructor = true; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -1032,8 +1031,6 @@ TEST(BreakPointBuiltinNewContext) { i::Handle<i::BreakPoint> bp; // === Test builtin from a new context === -// This does not work with no-snapshot build. -#ifdef V8_USE_SNAPSHOT break_point_hit_count = 0; builtin = CompileRun("String.prototype.repeat").As<v8::Function>(); CompileRun("'a'.repeat(10)"); @@ -1059,7 +1056,6 @@ TEST(BreakPointBuiltinNewContext) { CompileRun("'b'.repeat(10)"); CHECK_EQ(2, break_point_hit_count); } -#endif v8::debug::SetDebugDelegate(env->GetIsolate(), nullptr); CheckDebuggerUnloaded(); @@ -3135,8 +3131,8 @@ TEST(NoBreakWhenBootstrapping) { { // Create a context with an extension to make sure that some JavaScript // code is executed during bootstrapping. - v8::RegisterExtension(v8::base::make_unique<v8::Extension>( - "simpletest", kSimpleExtensionSource)); + v8::RegisterExtension( + std::make_unique<v8::Extension>("simpletest", kSimpleExtensionSource)); const char* extension_names[] = { "simpletest" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::HandleScope handle_scope(isolate); @@ -4510,7 +4506,7 @@ UNINITIALIZED_TEST(LoadedAtStartupScripts) { } } CHECK_EQ(count_by_type[i::Script::TYPE_NATIVE], 0); - CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 2); + CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 1); CHECK_EQ(count_by_type[i::Script::TYPE_NORMAL], 1); CHECK_EQ(count_by_type[i::Script::TYPE_WASM], 0); CHECK_EQ(count_by_type[i::Script::TYPE_INSPECTOR], 0); diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc index 76e06df47e..16dee03f50 100644 --- a/deps/v8/test/cctest/test-disasm-arm.cc +++ b/deps/v8/test/cctest/test-disasm-arm.cc @@ -1166,6 +1166,12 @@ TEST(Neon) { "f2dae550 vshl.i16 q15, q0, #10"); COMPARE(vshl(NeonS32, q15, q0, 17), "f2f1e550 vshl.i32 q15, q0, #17"); + COMPARE(vshl(NeonS8, q15, q0, q1), + "f242e440 vshl.s8 q15, q0, q1"); + COMPARE(vshl(NeonU16, q15, q2, q3), + "f356e444 vshl.u16 q15, q2, q3"); + COMPARE(vshl(NeonS32, q15, q4, q5), + "f26ae448 vshl.s32 q15, q4, q5"); COMPARE(vshr(NeonS8, q15, q0, 6), "f2cae050 vshr.s8 q15, q0, #6"); COMPARE(vshr(NeonU16, q15, q0, 10), diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc index ba4d92d3a2..2b46d7ed11 100644 --- a/deps/v8/test/cctest/test-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-disasm-arm64.cc @@ -1888,6 +1888,8 @@ TEST(system_pauth) { COMPARE(paciasp(), "paciasp"); COMPARE(autia1716(), "autia1716"); COMPARE(autiasp(), "autiasp"); + + CLEANUP(); } TEST_(debug) { diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index 4078bd429c..563d3a87cf 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -435,6 +435,8 @@ TEST(DisasmIa320) { __ maxps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ rcpps(xmm1, xmm0); __ rcpps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ sqrtps(xmm1, xmm0); + __ sqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ rsqrtps(xmm1, xmm0); __ rsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); @@ -444,6 +446,8 @@ TEST(DisasmIa320) { __ cmpltps(xmm5, Operand(ebx, ecx, times_4, 10000)); __ cmpleps(xmm5, xmm1); __ cmpleps(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpunordps(xmm5, xmm1); + __ cmpunordps(xmm5, Operand(ebx, ecx, times_4, 10000)); __ cmpneqps(xmm5, xmm1); __ cmpneqps(xmm5, Operand(ebx, ecx, times_4, 10000)); @@ -467,6 +471,9 @@ TEST(DisasmIa320) { __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000)); __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0); + __ movapd(xmm0, xmm1); + __ movapd(xmm0, Operand(edx, 4)); + __ movd(xmm0, edi); __ movd(xmm0, Operand(ebx, ecx, times_4, 10000)); __ movd(eax, xmm1); @@ -490,6 +497,36 @@ TEST(DisasmIa320) { __ cmpltsd(xmm0, xmm1); __ andpd(xmm0, xmm1); + __ andpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ andnpd(xmm0, xmm1); + __ andnpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ orpd(xmm0, xmm1); + __ orpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ xorpd(xmm0, xmm1); + __ xorpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ addpd(xmm1, xmm0); + __ addpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ subpd(xmm1, xmm0); + __ subpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ mulpd(xmm1, xmm0); + __ mulpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ divpd(xmm1, xmm0); + __ divpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ minpd(xmm1, xmm0); + __ minpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ maxpd(xmm1, xmm0); + __ maxpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + + __ cmpeqpd(xmm5, xmm1); + __ cmpeqpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpltpd(xmm5, xmm1); + __ cmpltpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmplepd(xmm5, xmm1); + __ cmplepd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpunordpd(xmm5, xmm1); + __ cmpunordpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpneqpd(xmm5, xmm1); + __ cmpneqpd(xmm5, Operand(ebx, ecx, times_4, 10000)); __ psllw(xmm0, 17); __ pslld(xmm0, 17); @@ -623,6 +660,8 @@ TEST(DisasmIa320) { __ vandps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vandnps(xmm0, xmm1, xmm2); __ vandnps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vorps(xmm0, xmm1, xmm2); + __ vorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vxorps(xmm0, xmm1, xmm2); __ vxorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vaddps(xmm0, xmm1, xmm2); @@ -639,9 +678,13 @@ TEST(DisasmIa320) { __ vmaxps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vrcpps(xmm1, xmm0); __ vrcpps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vsqrtps(xmm1, xmm0); + __ vsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ vrsqrtps(xmm1, xmm0); __ vrsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ vmovaps(xmm0, xmm1); + __ vmovapd(xmm0, xmm1); + __ vmovapd(xmm0, Operand(ebx, ecx, times_4, 10000)); __ vshufps(xmm0, xmm1, xmm2, 3); __ vshufps(xmm0, xmm1, Operand(edx, 4), 3); __ vhaddps(xmm0, xmm1, xmm2); @@ -653,11 +696,17 @@ TEST(DisasmIa320) { __ vcmpltps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vcmpleps(xmm5, xmm4, xmm1); __ vcmpleps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpunordps(xmm5, xmm4, xmm1); + __ vcmpunordps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vcmpneqps(xmm5, xmm4, xmm1); __ vcmpneqps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vandpd(xmm0, xmm1, xmm2); __ vandpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vandnpd(xmm0, xmm1, xmm2); + __ vandnpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vorpd(xmm0, xmm1, xmm2); + __ vorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vxorpd(xmm0, xmm1, xmm2); __ vxorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vaddpd(xmm0, xmm1, xmm2); @@ -673,10 +722,22 @@ TEST(DisasmIa320) { __ vmaxpd(xmm0, xmm1, xmm2); __ vmaxpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vcmpeqpd(xmm5, xmm4, xmm1); + __ vcmpeqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpltpd(xmm5, xmm4, xmm1); + __ vcmpltpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmplepd(xmm5, xmm4, xmm1); + __ vcmplepd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpunordpd(xmm5, xmm4, xmm1); + __ vcmpunordpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpneqpd(xmm5, xmm4, xmm1); + __ vcmpneqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vpsllw(xmm0, xmm7, 21); __ vpslld(xmm0, xmm7, 21); __ vpsrlw(xmm0, xmm7, 21); __ vpsrld(xmm0, xmm7, 21); + __ vpsrlq(xmm0, xmm7, 21); __ vpsraw(xmm0, xmm7, 21); __ vpsrad(xmm0, xmm7, 21); diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index 08793fba4a..86d98d8daf 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -182,6 +182,8 @@ TEST(DisasmX64) { __ decq(rdx); __ cdq(); + __ repstosq(); + __ nop(); __ idivq(rdx); __ mull(rdx); diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc index 512bf2a9c6..9eb9071d77 100644 --- a/deps/v8/test/cctest/test-field-type-tracking.cc +++ b/deps/v8/test/cctest/test-field-type-tracking.cc @@ -249,21 +249,22 @@ class Expectations { } } - bool Check(DescriptorArray descriptors, int descriptor) const { + bool Check(DescriptorArray descriptors, InternalIndex descriptor) const { PropertyDetails details = descriptors.GetDetails(descriptor); - if (details.kind() != kinds_[descriptor]) return false; - if (details.location() != locations_[descriptor]) return false; - if (details.constness() != constnesses_[descriptor]) return false; + if (details.kind() != kinds_[descriptor.as_int()]) return false; + if (details.location() != locations_[descriptor.as_int()]) return false; + if (details.constness() != constnesses_[descriptor.as_int()]) return false; - PropertyAttributes expected_attributes = attributes_[descriptor]; + PropertyAttributes expected_attributes = attributes_[descriptor.as_int()]; if (details.attributes() != expected_attributes) return false; - Representation expected_representation = representations_[descriptor]; + Representation expected_representation = + representations_[descriptor.as_int()]; if (!details.representation().Equals(expected_representation)) return false; - Object expected_value = *values_[descriptor]; + Object expected_value = *values_[descriptor.as_int()]; if (details.location() == kField) { if (details.kind() == kData) { FieldType type = descriptors.GetFieldType(descriptor); @@ -278,7 +279,7 @@ class Expectations { if (value == expected_value) return true; if (!value.IsAccessorPair()) return false; AccessorPair pair = AccessorPair::cast(value); - return pair.Equals(expected_value, *setter_values_[descriptor]); + return pair.Equals(expected_value, *setter_values_[descriptor.as_int()]); } UNREACHABLE(); } @@ -291,13 +292,12 @@ class Expectations { DescriptorArray descriptors = map.instance_descriptors(); CHECK(expected_nof <= number_of_properties_); - for (int i = 0; i < expected_nof; i++) { + for (InternalIndex i : InternalIndex::Range(expected_nof)) { if (!Check(descriptors, i)) { Print(); #ifdef OBJECT_PRINT descriptors.Print(); #endif - Check(descriptors, i); return false; } } @@ -459,7 +459,7 @@ class Expectations { Handle<Object> getter(pair->getter(), isolate); Handle<Object> setter(pair->setter(), isolate); - int descriptor = + InternalIndex descriptor = map->instance_descriptors().SearchWithCache(isolate, *name, *map); map = Map::TransitionToAccessorProperty(isolate, map, name, descriptor, getter, setter, attributes); @@ -495,8 +495,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) { CHECK(map->is_stable()); CHECK(expectations.Check(*map)); + InternalIndex first(0); Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::None(), none_type); + isolate, map, first, kData, NONE, Representation::None(), none_type); // |map| did not change except marked unstable. CHECK(!map->is_deprecated()); CHECK(!map->is_stable()); @@ -511,12 +512,12 @@ TEST(ReconfigureAccessorToNonExistingDataField) { CHECK(expectations.Check(*new_map)); Handle<Map> new_map2 = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::None(), none_type); + isolate, map, first, kData, NONE, Representation::None(), none_type); CHECK_EQ(*new_map, *new_map2); Handle<Object> value(Smi::kZero, isolate); Handle<Map> prepared_map = Map::PrepareForDataProperty( - isolate, new_map, 0, PropertyConstness::kConst, value); + isolate, new_map, first, PropertyConstness::kConst, value); // None to Smi generalization is trivial, map does not change. CHECK_EQ(*new_map, *prepared_map); @@ -530,7 +531,7 @@ TEST(ReconfigureAccessorToNonExistingDataField) { Factory* factory = isolate->factory(); Handle<JSObject> obj = factory->NewJSObjectFromMap(map); JSObject::MigrateToMap(isolate, obj, prepared_map); - FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, 0); + FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, first); CHECK(obj->RawFastPropertyAt(index).IsUninitialized(isolate)); #ifdef VERIFY_HEAP obj->ObjectVerify(isolate); @@ -565,14 +566,16 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) { Handle<JSObject> obj = Handle<JSObject>::cast(obj_value); CHECK_EQ(1, obj->map().NumberOfOwnDescriptors()); - CHECK(obj->map().instance_descriptors().GetStrongValue(0).IsAccessorPair()); + InternalIndex first(0); + CHECK( + obj->map().instance_descriptors().GetStrongValue(first).IsAccessorPair()); Handle<Object> value(Smi::FromInt(42), isolate); JSObject::SetOwnPropertyIgnoreAttributes(obj, foo_str, value, NONE).Check(); // Check that the property contains |value|. CHECK_EQ(1, obj->map().NumberOfOwnDescriptors()); - FieldIndex index = FieldIndex::ForDescriptor(obj->map(), 0); + FieldIndex index = FieldIndex::ForDescriptor(obj->map(), first); Object the_value = obj->RawFastPropertyAt(index); CHECK(the_value.IsSmi()); CHECK_EQ(42, Smi::ToInt(the_value)); @@ -641,7 +644,7 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, from.representation, from.type); } else { map = expectations.AddDataField(map, NONE, PropertyConstness::kConst, - Representation::Double(), any_type); + Representation::Smi(), any_type); if (i == detach_property_at_index) { detach_point_map = map; } @@ -653,11 +656,11 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, if (is_detached_map) { detach_point_map = Map::ReconfigureProperty( - isolate, detach_point_map, detach_property_at_index, kData, NONE, - Representation::Tagged(), any_type); + isolate, detach_point_map, InternalIndex(detach_property_at_index), + kData, NONE, Representation::Double(), any_type); expectations.SetDataField(detach_property_at_index, PropertyConstness::kConst, - Representation::Tagged(), any_type); + Representation::Double(), any_type); CHECK(map->is_deprecated()); CHECK(expectations.Check(*detach_point_map, detach_point_map->NumberOfOwnDescriptors())); @@ -666,16 +669,17 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index), - isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(property_index)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); CHECK(!code->marked_for_deoptimization()); // Create new maps by generalizing representation of propX field. - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, property_index, kData, NONE, to.representation, to.type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(property_index), + kData, NONE, to.representation, to.type); expectations.SetDataField(property_index, expected.constness, expected.representation, expected.type); @@ -814,7 +818,9 @@ TEST(GeneralizeDoubleFieldToTagged) { TestGeneralizeField( {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace, + !FLAG_unbox_double_fields && FLAG_modify_field_representation_inplace); } TEST(GeneralizeHeapObjectFieldToTagged) { @@ -965,8 +971,9 @@ TEST(GeneralizeFieldWithAccessorProperties) { maps[i] = maps[i - 1]; continue; } - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, i, kData, NONE, Representation::Double(), any_type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(i), kData, NONE, + Representation::Double(), any_type); maps[i] = new_map; expectations.SetDataField(i, PropertyConstness::kMutable, @@ -1053,7 +1060,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeField( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kSplitProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kSplitProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -1061,8 +1069,9 @@ void TestReconfigureDataFieldAttribute_GeneralizeField( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1141,7 +1150,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kSplitProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kSplitProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -1149,8 +1159,9 @@ void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1436,8 +1447,7 @@ struct CheckNormalize { // template <typename TestConfig, typename Checker> static void TestReconfigureProperty_CustomPropertyAfterTargetMap( - TestConfig& config, // NOLINT(runtime/references) - Checker& checker) { // NOLINT(runtime/references) + TestConfig* config, Checker* checker) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -1469,7 +1479,7 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( map1 = expectations1.AddDataField(map1, NONE, constness, representation, any_type); } - map1 = config.AddPropertyAtBranch(1, expectations1, map1); + map1 = config->AddPropertyAtBranch(1, &expectations1, map1); for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { map1 = expectations1.AddDataField(map1, NONE, constness, representation, any_type); @@ -1489,7 +1499,7 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( map2 = expectations2.AddDataField(map2, NONE, constness, representation, any_type); } - map2 = config.AddPropertyAtBranch(2, expectations2, map2); + map2 = config->AddPropertyAtBranch(2, &expectations2, map2); for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { map2 = expectations2.AddDataField(map2, NONE, constness, representation, any_type); @@ -1501,8 +1511,9 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1510,8 +1521,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( CHECK_NE(*map2, *new_map); CHECK(expectations2.Check(*map2)); - config.UpdateExpectations(kCustomPropIndex, expectations1); - checker.Check(isolate, map1, new_map, expectations1); + config->UpdateExpectations(kCustomPropIndex, &expectations1); + checker->Check(isolate, map1, new_map, expectations1); } TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { @@ -1526,18 +1537,14 @@ TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { js_func_ = factory->NewFunctionForTest(factory->empty_string()); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); // Add the same data constant property at both transition tree branches. - return expectations.AddDataConstant(map, NONE, js_func_); + return expectations->AddDataConstant(map, NONE, js_func_); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { // Expectations stay the same. } }; @@ -1545,7 +1552,7 @@ TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { TestConfig config; // Two branches are "compatible" so the |map1| should NOT be deprecated. CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1575,26 +1582,22 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) { factory->NewFunction(sloppy_map, info, isolate->native_context()); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); Handle<JSFunction> js_func = branch_id == 1 ? js_func1_ : js_func2_; - return expectations.AddDataConstant(map, NONE, js_func); + return expectations->AddDataConstant(map, NONE, js_func); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) - expectations.SetDataField(property_index, PropertyConstness::kConst, - Representation::HeapObject(), function_type_); + void UpdateExpectations(int property_index, Expectations* expectations) { + expectations->SetDataField(property_index, PropertyConstness::kConst, + Representation::HeapObject(), function_type_); } }; TestConfig config; CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1612,28 +1615,23 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToAccConstantAfterTargetMap) { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); if (branch_id == 1) { - return expectations.AddDataConstant(map, NONE, js_func_); + return expectations->AddDataConstant(map, NONE, js_func_); } else { - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } } - void UpdateExpectations( - int property_index, - Expectations& expectations // NOLINT(runtime/references) - ) {} + void UpdateExpectations(int property_index, Expectations* expectations) {} }; TestConfig config; // These are completely separate branches in transition tree. CheckUnrelated checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1645,26 +1643,22 @@ TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) { Handle<AccessorPair> pair_; TestConfig() { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); // Add the same accessor constant property at both transition tree // branches. - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { // Two branches are "compatible" so the |map1| should NOT be deprecated. } }; TestConfig config; CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1680,24 +1674,20 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { pair2_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); Handle<AccessorPair> pair = branch_id == 1 ? pair1_ : pair2_; - return expectations.AddAccessorConstant(map, NONE, pair); + return expectations->AddAccessorConstant(map, NONE, pair); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { if (IS_ACCESSOR_FIELD_SUPPORTED) { - expectations.SetAccessorField(property_index); + expectations->SetAccessorField(property_index); } else { // Currently we have a normalize case and ACCESSOR property becomes // ACCESSOR_CONSTANT. - expectations.SetAccessorConstant(property_index, pair2_); + expectations->SetAccessorConstant(property_index, pair2_); } } }; @@ -1705,11 +1695,11 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { TestConfig config; if (IS_ACCESSOR_FIELD_SUPPORTED) { CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } else { // Currently we have a normalize case. CheckNormalize checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } } @@ -1722,31 +1712,26 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) { Handle<AccessorPair> pair_; TestConfig() { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); if (branch_id == 1) { - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } else { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); - return expectations.AddDataField(map, NONE, PropertyConstness::kConst, - Representation::Smi(), any_type); + return expectations->AddDataField(map, NONE, PropertyConstness::kConst, + Representation::Smi(), any_type); } } - void UpdateExpectations( - int property_index, - Expectations& expectations // NOLINT(runtime/references) - ) {} + void UpdateExpectations(int property_index, Expectations* expectations) {} }; TestConfig config; // These are completely separate branches in transition tree. CheckUnrelated checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1811,7 +1796,8 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kDiffProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kDiffProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -2084,8 +2070,9 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { map2 = handle(target, isolate); } - map2 = Map::ReconfigureProperty(isolate, map2, kSplitProp, kData, NONE, - Representation::Double(), any_type); + map2 = Map::ReconfigureProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, Representation::Double(), + any_type); expectations.SetDataField(kSplitProp, PropertyConstness::kMutable, Representation::Double(), any_type); @@ -2141,9 +2128,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { // fixed. template <typename TestConfig> static void TestGeneralizeFieldWithSpecialTransition( - TestConfig& config, // NOLINT(runtime/references) - const CRFTData& from, const CRFTData& to, const CRFTData& expected, - bool expected_deprecation) { + TestConfig* config, const CRFTData& from, const CRFTData& to, + const CRFTData& expected, bool expected_deprecation) { Isolate* isolate = CcTest::i_isolate(); Expectations expectations(isolate); @@ -2163,13 +2149,13 @@ static void TestGeneralizeFieldWithSpecialTransition( // Apply some special transition to |map|. CHECK(map->owns_descriptors()); - Handle<Map> map2 = config.Transition(map, expectations2); + Handle<Map> map2 = config->Transition(map, &expectations2); // |map| should still match expectations. CHECK(!map->is_deprecated()); CHECK(expectations.Check(*map)); - if (config.generalizes_representations()) { + if (config->generalizes_representations()) { for (int i = 0; i < kPropCount; i++) { expectations2.GeneralizeField(i); } @@ -2182,8 +2168,9 @@ static void TestGeneralizeFieldWithSpecialTransition( // Create new maps by generalizing representation of propX field. Handle<Map> maps[kPropCount]; for (int i = 0; i < kPropCount; i++) { - Handle<Map> new_map = Map::ReconfigureProperty(isolate, map, i, kData, NONE, - to.representation, to.type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(i), kData, NONE, + to.representation, to.type); maps[i] = new_map; expectations.SetDataField(i, expected.constness, expected.representation, @@ -2206,10 +2193,10 @@ static void TestGeneralizeFieldWithSpecialTransition( CHECK_EQ(*new_map2, *tmp_map); } else { // Equivalent transitions should always find the updated map. - CHECK(config.is_non_equivalent_transition()); + CHECK(config->is_non_equivalent_transition()); } - if (config.is_non_equivalent_transition()) { + if (config->is_non_equivalent_transition()) { // In case of non-equivalent transition currently we generalize all // representations. for (int i = 0; i < kPropCount; i++) { @@ -2260,9 +2247,9 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) { ElementsKind kind) : attributes(attributes), symbol(symbol), elements_kind(kind) {} - Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { - expectations.SetElementsKind(elements_kind); - expectations.ChangeAttributesForAllProperties(attributes); + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { + expectations->SetElementsKind(elements_kind); + expectations->ChangeAttributesForAllProperties(attributes); return Map::CopyForPreventExtensions(CcTest::i_isolate(), map, attributes, symbol, "CopyForPreventExtensions"); } @@ -2287,17 +2274,17 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) { : DICTIONARY_ELEMENTS}}; for (size_t i = 0; i < arraysize(configs); i++) { TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, - true); + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } } @@ -2316,7 +2303,7 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { ElementsKind kind) : attributes(attributes), symbol(symbol), elements_kind(kind) {} - Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2329,8 +2316,8 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { .ToHandleChecked(); CHECK(!map->owns_descriptors()); - expectations.SetElementsKind(elements_kind); - expectations.ChangeAttributesForAllProperties(attributes); + expectations->SetElementsKind(elements_kind); + expectations->ChangeAttributesForAllProperties(attributes); return Map::CopyForPreventExtensions(isolate, map, attributes, symbol, "CopyForPreventExtensions"); } @@ -2355,17 +2342,17 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { : DICTIONARY_ELEMENTS}}; for (size_t i = 0; i < arraysize(configs); i++) { TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, - true); + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } } @@ -2388,9 +2375,7 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) { prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); } - Handle<Map> Transition( - Handle<Map> map, - Expectations& expectations) { // NOLINT(runtime/references) + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { return Map::TransitionToPrototype(CcTest::i_isolate(), map, prototype_); } // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. @@ -2401,14 +2386,16 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) { }; TestConfig config; TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, + &config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Double(), any_type}, + &config, + {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}, true); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } TEST(PrototypeTransitionFromMapNotOwningDescriptor) { @@ -2429,9 +2416,7 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) { prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); } - Handle<Map> Transition( - Handle<Map> map, - Expectations& expectations) { // NOLINT(runtime/references) + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2454,14 +2439,16 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) { }; TestConfig config; TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, + &config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Double(), any_type}, + &config, + {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}, true); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } //////////////////////////////////////////////////////////////////////////////// @@ -2486,10 +2473,8 @@ struct TransitionToDataFieldOperator { heap_type_(heap_type), value_(value) {} - Handle<Map> DoTransition( - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { - return expectations.TransitionToDataField( + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToDataField( map, attributes_, constness_, representation_, heap_type_, value_); } }; @@ -2503,8 +2488,8 @@ struct TransitionToDataConstantOperator { PropertyAttributes attributes = NONE) : attributes_(attributes), value_(value) {} - Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { - return expectations.TransitionToDataConstant(map, attributes_, value_); + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToDataConstant(map, attributes_, value_); } }; @@ -2517,14 +2502,14 @@ struct TransitionToAccessorConstantOperator { PropertyAttributes attributes = NONE) : attributes_(attributes), pair_(pair) {} - Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { - return expectations.TransitionToAccessorConstant(map, attributes_, pair_); + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToAccessorConstant(map, attributes_, pair_); } }; struct ReconfigureAsDataPropertyOperator { - int descriptor_; + InternalIndex descriptor_; Representation representation_; PropertyAttributes attributes_; Handle<FieldType> heap_type_; @@ -2538,12 +2523,11 @@ struct ReconfigureAsDataPropertyOperator { attributes_(attributes), heap_type_(heap_type) {} - Handle<Map> DoTransition( - Isolate* isolate, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { - expectations.SetDataField(descriptor_, PropertyConstness::kMutable, - representation_, heap_type_); + Handle<Map> DoTransition(Isolate* isolate, Expectations* expectations, + Handle<Map> map) { + expectations->SetDataField(descriptor_.as_int(), + PropertyConstness::kMutable, representation_, + heap_type_); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, kData, attributes_, PropertyConstness::kConst); @@ -2552,16 +2536,16 @@ struct ReconfigureAsDataPropertyOperator { struct ReconfigureAsAccessorPropertyOperator { - int descriptor_; + InternalIndex descriptor_; PropertyAttributes attributes_; ReconfigureAsAccessorPropertyOperator(int descriptor, PropertyAttributes attributes = NONE) : descriptor_(descriptor), attributes_(attributes) {} - Handle<Map> DoTransition(Isolate* isolate, Expectations& expectations, + Handle<Map> DoTransition(Isolate* isolate, Expectations* expectations, Handle<Map> map) { - expectations.SetAccessorField(descriptor_); + expectations->SetAccessorField(descriptor_.as_int()); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, kAccessor, attributes_, PropertyConstness::kConst); @@ -2586,9 +2570,8 @@ struct FieldGeneralizationChecker { attributes_(attributes), heap_type_(heap_type) {} - void Check(Isolate* isolate, - Expectations& expectations2, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Isolate* isolate, Expectations* expectations, Handle<Map> map1, + Handle<Map> map2) { CHECK(!map2->is_deprecated()); CHECK(map1->is_deprecated()); @@ -2597,21 +2580,20 @@ struct FieldGeneralizationChecker { CHECK_EQ(*map2, *updated_map); CheckMigrationTarget(isolate, *map1, *updated_map); - expectations2.SetDataField(descriptor_, attributes_, constness_, + expectations->SetDataField(descriptor_, attributes_, constness_, representation_, heap_type_); - CHECK(expectations2.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; // Checks that existing transition was taken as is. struct SameMapChecker { - void Check(Isolate* isolate, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Isolate* isolate, Expectations* expectations, Handle<Map> map1, + Handle<Map> map2) { CHECK(!map2->is_deprecated()); CHECK_EQ(*map1, *map2); - CHECK(expectations.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; @@ -2619,12 +2601,11 @@ struct SameMapChecker { // Checks that both |map1| and |map2| should stays non-deprecated, this is // the case when property kind is change. struct PropertyKindReconfigurationChecker { - void Check(Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Expectations* expectations, Handle<Map> map1, Handle<Map> map2) { CHECK(!map1->is_deprecated()); CHECK(!map2->is_deprecated()); CHECK_NE(*map1, *map2); - CHECK(expectations.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; @@ -2645,10 +2626,8 @@ struct PropertyKindReconfigurationChecker { // where "p4A" and "p4B" differ only in the attributes. // template <typename TransitionOp1, typename TransitionOp2, typename Checker> -static void TestTransitionTo( - TransitionOp1& transition_op1, // NOLINT(runtime/references) - TransitionOp2& transition_op2, // NOLINT(runtime/references) - Checker& checker) { // NOLINT(runtime/references) +static void TestTransitionTo(TransitionOp1* transition_op1, + TransitionOp2* transition_op2, Checker* checker) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2664,14 +2643,14 @@ static void TestTransitionTo( CHECK(expectations.Check(*map)); Expectations expectations1 = expectations; - Handle<Map> map1 = transition_op1.DoTransition(expectations1, map); + Handle<Map> map1 = transition_op1->DoTransition(&expectations1, map); CHECK(expectations1.Check(*map1)); Expectations expectations2 = expectations; - Handle<Map> map2 = transition_op2.DoTransition(expectations2, map); + Handle<Map> map2 = transition_op2->DoTransition(&expectations2, map); // Let the test customization do the check. - checker.Check(isolate, expectations2, map1, map2); + checker->Check(isolate, &expectations2, map1, map2); } TEST(TransitionDataFieldToDataField) { @@ -2692,7 +2671,7 @@ TEST(TransitionDataFieldToDataField) { FieldGeneralizationChecker checker(kPropCount - 1, PropertyConstness::kMutable, Representation::Double(), any_type); - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } TEST(TransitionDataConstantToSameDataConstant) { @@ -2706,7 +2685,7 @@ TEST(TransitionDataConstantToSameDataConstant) { TransitionToDataConstantOperator transition_op(js_func); SameMapChecker checker; - TestTransitionTo(transition_op, transition_op, checker); + TestTransitionTo(&transition_op, &transition_op, &checker); } @@ -2732,7 +2711,7 @@ TEST(TransitionDataConstantToAnotherDataConstant) { TransitionToDataConstantOperator transition_op2(js_func2); SameMapChecker checker; - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } @@ -2754,12 +2733,12 @@ TEST(TransitionDataConstantToDataField) { if (FLAG_modify_field_representation_inplace) { SameMapChecker checker; - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } else { FieldGeneralizationChecker checker(kPropCount - 1, PropertyConstness::kMutable, Representation::Tagged(), any_type); - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } } @@ -2772,7 +2751,7 @@ TEST(TransitionAccessorConstantToSameAccessorConstant) { TransitionToAccessorConstantOperator transition_op(pair); SameMapChecker checker; - TestTransitionTo(transition_op, transition_op, checker); + TestTransitionTo(&transition_op, &transition_op, &checker); } // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. @@ -2840,11 +2819,11 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_dictionary_map()); CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + InternalIndex first(0); + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(PropertyConstness::kConst, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); // Store value2 to obj2 and check that it got same map and property details // did not change. @@ -2856,10 +2835,10 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(PropertyConstness::kConst, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); // Store value2 to obj1 and check that property became mutable. Call(isolate, store_func, obj1, value2).Check(); @@ -2869,10 +2848,10 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(expected_constness, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); } void TestStoreToConstantField_PlusMinusZero(const char* store_func_source, diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc index 4e5fcffa62..93c7048f81 100644 --- a/deps/v8/test/cctest/test-flags.cc +++ b/deps/v8/test/cctest/test-flags.cc @@ -209,11 +209,5 @@ TEST(FlagsJitlessImplications) { } } -TEST(FlagsRegexpInterpretAllImplications) { - if (FLAG_regexp_interpret_all) { - CHECK(!FLAG_regexp_tier_up); - } -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index 417679432b..98a66bf535 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -49,7 +49,7 @@ class NonRootingEmbedderHeapTracer final : public v8::EmbedderHeapTracer { const std::vector<std::pair<void*, void*>>& embedder_fields) final {} bool AdvanceTracing(double deadline_in_ms) final { return true; } bool IsTracingDone() final { return true; } - void TracePrologue() final {} + void TracePrologue(TraceFlags) final {} void TraceEpilogue() final {} void EnterFinalPause(EmbedderStackState) final {} diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 3aec4ae003..7784a7f855 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -3062,7 +3062,8 @@ TEST(ArrayBufferSharedBackingStore) { CHECK(ab2_data); CHECK_EQ(ab1_data, ab2_data); CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data)); - free(data); + ab_contents.Deleter()(ab_contents.Data(), ab_contents.ByteLength(), + ab_contents.DeleterData()); } @@ -3577,10 +3578,9 @@ TEST(AddressToTraceMap) { } static const v8::AllocationProfile::Node* FindAllocationProfileNode( - v8::Isolate* isolate, - v8::AllocationProfile& profile, // NOLINT(runtime/references) + v8::Isolate* isolate, v8::AllocationProfile* profile, const Vector<const char*>& names) { - v8::AllocationProfile::Node* node = profile.GetRootNode(); + v8::AllocationProfile::Node* node = profile->GetRootNode(); for (int i = 0; node != nullptr && i < names.length(); ++i) { const char* name = names[i]; auto children = node->children; @@ -3650,7 +3650,7 @@ TEST(SamplingHeapProfiler) { CHECK(profile); const char* names[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node_bar); @@ -3674,12 +3674,12 @@ TEST(SamplingHeapProfiler) { CHECK(profile); const char* names1[] = {"", "start", "f_0_0", "f_0_1", "f_0_2"}; - auto node1 = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node1 = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names1)); CHECK(node1); const char* names2[] = {"", "generateFunctions"}; - auto node2 = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node2 = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names2)); CHECK(node2); @@ -3737,11 +3737,11 @@ TEST(SamplingHeapProfilerRateAgnosticEstimates) { CHECK(profile); const char* path_to_foo[] = {"", "foo"}; - auto node_foo = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_foo = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_foo)); CHECK(node_foo); const char* path_to_bar[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_bar)); CHECK(node_bar); @@ -3761,11 +3761,11 @@ TEST(SamplingHeapProfilerRateAgnosticEstimates) { CHECK(profile); const char* path_to_foo[] = {"", "foo"}; - auto node_foo = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_foo = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_foo)); CHECK(node_foo); const char* path_to_bar[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_bar)); CHECK(node_bar); @@ -3804,7 +3804,7 @@ TEST(SamplingHeapProfilerApiAllocation) { heap_profiler->GetAllocationProfile()); CHECK(profile); const char* names[] = {"(V8 API)"}; - auto node = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node); @@ -3944,7 +3944,7 @@ TEST(SamplingHeapProfilerPretenuredInlineAllocations) { heap_profiler->StopSamplingHeapProfiler(); const char* names[] = {"f"}; - auto node_f = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_f = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node_f); @@ -3974,7 +3974,7 @@ TEST(SamplingHeapProfilerLargeInterval) { heap_profiler->GetAllocationProfile()); CHECK(profile); const char* names[] = {"(EXTERNAL)"}; - auto node = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node); diff --git a/deps/v8/test/cctest/test-inobject-slack-tracking.cc b/deps/v8/test/cctest/test-inobject-slack-tracking.cc index 6a25536dd5..e2de4df4fb 100644 --- a/deps/v8/test/cctest/test-inobject-slack-tracking.cc +++ b/deps/v8/test/cctest/test-inobject-slack-tracking.cc @@ -1112,7 +1112,7 @@ TEST(SubclassRegExpBuiltin) { v8::HandleScope scope(CcTest::isolate()); const int first_field = 1; - TestSubclassBuiltin("A1", JS_REGEXP_TYPE, "RegExp", "'o(..)h', 'g'", + TestSubclassBuiltin("A1", JS_REG_EXP_TYPE, "RegExp", "'o(..)h', 'g'", first_field); } diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index 092c107841..4ed00e0a11 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -944,7 +944,7 @@ TEST(ExtensionsRegistration) { "test4", "test5", "test6", "test7"}; for (const char* name : extension_names) { v8::RegisterExtension( - v8::base::make_unique<v8::Extension>(name, kSimpleExtensionSource)); + std::make_unique<v8::Extension>(name, kSimpleExtensionSource)); } std::vector<JoinableThread*> threads; threads.reserve(kNThreads); diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 1344c0e9d1..e238c8c021 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -242,37 +242,37 @@ TEST(SmiTag) { __ movq(rax, Immediate(1)); // Test number. __ movq(rcx, Immediate(0)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::kZero.ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(2)); // Test number. __ movq(rcx, Immediate(1024)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(1024).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(3)); // Test number. __ movq(rcx, Immediate(-1)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(-1).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(4)); // Test number. __ movq(rcx, Immediate(Smi::kMaxValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(Smi::kMaxValue).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(5)); // Test number. __ movq(rcx, Immediate(Smi::kMinValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(Smi::kMinValue).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); // Different target register. @@ -281,35 +281,35 @@ TEST(SmiTag) { __ movq(rcx, Immediate(0)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::zero().ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(7)); // Test number. __ movq(rcx, Immediate(1024)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(1024).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(8)); // Test number. __ movq(rcx, Immediate(-1)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(-1).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(9)); // Test number. __ movq(rcx, Immediate(Smi::kMaxValue)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(Smi::kMaxValue).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(10)); // Test number. __ movq(rcx, Immediate(Smi::kMinValue)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(Smi::kMinValue).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); @@ -344,7 +344,7 @@ TEST(SmiCheck) { // CheckSmi __ movl(rcx, Immediate(0)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -355,7 +355,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(-1)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -366,7 +366,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(Smi::kMaxValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -377,7 +377,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(Smi::kMinValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); diff --git a/deps/v8/test/cctest/test-modules.cc b/deps/v8/test/cctest/test-modules.cc index 0f2bfd2a5f..d7cb6e610e 100644 --- a/deps/v8/test/cctest/test-modules.cc +++ b/deps/v8/test/cctest/test-modules.cc @@ -14,6 +14,7 @@ using v8::Isolate; using v8::Local; using v8::MaybeLocal; using v8::Module; +using v8::Promise; using v8::ScriptCompiler; using v8::ScriptOrigin; using v8::String; @@ -196,99 +197,480 @@ static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback( } TEST(ModuleEvaluation) { - Isolate* isolate = CcTest::isolate(); - HandleScope scope(isolate); - LocalContext env; - v8::TryCatch try_catch(isolate); + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; - Local<String> source_text = v8_str( - "import 'Object.expando = 5';" - "import 'Object.expando *= 2';"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(!module->Evaluate(env.local()).IsEmpty()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - ExpectInt32("Object.expando", 10); + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); - CHECK(!try_catch.HasCaught()); + Local<String> source_text = v8_str( + "import 'Object.expando = 5';" + "import 'Object.expando *= 2';"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + MaybeLocal<Value> result = module->Evaluate(env.local()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked()); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK(!result.IsEmpty()); + ExpectInt32("Object.expando", 10); + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; } -TEST(ModuleEvaluationError) { - Isolate* isolate = CcTest::isolate(); - HandleScope scope(isolate); - LocalContext env; - v8::TryCatch try_catch(isolate); +TEST(ModuleEvaluationError1) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; - Local<String> source_text = - v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); - { - v8::TryCatch inner_try_catch(isolate); - CHECK(module->Evaluate(env.local()).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); - CHECK_EQ(Module::kErrored, module->GetStatus()); - Local<Value> exception = module->GetException(); - CHECK(exception->StrictEquals(v8_str("boom"))); - ExpectInt32("Object.x", 1); + Local<String> source_text = + v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + MaybeLocal<Value> result_1; + { + v8::TryCatch inner_try_catch(isolate); + result_1 = module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + Local<Value> exception = module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + ExpectInt32("Object.x", 1); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + + MaybeLocal<Value> result_2; + { + v8::TryCatch inner_try_catch(isolate); + result_2 = module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + Local<Value> exception = module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + ExpectInt32("Object.x", 1); + + if (i::FLAG_harmony_top_level_await) { + // With top level await we do not rethrow the exception. + CHECK(!inner_try_catch.HasCaught()); + } else { + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + } + if (i::FLAG_harmony_top_level_await) { + // With top level await, errored evaluation returns a rejected promise + // with the exception. + Local<Promise> promise_1 = + Local<Promise>::Cast(result_1.ToLocalChecked()); + Local<Promise> promise_2 = + Local<Promise>::Cast(result_2.ToLocalChecked()); + CHECK_EQ(promise_1->State(), v8::Promise::kRejected); + CHECK_EQ(promise_2->State(), v8::Promise::kRejected); + CHECK_EQ(promise_1->Result(), module->GetException()); + CHECK_EQ(promise_2->Result(), module->GetException()); + } else { + CHECK(result_1.IsEmpty() && result_2.IsEmpty()); + } + + CHECK(!try_catch.HasCaught()); } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} - { - v8::TryCatch inner_try_catch(isolate); - CHECK(module->Evaluate(env.local()).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); - CHECK_EQ(Module::kErrored, module->GetStatus()); - Local<Value> exception = module->GetException(); - CHECK(exception->StrictEquals(v8_str("boom"))); - ExpectInt32("Object.x", 1); +static Local<Module> failure_module; +static Local<Module> dependent_module; +MaybeLocal<Module> ResolveCallbackForModuleEvaluationError2( + Local<Context> context, Local<String> specifier, Local<Module> referrer) { + if (specifier->StrictEquals(v8_str("./failure.js"))) { + return failure_module; + } else { + CHECK(specifier->StrictEquals(v8_str("./dependent.js"))); + return dependent_module; } +} - CHECK(!try_catch.HasCaught()); +TEST(ModuleEvaluationError2) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + Local<String> failure_text = v8_str("throw 'boom';"); + ScriptOrigin failure_origin = + ModuleOrigin(v8_str("failure.js"), CcTest::isolate()); + ScriptCompiler::Source failure_source(failure_text, failure_origin); + failure_module = ScriptCompiler::CompileModule(isolate, &failure_source) + .ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, failure_module->GetStatus()); + CHECK(failure_module + ->InstantiateModule(env.local(), + ResolveCallbackForModuleEvaluationError2) + .FromJust()); + CHECK_EQ(Module::kInstantiated, failure_module->GetStatus()); + + MaybeLocal<Value> result_1; + { + v8::TryCatch inner_try_catch(isolate); + result_1 = failure_module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, failure_module->GetStatus()); + Local<Value> exception = failure_module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + + Local<String> dependent_text = + v8_str("import './failure.js'; export const c = 123;"); + ScriptOrigin dependent_origin = + ModuleOrigin(v8_str("dependent.js"), CcTest::isolate()); + ScriptCompiler::Source dependent_source(dependent_text, dependent_origin); + dependent_module = ScriptCompiler::CompileModule(isolate, &dependent_source) + .ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, dependent_module->GetStatus()); + CHECK(dependent_module + ->InstantiateModule(env.local(), + ResolveCallbackForModuleEvaluationError2) + .FromJust()); + CHECK_EQ(Module::kInstantiated, dependent_module->GetStatus()); + + MaybeLocal<Value> result_2; + { + v8::TryCatch inner_try_catch(isolate); + result_2 = dependent_module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, dependent_module->GetStatus()); + Local<Value> exception = dependent_module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + CHECK_EQ(exception, failure_module->GetException()); + + if (i::FLAG_harmony_top_level_await) { + // With top level await we do not rethrow the exception. + CHECK(!inner_try_catch.HasCaught()); + } else { + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + } + + if (i::FLAG_harmony_top_level_await) { + // With top level await, errored evaluation returns a rejected promise + // with the exception. + Local<Promise> promise_1 = + Local<Promise>::Cast(result_1.ToLocalChecked()); + Local<Promise> promise_2 = + Local<Promise>::Cast(result_2.ToLocalChecked()); + CHECK_EQ(promise_1->State(), v8::Promise::kRejected); + CHECK_EQ(promise_2->State(), v8::Promise::kRejected); + CHECK_EQ(promise_1->Result(), failure_module->GetException()); + CHECK_EQ(promise_2->Result(), failure_module->GetException()); + } else { + CHECK(result_1.IsEmpty() && result_2.IsEmpty()); + } + + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; } TEST(ModuleEvaluationCompletion1) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + const char* sources[] = { + "", + "var a = 1", + "import '42'", + "export * from '42'", + "export {} from '42'", + "export {}", + "var a = 1; export {a}", + "export function foo() {}", + "export class C extends null {}", + "export let a = 1", + "export default 1", + "export default function foo() {}", + "export default function () {}", + "export default (function () {})", + "export default class C extends null {}", + "export default (class C extends null {})", + "for (var i = 0; i < 5; ++i) {}", + }; + + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + // Evaluate twice. + Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result_1); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + + // Second evaluation should return the same promise. + Local<Promise> promise_too = Local<Promise>::Cast(result_2); + CHECK_EQ(promise, promise_too); + CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled); + CHECK(promise_too->Result()->IsUndefined()); + } else { + CHECK(result_1->IsUndefined()); + CHECK(result_2->IsUndefined()); + } + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleEvaluationCompletion2) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + const char* sources[] = { + "'gaga'; ", + "'gaga'; var a = 1", + "'gaga'; import '42'", + "'gaga'; export * from '42'", + "'gaga'; export {} from '42'", + "'gaga'; export {}", + "'gaga'; var a = 1; export {a}", + "'gaga'; export function foo() {}", + "'gaga'; export class C extends null {}", + "'gaga'; export let a = 1", + "'gaga'; export default 1", + "'gaga'; export default function foo() {}", + "'gaga'; export default function () {}", + "'gaga'; export default (function () {})", + "'gaga'; export default class C extends null {}", + "'gaga'; export default (class C extends null {})", + }; + + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result_1); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + + // Second Evaluation should return the same promise. + Local<Promise> promise_too = Local<Promise>::Cast(result_2); + CHECK_EQ(promise, promise_too); + CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled); + CHECK(promise_too->Result()->IsUndefined()); + } else { + CHECK(result_1->StrictEquals(v8_str("gaga"))); + CHECK(result_2->IsUndefined()); + } + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleNamespace) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + Local<v8::Object> ReferenceError = + CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked(); + + Local<String> source_text = v8_str( + "import {a, b} from 'export var a = 1; export let b = 2';" + "export function geta() {return a};" + "export function getb() {return b};" + "export let radio = 3;" + "export var gaga = 4;"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Local<Value> ns = module->GetModuleNamespace(); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked(); + CHECK_EQ(nsobj->CreationContext(), env.local()); + + // a, b + CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined()); + CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined()); + + // geta + { + auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); + auto a = geta.As<v8::Function>() + ->Call(env.local(), geta, 0, nullptr) + .ToLocalChecked(); + CHECK(a->IsUndefined()); + } + + // getb + { + v8::TryCatch inner_try_catch(isolate); + auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); + CHECK(getb.As<v8::Function>() + ->Call(env.local(), getb, 0, nullptr) + .IsEmpty()); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception() + ->InstanceOf(env.local(), ReferenceError) + .FromJust()); + } + + // radio + { + v8::TryCatch inner_try_catch(isolate); + // https://bugs.chromium.org/p/v8/issues/detail?id=7235 + // CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty()); + CHECK(nsobj->Get(env.local(), v8_str("radio")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception() + ->InstanceOf(env.local(), ReferenceError) + .FromJust()); + } + + // gaga + { + auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); + CHECK(gaga->IsUndefined()); + } + + CHECK(!try_catch.HasCaught()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + // geta + { + auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); + auto a = geta.As<v8::Function>() + ->Call(env.local(), geta, 0, nullptr) + .ToLocalChecked(); + CHECK_EQ(1, a->Int32Value(env.local()).FromJust()); + } + + // getb + { + auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); + auto b = getb.As<v8::Function>() + ->Call(env.local(), getb, 0, nullptr) + .ToLocalChecked(); + CHECK_EQ(2, b->Int32Value(env.local()).FromJust()); + } + + // radio + { + auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked(); + CHECK_EQ(3, radio->Int32Value(env.local()).FromJust()); + } + + // gaga + { + auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); + CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust()); + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleEvaluationTopLevelAwait) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext env; v8::TryCatch try_catch(isolate); - const char* sources[] = { - "", - "var a = 1", - "import '42'", - "export * from '42'", - "export {} from '42'", - "export {}", - "var a = 1; export {a}", - "export function foo() {}", - "export class C extends null {}", - "export let a = 1", - "export default 1", - "export default function foo() {}", - "export default function () {}", - "export default (function () {})", - "export default class C extends null {}", - "export default (class C extends null {})", - "for (var i = 0; i < 5; ++i) {}", + "await 42", + "import 'await 42';", + "import '42'; import 'await 42';", }; for (auto src : sources) { @@ -303,41 +685,30 @@ TEST(ModuleEvaluationCompletion1) { CompileSpecifierAsModuleResolveCallback) .FromJust()); CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + CHECK(!try_catch.HasCaught()); } - - CHECK(!try_catch.HasCaught()); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; } -TEST(ModuleEvaluationCompletion2) { +TEST(ModuleEvaluationTopLevelAwaitError) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext env; - v8::TryCatch try_catch(isolate); - const char* sources[] = { - "'gaga'; ", - "'gaga'; var a = 1", - "'gaga'; import '42'", - "'gaga'; export * from '42'", - "'gaga'; export {} from '42'", - "'gaga'; export {}", - "'gaga'; var a = 1; export {a}", - "'gaga'; export function foo() {}", - "'gaga'; export class C extends null {}", - "'gaga'; export let a = 1", - "'gaga'; export default 1", - "'gaga'; export default function foo() {}", - "'gaga'; export default function () {}", - "'gaga'; export default (function () {})", - "'gaga'; export default class C extends null {}", - "'gaga'; export default (class C extends null {})", + "await 42; throw 'boom';", + "import 'await 42; throw \"boom\";';", + "import '42'; import 'await 42; throw \"boom\";';", }; for (auto src : sources) { + v8::TryCatch try_catch(isolate); Local<String> source_text = v8_str(src); ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); ScriptCompiler::Source source(source_text, origin); @@ -349,126 +720,170 @@ TEST(ModuleEvaluationCompletion2) { CompileSpecifierAsModuleResolveCallback) .FromJust()); CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(module->Evaluate(env.local()) - .ToLocalChecked() - ->StrictEquals(v8_str("gaga"))); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK(promise->Result()->StrictEquals(v8_str("boom"))); + CHECK(module->GetException()->StrictEquals(v8_str("boom"))); + + // TODO(joshualitt) I am not sure, but this might not be supposed to throw + // because it is async. + CHECK(!try_catch.HasCaught()); } + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; +} - CHECK(!try_catch.HasCaught()); +namespace { +struct DynamicImportData { + DynamicImportData(Isolate* isolate_, Local<Promise::Resolver> resolver_, + Local<Context> context_, bool should_resolve_) + : isolate(isolate_), should_resolve(should_resolve_) { + resolver.Reset(isolate, resolver_); + context.Reset(isolate, context_); + } + + Isolate* isolate; + v8::Global<Promise::Resolver> resolver; + v8::Global<Context> context; + bool should_resolve; +}; + +void DoHostImportModuleDynamically(void* import_data) { + std::unique_ptr<DynamicImportData> import_data_( + static_cast<DynamicImportData*>(import_data)); + Isolate* isolate(import_data_->isolate); + HandleScope handle_scope(isolate); + + Local<Promise::Resolver> resolver(import_data_->resolver.Get(isolate)); + Local<Context> realm(import_data_->context.Get(isolate)); + Context::Scope context_scope(realm); + + if (import_data_->should_resolve) { + resolver->Resolve(realm, True(isolate)).ToChecked(); + } else { + resolver->Reject(realm, v8_str("boom")).ToChecked(); + } } -TEST(ModuleNamespace) { +v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackResolve( + Local<Context> context, Local<v8::ScriptOrModule> referrer, + Local<String> specifier) { + Isolate* isolate = context->GetIsolate(); + Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + + DynamicImportData* data = + new DynamicImportData(isolate, resolver, context, true); + isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data); + return resolver->GetPromise(); +} + +v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackReject( + Local<Context> context, Local<v8::ScriptOrModule> referrer, + Local<String> specifier) { + Isolate* isolate = context->GetIsolate(); + Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + + DynamicImportData* data = + new DynamicImportData(isolate, resolver, context, false); + isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data); + return resolver->GetPromise(); +} + +} // namespace + +TEST(ModuleEvaluationTopLevelAwaitDynamicImport) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + bool previous_dynamic_import_flag_value = i::FLAG_harmony_dynamic_import; + i::FLAG_harmony_top_level_await = true; + i::FLAG_harmony_dynamic_import = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); + isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); + isolate->SetHostImportModuleDynamicallyCallback( + HostImportModuleDynamicallyCallbackResolve); LocalContext env; v8::TryCatch try_catch(isolate); + const char* sources[] = { + "await import('foo');", + "import 'await import(\"foo\");';", + "import '42'; import 'await import(\"foo\");';", + }; - Local<v8::Object> ReferenceError = - CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked(); - - Local<String> source_text = v8_str( - "import {a, b} from 'export var a = 1; export let b = 2';" - "export function geta() {return a};" - "export function getb() {return b};" - "export let radio = 3;" - "export var gaga = 4;"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - Local<Value> ns = module->GetModuleNamespace(); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked(); - - // a, b - CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined()); - CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined()); - - // geta - { - auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); - auto a = geta.As<v8::Function>() - ->Call(env.local(), geta, 0, nullptr) - .ToLocalChecked(); - CHECK(a->IsUndefined()); - } - - // getb - { - v8::TryCatch inner_try_catch(isolate); - auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); - CHECK( - getb.As<v8::Function>()->Call(env.local(), getb, 0, nullptr).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception() - ->InstanceOf(env.local(), ReferenceError) + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) .FromJust()); - } + CHECK_EQ(Module::kInstantiated, module->GetStatus()); - // radio - { - v8::TryCatch inner_try_catch(isolate); - // https://bugs.chromium.org/p/v8/issues/detail?id=7235 - // CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty()); - CHECK(nsobj->Get(env.local(), v8_str("radio")) - .ToLocalChecked() - ->IsUndefined()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception() - ->InstanceOf(env.local(), ReferenceError) - .FromJust()); - } + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kPending); + CHECK(!try_catch.HasCaught()); - // gaga - { - auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); - CHECK(gaga->IsUndefined()); + isolate->RunMicrotasks(); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); } + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; + i::FLAG_harmony_dynamic_import = previous_dynamic_import_flag_value; +} - CHECK(!try_catch.HasCaught()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - module->Evaluate(env.local()).ToLocalChecked(); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - - // geta - { - auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); - auto a = geta.As<v8::Function>() - ->Call(env.local(), geta, 0, nullptr) - .ToLocalChecked(); - CHECK_EQ(1, a->Int32Value(env.local()).FromJust()); - } +TEST(ModuleEvaluationTopLevelAwaitDynamicImportError) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + bool previous_dynamic_import_flag_value = i::FLAG_harmony_dynamic_import; + i::FLAG_harmony_top_level_await = true; + i::FLAG_harmony_dynamic_import = true; + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); + isolate->SetHostImportModuleDynamicallyCallback( + HostImportModuleDynamicallyCallbackReject); + LocalContext env; + v8::TryCatch try_catch(isolate); + const char* sources[] = { + "await import('foo');", + "import 'await import(\"foo\");';", + "import '42'; import 'await import(\"foo\");';", + }; - // getb - { - auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); - auto b = getb.As<v8::Function>() - ->Call(env.local(), getb, 0, nullptr) - .ToLocalChecked(); - CHECK_EQ(2, b->Int32Value(env.local()).FromJust()); - } + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); - // radio - { - auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked(); - CHECK_EQ(3, radio->Int32Value(env.local()).FromJust()); - } + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kPending); + CHECK(!try_catch.HasCaught()); - // gaga - { - auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); - CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust()); + isolate->RunMicrotasks(); + CHECK_EQ(Module::kErrored, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK(promise->Result()->StrictEquals(v8_str("boom"))); + CHECK(module->GetException()->StrictEquals(v8_str("boom"))); + CHECK(!try_catch.HasCaught()); } - - CHECK(!try_catch.HasCaught()); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; + i::FLAG_harmony_dynamic_import = previous_dynamic_import_flag_value; } + } // anonymous namespace diff --git a/deps/v8/test/cctest/test-orderedhashtable.cc b/deps/v8/test/cctest/test-orderedhashtable.cc index 44a845eb74..189f950b2e 100644 --- a/deps/v8/test/cctest/test-orderedhashtable.cc +++ b/deps/v8/test/cctest/test-orderedhashtable.cc @@ -1262,6 +1262,7 @@ TEST(OrderedHashMapHandlerInsertion) { Verify(isolate, map); CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); CHECK(SmallOrderedHashMap::Is(map)); + for (int i = 0; i < 1024; i++) { Handle<Smi> key_i(Smi::FromInt(i), isolate); Handle<Smi> value_i(Smi::FromInt(i), isolate); @@ -1276,6 +1277,83 @@ TEST(OrderedHashMapHandlerInsertion) { CHECK(OrderedHashMap::Is(map)); } +TEST(OrderedHashSetHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> set = + OrderedHashSetHandler::Allocate(isolate, 4).ToHandleChecked(); + Verify(isolate, set); + + // Add a new key. + Handle<Smi> key1(Smi::FromInt(1), isolate); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key1)); + set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked(); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + + // Add existing key. + set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked(); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(SmallOrderedHashSet::Is(set)); + + // Remove a non-existing key. + Handle<Smi> key2(Smi::FromInt(2), isolate); + OrderedHashSetHandler::Delete(isolate, set, key2); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key2)); + CHECK(SmallOrderedHashSet::Is(set)); + + // Remove an existing key. + OrderedHashSetHandler::Delete(isolate, set, key1); + Verify(isolate, set); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(SmallOrderedHashSet::Is(set)); +} + +TEST(OrderedHashMapHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> map = + OrderedHashMapHandler::Allocate(isolate, 4).ToHandleChecked(); + Verify(isolate, map); + + // Add a new key. + Handle<Smi> key1(Smi::FromInt(1), isolate); + Handle<Smi> value1(Smi::FromInt(1), isolate); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key1)); + map = + OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked(); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + + // Add existing key. + map = + OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked(); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(SmallOrderedHashMap::Is(map)); + + // Remove a non-existing key. + Handle<Smi> key2(Smi::FromInt(2), isolate); + OrderedHashMapHandler::Delete(isolate, map, key2); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key2)); + CHECK(SmallOrderedHashMap::Is(map)); + + // Remove an existing key. + OrderedHashMapHandler::Delete(isolate, map, key1); + Verify(isolate, map); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(SmallOrderedHashMap::Is(map)); +} + TEST(OrderedNameDictionaryInsertion) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); @@ -1798,6 +1876,49 @@ TEST(OrderedNameDictionaryHandlerInsertion) { CHECK(table->IsOrderedNameDictionary()); } +TEST(OrderedNameDictionaryHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> table = + OrderedNameDictionaryHandler::Allocate(isolate, 4).ToHandleChecked(); + CHECK(table->IsSmallOrderedNameDictionary()); + Verify(isolate, table); + + // Add a new key. + Handle<String> value = isolate->factory()->InternalizeUtf8String("bar"); + Handle<String> key = isolate->factory()->InternalizeUtf8String("foo"); + Handle<String> key2 = isolate->factory()->InternalizeUtf8String("foo2"); + PropertyDetails details = PropertyDetails::Empty(); + + table = OrderedNameDictionaryHandler::Add(isolate, table, key, value, details) + .ToHandleChecked(); + DCHECK(key->IsUniqueName()); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_NE(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + // Remove a non-existing key. + OrderedNameDictionaryHandler::Delete(isolate, table, key2); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_EQ(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key2)); + CHECK_NE(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + // Remove an existing key. + OrderedNameDictionaryHandler::Delete(isolate, table, key); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_EQ(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + CHECK(table->IsSmallOrderedNameDictionary()); +} + TEST(OrderedNameDictionarySetEntry) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index 857bd7a454..18f15af477 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -1506,8 +1506,11 @@ TEST(DiscardFunctionBody) { fun = exp->AsObjectLiteral()->properties()->at(0)->value()-> AsFunctionLiteral(); } else { - fun = exp->AsClassLiteral()->properties()->at(0)->value()-> - AsFunctionLiteral(); + fun = exp->AsClassLiteral() + ->public_members() + ->at(0) + ->value() + ->AsFunctionLiteral(); } } CHECK(!fun->ShouldEagerCompile()); @@ -3608,6 +3611,14 @@ TEST(MaybeAssignedParameters) { "g(arg)}"}, {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"}, {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"}, + + // default values + {false, "function f({x:arg = 1}) {}"}, + {true, "function f({x:arg = 1}, {y:b=(arg=2)}) {}"}, + {true, "function f({x:arg = (arg = 2)}) {}"}, + {false, "var f = ({x:arg = 1}) => {}"}, + {true, "var f = ({x:arg = 1}, {y:b=(arg=2)}) => {}"}, + {true, "var f = ({x:arg = (arg = 2)}) => {}"}, }; const char* suffix = "; f"; @@ -5877,6 +5888,70 @@ TEST(PrivateMembersWrongAccessNoEarlyErrors) { private_methods, arraysize(private_methods)); } +TEST(PrivateStaticClassMethodsAndAccessorsNoErrors) { + // clang-format off + // Tests proposed class fields syntax. + const char* context_data[][2] = {{"(class {", "});"}, + {"(class extends Base {", "});"}, + {"class C {", "}"}, + {"class C extends Base {", "}"}, + {nullptr, nullptr}}; + const char* class_body_data[] = { + "static #a() { }", + "static get #a() { }", + "static set #a(val) { }", + "static get #a() { } static set #a(val) { }", + "static *#a() { }", + "static async #a() { }", + "static async *#a() { }", + nullptr + }; + // clang-format on + + RunParserSyncTest(context_data, class_body_data, kError); + + static const ParserFlag private_methods[] = {kAllowHarmonyPrivateMethods}; + RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0, + private_methods, arraysize(private_methods)); +} + +TEST(PrivateStaticClassMethodsAndAccessorsDuplicateErrors) { + // clang-format off + // Tests proposed class fields syntax. + const char* context_data[][2] = {{"(class {", "});"}, + {"(class extends Base {", "});"}, + {"class C {", "}"}, + {"class C extends Base {", "}"}, + {nullptr, nullptr}}; + const char* class_body_data[] = { + "static get #a() {} static get #a() {}", + "static get #a() {} static #a() {}", + "static get #a() {} get #a() {}", + "static get #a() {} set #a(val) {}", + "static get #a() {} #a() {}", + + "static set #a(val) {} static set #a(val) {}", + "static set #a(val) {} static #a() {}", + "static set #a(val) {} get #a() {}", + "static set #a(val) {} set #a(val) {}", + "static set #a(val) {} #a() {}", + + "static #a() {} static #a() {}", + "static #a() {} #a(val) {}", + "static #a() {} set #a(val) {}", + "static #a() {} get #a() {}", + + nullptr + }; + // clang-format on + + RunParserSyncTest(context_data, class_body_data, kError); + + static const ParserFlag private_methods[] = {kAllowHarmonyPrivateMethods}; + RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0, + private_methods, arraysize(private_methods)); +} + TEST(PrivateClassFieldsNoErrors) { // clang-format off // Tests proposed class fields syntax. @@ -6216,14 +6291,6 @@ TEST(PrivateStaticClassFieldsErrors) { "#a; static #a", "static #a; #a", - // TODO(joyee): support static private methods - "static #a() { }", - "static get #a() { }", - "static set #a() { }", - "static *#a() { }", - "static async #a() { }", - "static async *#a() { }", - // ASI "static #['a'] = 0\n", "static #['a'] = 0\n b", diff --git a/deps/v8/test/cctest/test-poison-disasm-arm.cc b/deps/v8/test/cctest/test-poison-disasm-arm.cc index 3410e5487d..dd54bf28bc 100644 --- a/deps/v8/test/cctest/test-poison-disasm-arm.cc +++ b/deps/v8/test/cctest/test-poison-disasm-arm.cc @@ -24,6 +24,8 @@ const std::string kPReg = // NOLINT(runtime/string) TEST(DisasmPoisonMonomorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -58,6 +60,8 @@ TEST(DisasmPoisonMonomorphicLoad) { TEST(DisasmPoisonPolymorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -101,7 +105,7 @@ TEST(DisasmPoisonPolymorphicLoad) { "csdb", // spec. barrier "ldr <<BSt:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load backing store "and <<BSt>>, <<BSt>>, " + kPReg, // apply the poison - "ldr <<Prop:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the property + "ldr <<Prop:r[0-9]+>>, \\[<<BSt>>, #\\+[0-9]+\\]", // load the property "and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison // Ldone: }; @@ -109,5 +113,43 @@ TEST(DisasmPoisonPolymorphicLoad) { #endif // ENABLE_DISASSEMBLER } +TEST(DisasmPoisonMonomorphicLoadFloat64) { +#ifdef ENABLE_DISASSEMBLER + if (i::FLAG_always_opt || !i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + i::FLAG_untrusted_code_mitigations = true; + + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + CompileRun( + "function mono(o) { return o.x; }" + "%PrepareFunctionForOptimization(mono);" + "mono({ x : 1.1 });" + "mono({ x : 1.1 });" + "%OptimizeFunctionOnNextCall(mono);" + "mono({ x : 1.1 });"); + + // Matches that the property access sequence is instrumented with + // poisoning. + std::vector<std::string> patterns_array = { + "ldr <<Map:r[0-9]+>>, \\[<<Obj:r[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:r[0-9]+>>, \\[pc, #", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "bne", // deopt if different + "eorne " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison + "csdb", // spec. barrier + "ldr <<Field:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the field + "and <<Field>>, <<Field>>, " + kPReg, // apply the poison + "mov <<Mov:r[0-9]+>>, #[0-9]+", // addr. calculation + "add ip, <<Field>>, <<Mov>>", // addr. calculation + "and ip, ip, " + kPReg, // apply the poison + "vldr d[0-9]+, \\[ip", // load Float64 + }; + CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array)); +#endif // ENABLE_DISASSEMBLER +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-poison-disasm-arm64.cc b/deps/v8/test/cctest/test-poison-disasm-arm64.cc index a428ce7b89..32f4315e3a 100644 --- a/deps/v8/test/cctest/test-poison-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-poison-disasm-arm64.cc @@ -24,6 +24,8 @@ const std::string kPReg = // NOLINT(runtime/string) TEST(DisasmPoisonMonomorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -49,7 +51,7 @@ TEST(DisasmPoisonMonomorphicLoad) { "b.ne", // deopt if different "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldursw x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field + "ldur w<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field "and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison }; #else @@ -71,6 +73,8 @@ TEST(DisasmPoisonMonomorphicLoad) { TEST(DisasmPoisonPolymorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -113,7 +117,7 @@ TEST(DisasmPoisonPolymorphicLoad) { // Lcase1: "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldursw x<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store + "ldur w<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store // branchful decompress "add x<<BSt>>, x26, x<<BSt>>", // Add root to ref "and x<<BSt>>, x<<BSt>>, " + kPReg, // apply the poison @@ -135,9 +139,13 @@ TEST(DisasmPoisonPolymorphicLoad) { "b.ne", // deopt if different "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldur <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field - "and <<Field>>, <<Field>>, " + kPReg, // apply the poison - "asr x[0-9]+, <<Field>>, #32", // untag + "ldur x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field + "and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison +#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH + "asr w<<Field>>, w<<Field>>, #1", // untag +#else + "asr x[0-9]+, x<<Field>>, #32", // untag +#endif "b", // goto merge point // Lcase1: "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison @@ -153,5 +161,65 @@ TEST(DisasmPoisonPolymorphicLoad) { #endif // ENABLE_DISASSEMBLER } +TEST(DisasmPoisonMonomorphicLoadFloat64) { +#ifdef ENABLE_DISASSEMBLER + if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; + + i::FLAG_allow_natives_syntax = true; + i::FLAG_untrusted_code_mitigations = true; + + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + CompileRun( + "function mono(o) { return o.x; }" + "%PrepareFunctionForOptimization(mono);" + "mono({ x : 1.1 });" + "mono({ x : 1.1 });" + "%OptimizeFunctionOnNextCall(mono);" + "mono({ x : 1.1 });"); + + // Matches that the property access sequence is instrumented with + // poisoning. +#if defined(V8_COMPRESS_POINTERS) + std::vector<std::string> patterns_array = { + "ldur <<Map:w[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:w[0-9]+>>, pc", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "b.ne", // deopt if differ + "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison + "csdb", // spec. barrier + "ldur w<<F1:[0-9]+>>, \\[<<Obj>>, #11\\]", // load heap number + "add x<<F1>>, x26, x<<F1>>", // Decompress ref + "and x<<F1>>, x<<F1>>, " + kPReg, // apply the poison + "add <<Addr:x[0-9]+>>, x<<F1>>, #0x[0-9a-f]+", // addr. calculation + "and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison + "ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64 + }; +#else + std::vector<std::string> patterns_array = { + "ldur <<Map:x[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:x[0-9]+>>, pc", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "b.ne", // deopt if differ + "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison + "csdb", // spec. barrier +#if V8_DOUBLE_FIELDS_UNBOXING + "add <<Addr:x[0-9]+>>, <<Obj>>, #0x[0-9a-f]+", // addr. calculation +#else + "ldur <<F1:x[0-9]+>>, \\[<<Obj>>, #23\\]", // load heap number + "and <<F1>>, <<F1>>, " + kPReg, // apply the poison + "add <<Addr:x[0-9]+>>, <<F1>>, #0x7", // addr. calculation +#endif + "and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison + "ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64 + }; +#endif + CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array)); +#endif // ENABLE_DISASSEMBLER +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index ccebabec30..5cfc4df2a3 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -674,13 +674,12 @@ static const char* line_number_test_source_profile_time_functions = "bar_at_the_second_line();\n" "function lazy_func_at_6th_line() {}"; -int GetFunctionLineNumber(CpuProfiler& profiler, // NOLINT(runtime/references) - LocalContext& env, // NOLINT(runtime/references) +int GetFunctionLineNumber(CpuProfiler* profiler, LocalContext* env, const char* name) { - CodeMap* code_map = profiler.generator()->code_map(); + CodeMap* code_map = profiler->generator()->code_map(); i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(env.local(), v8_str(name)).ToLocalChecked()))); + (*env)->Global()->Get(env->local(), v8_str(name)).ToLocalChecked()))); CodeEntry* func_entry = code_map->FindEntry(func->abstract_code().InstructionStart()); if (!func_entry) FATAL("%s", name); @@ -705,12 +704,12 @@ TEST(LineNumber) { profiler.processor()->StopSynchronously(); bool is_lazy = i::FLAG_lazy; - CHECK_EQ(1, GetFunctionLineNumber(profiler, env, "foo_at_the_first_line")); + CHECK_EQ(1, GetFunctionLineNumber(&profiler, &env, "foo_at_the_first_line")); CHECK_EQ(is_lazy ? 0 : 4, - GetFunctionLineNumber(profiler, env, "lazy_func_at_forth_line")); - CHECK_EQ(2, GetFunctionLineNumber(profiler, env, "bar_at_the_second_line")); + GetFunctionLineNumber(&profiler, &env, "lazy_func_at_forth_line")); + CHECK_EQ(2, GetFunctionLineNumber(&profiler, &env, "bar_at_the_second_line")); CHECK_EQ(is_lazy ? 0 : 6, - GetFunctionLineNumber(profiler, env, "lazy_func_at_6th_line")); + GetFunctionLineNumber(&profiler, &env, "lazy_func_at_6th_line")); profiler.StopProfiling("LineNumber"); } diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 1374673c61..95e752bece 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -38,6 +38,7 @@ #include "src/objects/js-regexp-inl.h" #include "src/objects/objects-inl.h" #include "src/regexp/regexp-bytecode-generator.h" +#include "src/regexp/regexp-bytecodes.h" #include "src/regexp/regexp-compiler.h" #include "src/regexp/regexp-interpreter.h" #include "src/regexp/regexp-macro-assembler-arch.h" @@ -1744,19 +1745,6 @@ TEST(UseCountRegExp) { CHECK_EQ(2, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]); CHECK(resultToStringError->IsObject()); - - // Increment a UseCounter when .matchAll() is used with a non-global - // regular expression. - CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - v8::Local<v8::Value> resultReMatchAllNonGlobal = - CompileRun("'a'.matchAll(/./)"); - CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - CHECK(resultReMatchAllNonGlobal->IsObject()); - // Don't increment the counter for global regular expressions. - v8::Local<v8::Value> resultReMatchAllGlobal = - CompileRun("'a'.matchAll(/./g)"); - CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - CHECK(resultReMatchAllGlobal->IsObject()); } class UncachedExternalString @@ -1783,6 +1771,567 @@ TEST(UncachedExternalString) { ExpectString("external.substring(1).match(re)[1]", "z"); } +// Test bytecode peephole optimization + +void CreatePeepholeNoChangeBytecode(RegExpMacroAssembler* m) { + Label fail, backtrack; + m->PushBacktrack(&fail); + m->CheckNotAtStart(0, nullptr); + m->LoadCurrentCharacter(2, nullptr); + m->CheckNotCharacter('o', nullptr); + m->LoadCurrentCharacter(1, nullptr, false); + m->CheckNotCharacter('o', nullptr); + m->LoadCurrentCharacter(0, nullptr, false); + m->CheckNotCharacter('f', nullptr); + m->WriteCurrentPositionToRegister(0, 0); + m->WriteCurrentPositionToRegister(1, 3); + m->AdvanceCurrentPosition(3); + m->PushBacktrack(&backtrack); + m->Succeed(); + m->Bind(&backtrack); + m->Backtrack(); + m->Bind(&fail); + m->Fail(); +} + +TEST(PeepholeNoChange) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeNoChangeBytecode(&orig); + CreatePeepholeNoChangeBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("^foo"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + byte* byte_array = array->GetDataStartAddress(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + byte* byte_array_optimized = array_optimized->GetDataStartAddress(); + + CHECK_EQ(0, memcmp(byte_array, byte_array_optimized, length)); +} + +void CreatePeepholeSkipUntilCharBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilChar) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharBytecode(&orig); + CreatePeepholeSkipUntilCharBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, + array_optimized->get(RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR))); +} + +void CreatePeepholeSkipUntilBitInTableBytecode(RegExpMacroAssembler* m, + Factory* factory) { + Handle<ByteArray> bit_table = factory->NewByteArray( + RegExpMacroAssembler::kTableSize, AllocationType::kOld); + for (uint32_t i = 0; i < RegExpMacroAssembler::kTableSize; i++) { + bit_table->set(i, 0); + } + + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckBitInTable(bit_table, nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilBitInTable) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilBitInTableBytecode(&orig, factory); + CreatePeepholeSkipUntilBitInTableBytecode(&opt, factory); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_BIT_IN_TABLE, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get( + RegExpBytecodeLength(BC_SKIP_UNTIL_BIT_IN_TABLE))); +} + +void CreatePeepholeSkipUntilCharPosCheckedBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true, 1, 2); + m->CheckCharacter('x', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharPosChecked) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharPosCheckedBytecode(&orig); + CreatePeepholeSkipUntilCharPosCheckedBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_CHECK_CURRENT_POSITION) + + RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR_UNCHECKED) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_POS_CHECKED) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_POS_CHECKED, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get(RegExpBytecodeLength( + BC_SKIP_UNTIL_CHAR_POS_CHECKED))); +} + +void CreatePeepholeSkipUntilCharAndBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true, 1, 2); + m->CheckCharacterAfterAnd('x', 0xFF, nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharAnd) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharAndBytecode(&orig); + CreatePeepholeSkipUntilCharAndBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_CHECK_CURRENT_POSITION) + + RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR_UNCHECKED) + + RegExpBytecodeLength(BC_AND_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_AND) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_AND, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, + array_optimized->get(RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_AND))); +} + +void CreatePeepholeSkipUntilCharOrCharBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharOrChar) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharOrCharBytecode(&orig); + CreatePeepholeSkipUntilCharOrCharBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_OR_CHAR) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_OR_CHAR, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get( + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_OR_CHAR))); +} + +void CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(RegExpMacroAssembler* m, + Factory* factory) { + Handle<ByteArray> bit_table = factory->NewByteArray( + RegExpMacroAssembler::kTableSize, AllocationType::kOld); + for (uint32_t i = 0; i < RegExpMacroAssembler::kTableSize; i++) { + bit_table->set(i, 0); + } + + Label start, end, advance; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacterGT('x', nullptr); + m->CheckBitInTable(bit_table, &advance); + m->GoTo(&end); + m->Bind(&advance); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); + m->Bind(&end); +} + +TEST(PeepholeSkipUntilGtOrNotBitInTable) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(&orig, factory); + CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(&opt, factory); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_GT) + + RegExpBytecodeLength(BC_CHECK_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_GOTO) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get(RegExpBytecodeLength( + BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE))); +} + +void CreatePeepholeLabelFixupsInsideBytecode(RegExpMacroAssembler* m, + Label* dummy_before, + Label* dummy_after, + Label* dummy_inside) { + Label loop; + m->Bind(dummy_before); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_after); + m->CheckCharacter('b', dummy_inside); + m->Bind(&loop); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->Bind(dummy_inside); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop); + m->Bind(dummy_after); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_after); + m->CheckCharacter('b', dummy_inside); +} + +TEST(PeepholeLabelFixupsInside) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + { + Label dummy_before, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsInsideBytecode(&opt, &dummy_before, &dummy_after, + &dummy_inside); + } + Label dummy_before, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsInsideBytecode(&orig, &dummy_before, &dummy_after, + &dummy_inside); + + CHECK_EQ(0x00, dummy_before.pos()); + CHECK_EQ(0x28, dummy_inside.pos()); + CHECK_EQ(0x38, dummy_after.pos()); + + const Label* labels[] = {&dummy_before, &dummy_after, &dummy_inside}; + const int label_positions[4][3] = { + {0x04, 0x3C}, // dummy_before + {0x0C, 0x44}, // dummy after + {0x14, 0x4C} // dummy inside + }; + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + + for (int label_idx = 0; label_idx < 3; label_idx++) { + for (int pos_idx = 0; pos_idx < 2; pos_idx++) { + CHECK_EQ(labels[label_idx]->pos(), + array->get(label_positions[label_idx][pos_idx])); + } + } + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + + const int pos_fixups[] = { + 0, // Position before optimization should be unchanged. + 4, // Position after first replacement should be 4 (optimized size (20) - + // original size (32) + preserve length (16)). + }; + const int target_fixups[] = { + 0, // dummy_before should be unchanged + 4, // dummy_inside should be 4 + 4 // dummy_after should be 4 + }; + + for (int label_idx = 0; label_idx < 3; label_idx++) { + for (int pos_idx = 0; pos_idx < 2; pos_idx++) { + int label_pos = label_positions[label_idx][pos_idx] + pos_fixups[pos_idx]; + int jump_address = *reinterpret_cast<uint32_t*>( + array_optimized->GetDataStartAddress() + label_pos); + int expected_jump_address = + labels[label_idx]->pos() + target_fixups[label_idx]; + CHECK_EQ(expected_jump_address, jump_address); + } + } +} + +void CreatePeepholeLabelFixupsComplexBytecode(RegExpMacroAssembler* m, + Label* dummy_before, + Label* dummy_between, + Label* dummy_after, + Label* dummy_inside) { + Label loop1, loop2; + m->Bind(dummy_before); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); + m->Bind(&loop1); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop1); + m->Bind(dummy_between); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); + m->Bind(&loop2); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->Bind(dummy_inside); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop2); + m->Bind(dummy_after); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); +} + +TEST(PeepholeLabelFixupsComplex) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + { + Label dummy_before, dummy_between, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsComplexBytecode( + &opt, &dummy_before, &dummy_between, &dummy_after, &dummy_inside); + } + Label dummy_before, dummy_between, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsComplexBytecode(&orig, &dummy_before, &dummy_between, + &dummy_after, &dummy_inside); + + CHECK_EQ(0x00, dummy_before.pos()); + CHECK_EQ(0x40, dummy_between.pos()); + CHECK_EQ(0x70, dummy_inside.pos()); + CHECK_EQ(0x80, dummy_after.pos()); + + const Label* labels[] = {&dummy_before, &dummy_between, &dummy_after, + &dummy_inside}; + const int label_positions[4][3] = { + {0x04, 0x44, 0x84}, // dummy_before + {0x0C, 0x4C, 0x8C}, // dummy between + {0x14, 0x54, 0x94}, // dummy after + {0x1C, 0x5C, 0x9C} // dummy inside + }; + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + + for (int label_idx = 0; label_idx < 4; label_idx++) { + for (int pos_idx = 0; pos_idx < 3; pos_idx++) { + CHECK_EQ(labels[label_idx]->pos(), + array->get(label_positions[label_idx][pos_idx])); + } + } + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + + const int pos_fixups[] = { + 0, // Position before optimization should be unchanged. + -12, // Position after first replacement should be -12 (optimized size = + // 20 - 32 = original size). + -8 // Position after second replacement should be -8 (-12 from first + // optimization -12 from second optimization + 16 preserved + // bytecodes). + }; + const int target_fixups[] = { + 0, // dummy_before should be unchanged + -12, // dummy_between should be -12 + -8, // dummy_inside should be -8 + -8 // dummy_after should be -8 + }; + + for (int label_idx = 0; label_idx < 4; label_idx++) { + for (int pos_idx = 0; pos_idx < 3; pos_idx++) { + int label_pos = label_positions[label_idx][pos_idx] + pos_fixups[pos_idx]; + int jump_address = *reinterpret_cast<uint32_t*>( + array_optimized->GetDataStartAddress() + label_pos); + int expected_jump_address = + labels[label_idx]->pos() + target_fixups[label_idx]; + CHECK_EQ(expected_jump_address, jump_address); + } + } +} + #undef CHECK_PARSE_ERROR #undef CHECK_SIMPLE #undef CHECK_MIN_MAX diff --git a/deps/v8/test/cctest/test-roots.cc b/deps/v8/test/cctest/test-roots.cc index d041903639..f3d1a56543 100644 --- a/deps/v8/test/cctest/test-roots.cc +++ b/deps/v8/test/cctest/test-roots.cc @@ -46,8 +46,8 @@ bool IsInitiallyMutable(Factory* factory, Address object_address) { V(detached_contexts) \ V(dirty_js_finalization_groups) \ V(feedback_vectors_for_profiling_tools) \ + V(shared_wasm_memories) \ V(materialized_objects) \ - V(noscript_shared_function_infos) \ V(public_symbol_table) \ V(retained_maps) \ V(retaining_path_targets) \ diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 407437c4b1..e2ab996796 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -98,8 +98,7 @@ class TestSerializer { return v8_isolate; } - static v8::Isolate* NewIsolateFromBlob( - StartupBlobs& blobs) { // NOLINT(runtime/references) + static v8::Isolate* NewIsolateFromBlob(const StartupBlobs& blobs) { SnapshotData startup_snapshot(blobs.startup); SnapshotData read_only_snapshot(blobs.read_only); ReadOnlyDeserializer read_only_deserializer(&read_only_snapshot); @@ -204,8 +203,7 @@ Vector<const uint8_t> ConstructSource(Vector<const uint8_t> head, source_length); } -static v8::Isolate* Deserialize( - StartupBlobs& blobs) { // NOLINT(runtime/references) +static v8::Isolate* Deserialize(const StartupBlobs& blobs) { v8::Isolate* isolate = TestSerializer::NewIsolateFromBlob(blobs); CHECK(isolate); return isolate; @@ -1522,7 +1520,8 @@ TEST(CodeSerializerWithProfiler) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1563,7 +1562,8 @@ TEST(CodeSerializerWithProfiler) { void TestCodeSerializerOnePlusOneImpl(bool verify_builtins_count = true) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1676,7 +1676,8 @@ TEST(CodeSerializerPromotedToCompilationCache) { TEST(CodeSerializerInternalizedString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1734,7 +1735,8 @@ TEST(CodeSerializerInternalizedString) { TEST(CodeSerializerLargeCodeObject) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1793,7 +1795,8 @@ TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1863,7 +1866,8 @@ TEST(CodeSerializerLargeStrings) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Factory* f = isolate->factory(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1919,7 +1923,8 @@ TEST(CodeSerializerThreeBigStrings) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Factory* f = isolate->factory(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -2038,7 +2043,8 @@ class SerializerTwoByteResource : public v8::String::ExternalStringResource { TEST(CodeSerializerExternalString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -2104,7 +2110,8 @@ TEST(CodeSerializerExternalString) { TEST(CodeSerializerLargeExternalString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. Factory* f = isolate->factory(); @@ -2164,7 +2171,8 @@ TEST(CodeSerializerLargeExternalString) { TEST(CodeSerializerExternalScriptName) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. Factory* f = isolate->factory(); @@ -3606,13 +3614,13 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) { // We can introduce new extensions, which could override functions already // in the snapshot. auto extension = - base::make_unique<v8::Extension>("new extension", - "function i() { return 24; }" - "function j() { return 25; }" - "let a = 26;" - "try {" - " if (o.p == 7) o.p++;" - "} catch {}"); + std::make_unique<v8::Extension>("new extension", + "function i() { return 24; }" + "function j() { return 25; }" + "let a = 26;" + "try {" + " if (o.p == 7) o.p++;" + "} catch {}"); extension->set_auto_enable(true); v8::RegisterExtension(std::move(extension)); { @@ -3900,7 +3908,7 @@ UNINITIALIZED_TEST(WeakArraySerializationInSnapshot) { TEST(WeakArraySerializationInCodeCache) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); + isolate->compilation_cache()->DisableScriptAndEval(); v8::HandleScope scope(CcTest::isolate()); @@ -3929,7 +3937,8 @@ TEST(CachedCompileFunctionInContext) { DisableAlwaysOpt(); LocalContext env; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); diff --git a/deps/v8/test/cctest/test-smi-lexicographic-compare.cc b/deps/v8/test/cctest/test-smi-lexicographic-compare.cc index 914444c634..7b3e600c14 100644 --- a/deps/v8/test/cctest/test-smi-lexicographic-compare.cc +++ b/deps/v8/test/cctest/test-smi-lexicographic-compare.cc @@ -14,11 +14,11 @@ namespace internal { namespace { -void AddSigned(std::set<Smi>& smis, int64_t x) { // NOLINT(runtime/references) +void AddSigned(std::set<Smi>* smis, int64_t x) { if (!Smi::IsValid(x)) return; - smis.insert(Smi::FromInt(static_cast<int>(x))); - smis.insert(Smi::FromInt(static_cast<int>(-x))); + smis->insert(Smi::FromInt(static_cast<int>(x))); + smis->insert(Smi::FromInt(static_cast<int>(-x))); } // Uses std::lexicographical_compare twice to convert the result to -1, 0 or 1. @@ -58,14 +58,14 @@ TEST(TestSmiLexicographicCompare) { for (int64_t xb = 1; xb <= Smi::kMaxValue; xb *= 10) { for (int64_t xf = 0; xf <= 9; ++xf) { for (int64_t xo = -1; xo <= 1; ++xo) { - AddSigned(smis, xb * xf + xo); + AddSigned(&smis, xb * xf + xo); } } } for (int64_t yb = 1; yb <= Smi::kMaxValue; yb *= 2) { for (int64_t yo = -2; yo <= 2; ++yo) { - AddSigned(smis, yb + yo); + AddSigned(&smis, yb + yo); } } diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index 796f38a73b..f64c044a0c 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -1857,6 +1857,48 @@ GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING( #undef GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING +namespace { + +struct IndexData { + const char* string; + bool is_array_index; + uint32_t array_index; + bool is_integer_index; + size_t integer_index; +}; + +void TestString(i::Isolate* isolate, const IndexData& data) { + Handle<String> s = isolate->factory()->NewStringFromAsciiChecked(data.string); + if (data.is_array_index) { + uint32_t index; + CHECK(s->AsArrayIndex(&index)); + CHECK_EQ(data.array_index, index); + // AsArrayIndex only forces hash computation for cacheable indices; + // so trigger hash computation for longer strings manually. + if (s->length() > String::kMaxCachedArrayIndexLength) s->Hash(); + CHECK_EQ(0, s->hash_field() & String::kIsNotArrayIndexMask); + CHECK(s->HasHashCode()); + } + if (data.is_integer_index) { + size_t index; + CHECK(s->AsIntegerIndex(&index)); + CHECK_EQ(data.integer_index, index); + s->Hash(); + CHECK_EQ(0, s->hash_field() & String::kIsNotIntegerIndexMask); + CHECK(s->HasHashCode()); + } + if (!s->HasHashCode()) s->Hash(); + CHECK(s->HasHashCode()); + if (!data.is_array_index) { + CHECK_NE(0, s->hash_field() & String::kIsNotArrayIndexMask); + } + if (!data.is_integer_index) { + CHECK_NE(0, s->hash_field() & String::kIsNotIntegerIndexMask); + } +} + +} // namespace + TEST(HashArrayIndexStrings) { CcTest::InitializeVM(); LocalContext context; @@ -1870,6 +1912,27 @@ TEST(HashArrayIndexStrings) { CHECK_EQ(StringHasher::MakeArrayIndexHash(1 /* value */, 1 /* length */) >> Name::kHashShift, isolate->factory()->one_string()->Hash()); + + IndexData tests[] = { + {"", false, 0, false, 0}, + {"123no", false, 0, false, 0}, + {"12345", true, 12345, true, 12345}, + {"12345678", true, 12345678, true, 12345678}, + {"4294967294", true, 4294967294u, true, 4294967294u}, +#if V8_TARGET_ARCH_32_BIT + {"4294967295", false, 0, false, 0}, // Valid length but not index. + {"4294967296", false, 0, false, 0}, + {"18446744073709551615", false, 0, false, 0}, +#else + {"4294967295", false, 0, true, 4294967295u}, + {"4294967296", false, 0, true, 4294967296ull}, + {"18446744073709551615", false, 0, true, 18446744073709551615ull}, +#endif + {"18446744073709551616", false, 0, false, 0} + }; + for (int i = 0, n = arraysize(tests); i < n; i++) { + TestString(isolate, tests[i]); + } } TEST(StringEquals) { diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 2062724043..5c852d7232 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -75,7 +75,7 @@ TEST(ThreadIdValidation) { ThreadIdValidationThread* prev = i == kNThreads - 1 ? nullptr : threads[i + 1].get(); threads[i] = - base::make_unique<ThreadIdValidationThread>(prev, refs, i, &semaphore); + std::make_unique<ThreadIdValidationThread>(prev, refs, i, &semaphore); } CHECK(threads[0]->Start()); for (int i = 0; i < kNThreads; i++) { diff --git a/deps/v8/test/cctest/test-trace-event.cc b/deps/v8/test/cctest/test-trace-event.cc index 7b3c215d69..0f4a699d8a 100644 --- a/deps/v8/test/cctest/test-trace-event.cc +++ b/deps/v8/test/cctest/test-trace-event.cc @@ -6,7 +6,6 @@ #include "src/init/v8.h" -#include "src/base/template-utils.h" #include "test/cctest/cctest.h" #include "src/tracing/trace-event.h" @@ -55,9 +54,8 @@ class MockTracingController : public v8::TracingController { const uint64_t* arg_values, std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, unsigned int flags, int64_t timestamp) override { - std::unique_ptr<MockTraceObject> to = - v8::base::make_unique<MockTraceObject>( - phase, std::string(name), id, bind_id, num_args, flags, timestamp); + std::unique_ptr<MockTraceObject> to = std::make_unique<MockTraceObject>( + phase, std::string(name), id, bind_id, num_args, flags, timestamp); trace_objects_.push_back(std::move(to)); return 0; } diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc index fb4740cb92..5e715b75e0 100644 --- a/deps/v8/test/cctest/test-typedarrays.cc +++ b/deps/v8/test/cctest/test-typedarrays.cc @@ -7,6 +7,7 @@ #include "src/init/v8.h" #include "test/cctest/cctest.h" +#include "src/execution/protectors-inl.h" #include "src/heap/heap.h" #include "src/objects/objects-inl.h" #include "src/objects/objects.h" @@ -14,12 +15,11 @@ namespace v8 { namespace internal { -void TestArrayBufferViewContents( - LocalContext& env, // NOLINT(runtime/references) - bool should_use_buffer) { +void TestArrayBufferViewContents(LocalContext* env, bool should_use_buffer) { v8::Local<v8::Object> obj_a = v8::Local<v8::Object>::Cast( - env->Global() - ->Get(env->GetIsolate()->GetCurrentContext(), v8_str("a")) + (*env) + ->Global() + ->Get((*env)->GetIsolate()->GetCurrentContext(), v8_str("a")) .ToLocalChecked()); CHECK(obj_a->IsArrayBufferView()); v8::Local<v8::ArrayBufferView> array_buffer_view = @@ -43,7 +43,7 @@ TEST(CopyContentsTypedArray) { "a[1] = 1;" "a[2] = 2;" "a[3] = 3;"); - TestArrayBufferViewContents(env, false); + TestArrayBufferViewContents(&env, false); } @@ -51,7 +51,7 @@ TEST(CopyContentsArray) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); CompileRun("var a = new Uint8Array([0, 1, 2, 3]);"); - TestArrayBufferViewContents(env, false); + TestArrayBufferViewContents(&env, false); } @@ -68,7 +68,7 @@ TEST(CopyContentsView) { "c[4] = 2;" "c[5] = 3;" "var a = new DataView(b, 2);"); - TestArrayBufferViewContents(env, true); + TestArrayBufferViewContents(&env, true); } @@ -82,7 +82,7 @@ TEST(AllocateNotExternal) { v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024, v8::ArrayBufferCreationMode::kInternalized); CHECK(!buffer->IsExternal()); - CHECK_EQ(memory, buffer->GetContents().Data()); + CHECK_EQ(memory, buffer->GetBackingStore()->Data()); } void TestSpeciesProtector(char* code, @@ -115,12 +115,12 @@ void TestSpeciesProtector(char* code, v8::internal::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate); - CHECK(i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); CompileRun(code); if (invalidates_species_protector) { - CHECK(!i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(!Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); } else { - CHECK(i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); } v8::Local<v8::Value> my_typed_array = CompileRun("MyTypedArray"); diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc index 9cfc40d37d..ebeb05597e 100644 --- a/deps/v8/test/cctest/test-unboxed-doubles.cc +++ b/deps/v8/test/cctest/test-unboxed-doubles.cc @@ -78,8 +78,9 @@ static double GetDoubleFieldValue(JSObject obj, FieldIndex field_index) { } } -void WriteToField(JSObject object, int descriptor, Object value) { +void WriteToField(JSObject object, int index, Object value) { DescriptorArray descriptors = object.map().instance_descriptors(); + InternalIndex descriptor(index); PropertyDetails details = descriptors.GetDetails(descriptor); object.WriteToField(descriptor, details, value); } @@ -811,7 +812,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull( Handle<Map> map; // Now check layout descriptors of all intermediate maps. for (int i = 0; i < number_of_descriptors; i++) { - PropertyDetails details = descriptors->GetDetails(i); + PropertyDetails details = descriptors->GetDetails(InternalIndex(i)); map = maps[i]; LayoutDescriptor layout_desc = map->layout_descriptor(); @@ -962,7 +963,7 @@ TEST(Regress436816) { CHECK(fake_object.IsHeapObject()); uint64_t boom_value = bit_cast<uint64_t>(fake_object); - for (int i = 0; i < kPropsCount; i++) { + for (InternalIndex i : InternalIndex::Range(kPropsCount)) { FieldIndex index = FieldIndex::ForDescriptor(*map, i); CHECK(map->IsUnboxedDoubleField(index)); object->RawFastDoublePropertyAsBitsAtPut(index, boom_value); @@ -1100,7 +1101,7 @@ TEST(DoScavenge) { { // Ensure the object is properly set up. - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(0)); CHECK(field_index.is_inobject() && field_index.is_double()); CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index)); @@ -1119,7 +1120,8 @@ TEST(DoScavenge) { Address fake_object = temp->ptr() + kSystemPointerSize; double boom_value = bit_cast<double>(fake_object); - FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0); + FieldIndex field_index = + FieldIndex::ForDescriptor(obj->map(), InternalIndex(0)); auto boom_number = factory->NewHeapNumber(boom_value); obj->FastPropertyAtPut(field_index, *boom_number); @@ -1182,12 +1184,12 @@ TEST(DoScavengeWithIncrementalWriteBarrier) { { // Ensure the object is properly set up. - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(0)); CHECK(field_index.is_inobject() && field_index.is_double()); CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index)); - field_index = FieldIndex::ForDescriptor(*map, 1); + field_index = FieldIndex::ForDescriptor(*map, InternalIndex(1)); CHECK(field_index.is_inobject() && !field_index.is_double()); CHECK(!map->IsUnboxedDoubleField(field_index)); } @@ -1225,7 +1227,7 @@ TEST(DoScavengeWithIncrementalWriteBarrier) { // |obj_value| must be evacuated. CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(*obj_value)); - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 1); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(1)); CHECK_EQ(*obj_value, obj->RawFastPropertyAt(field_index)); } @@ -1248,7 +1250,7 @@ static void TestLayoutDescriptorHelper(Isolate* isolate, int end_offset = instance_size * 2; int first_non_tagged_field_offset = end_offset; - for (int i = 0; i < number_of_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(number_of_descriptors)) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; FieldIndex index = FieldIndex::ForDescriptor(*map, i); @@ -1430,9 +1432,9 @@ TEST(LayoutDescriptorSharing) { CHECK(map2->layout_descriptor().IsConsistentWithMap(*map2, true)); } - static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, - int tagged_descriptor, int double_descriptor, + InternalIndex tagged_descriptor, + InternalIndex double_descriptor, bool check_tagged_value = true) { FLAG_stress_compaction = true; FLAG_manual_evacuation_candidates_selection = true; @@ -1491,10 +1493,9 @@ static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, CHECK_EQ(boom_value, obj->RawFastDoublePropertyAsBitsAt(double_field_index)); } - static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map, - int tagged_descriptor, - int double_descriptor, + InternalIndex tagged_descriptor, + InternalIndex double_descriptor, bool check_tagged_value = true) { if (FLAG_never_compact || !FLAG_incremental_marking) return; ManualGCScope manual_gc_scope; @@ -1607,14 +1608,16 @@ static void TestWriteBarrierObjectShiftFieldsRight( .ToHandleChecked(); // Shift fields right by turning constant property to a field. - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::Tagged(), any_type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(0), kData, NONE, + Representation::Tagged(), any_type); if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { - TestWriteBarrier(map, new_map, 2, 1); + TestWriteBarrier(map, new_map, InternalIndex(2), InternalIndex(1)); } else { CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); - TestIncrementalWriteBarrier(map, new_map, 2, 1); + TestIncrementalWriteBarrier(map, new_map, InternalIndex(2), + InternalIndex(1)); } } diff --git a/deps/v8/test/cctest/torque/test-torque.cc b/deps/v8/test/cctest/torque/test-torque.cc index 184a867946..5cf70f3374 100644 --- a/deps/v8/test/cctest/torque/test-torque.cc +++ b/deps/v8/test/cctest/torque/test-torque.cc @@ -26,7 +26,6 @@ namespace compiler { namespace { -using Label = CodeAssemblerLabel; using Variable = CodeAssemblerVariable; class TestTorqueAssembler : public CodeStubAssembler { diff --git a/deps/v8/test/cctest/wasm/OWNERS b/deps/v8/test/cctest/wasm/OWNERS index dc68b39733..16b08f3b3b 100644 --- a/deps/v8/test/cctest/wasm/OWNERS +++ b/deps/v8/test/cctest/wasm/OWNERS @@ -1,5 +1,5 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org titzer@chromium.org # COMPONENT: Blink>JavaScript>WebAssembly diff --git a/deps/v8/test/cctest/wasm/test-grow-memory.cc b/deps/v8/test/cctest/wasm/test-grow-memory.cc new file mode 100644 index 0000000000..a188707cae --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-grow-memory.cc @@ -0,0 +1,131 @@ +// Copyright 2019 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. + +#include "src/wasm/wasm-objects-inl.h" +#include "src/wasm/wasm-opcodes.h" + +#include "src/wasm/wasm-module-builder.h" +#include "test/cctest/cctest.h" +#include "test/cctest/manually-externalized-buffer.h" +#include "test/common/wasm/flag-utils.h" +#include "test/common/wasm/test-signatures.h" +#include "test/common/wasm/wasm-macro-gen.h" +#include "test/common/wasm/wasm-module-runner.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace test_grow_memory { + +using testing::CompileAndInstantiateForTesting; +using v8::internal::testing::ManuallyExternalizedBuffer; + +namespace { +void ExportAsMain(WasmFunctionBuilder* f) { + f->builder()->AddExport(CStrVector("main"), f); +} +#define EMIT_CODE_WITH_END(f, code) \ + do { \ + f->EmitCode(code, sizeof(code)); \ + f->Emit(kExprEnd); \ + } while (false) + +void Cleanup(Isolate* isolate = CcTest::InitIsolateOnce()) { + // By sending a low memory notifications, we will try hard to collect all + // garbage and will therefore also invoke all weak callbacks of actually + // unreachable persistent handles. + reinterpret_cast<v8::Isolate*>(isolate)->LowMemoryNotification(); +} +} // namespace + +TEST(GrowMemDetaches) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<WasmMemoryObject> memory_object = + WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared) + .ToHandleChecked(); + Handle<JSArrayBuffer> buffer(memory_object->array_buffer(), isolate); + int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK_EQ(16, result); + CHECK_NE(*buffer, memory_object->array_buffer()); + CHECK(buffer->was_detached()); + } + Cleanup(); +} + +TEST(Externalized_GrowMemMemSize) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<WasmMemoryObject> memory_object = + WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared) + .ToHandleChecked(); + ManuallyExternalizedBuffer external( + handle(memory_object->array_buffer(), isolate)); + int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK_EQ(16, result); + CHECK_NE(*external.buffer_, memory_object->array_buffer()); + CHECK(external.buffer_->was_detached()); + } + Cleanup(); +} + +TEST(Run_WasmModule_Buffer_Externalized_GrowMem) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + TestSignatures sigs; + v8::internal::AccountingAllocator allocator; + Zone zone(&allocator, ZONE_NAME); + + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); + ExportAsMain(f); + byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP, + WASM_MEMORY_SIZE}; + EMIT_CODE_WITH_END(f, code); + + ZoneBuffer buffer(&zone); + builder->WriteTo(&buffer); + testing::SetupIsolateForWasmModule(isolate); + ErrorThrower thrower(isolate, "Test"); + const Handle<WasmInstanceObject> instance = + CompileAndInstantiateForTesting( + isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end())) + .ToHandleChecked(); + Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); + + // Fake the Embedder flow by externalizing the array buffer. + ManuallyExternalizedBuffer external1( + handle(memory_object->array_buffer(), isolate)); + + // Grow using the API. + uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4); + CHECK_EQ(16, result); + CHECK(external1.buffer_->was_detached()); // growing always detaches + CHECK_EQ(0, external1.buffer_->byte_length()); + + CHECK_NE(*external1.buffer_, memory_object->array_buffer()); + + // Fake the Embedder flow by externalizing the array buffer. + ManuallyExternalizedBuffer external2( + handle(memory_object->array_buffer(), isolate)); + + // Grow using an internal WASM bytecode. + result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr); + CHECK_EQ(26, result); + CHECK(external2.buffer_->was_detached()); // growing always detaches + CHECK_EQ(0, external2.buffer_->byte_length()); + CHECK_NE(*external2.buffer_, memory_object->array_buffer()); + } + Cleanup(); +} + +} // namespace test_grow_memory +} // namespace wasm +} // namespace internal +} // namespace v8 + +#undef EMIT_CODE_WITH_END diff --git a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc index 556d74daef..d3aa75a64e 100644 --- a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc +++ b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc @@ -36,7 +36,7 @@ constexpr size_t kThunkBufferSize = AssemblerBase::kMinimalBufferSize; #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 constexpr uint32_t kAvailableBufferSlots = - (kMaxWasmCodeMemory - kJumpTableSize) / kThunkBufferSize; + (kMaxWasmCodeSpaceSize - kJumpTableSize) / kThunkBufferSize; constexpr uint32_t kBufferSlotStartOffset = RoundUp<kThunkBufferSize>(kJumpTableSize); #else @@ -49,7 +49,7 @@ Address AllocateJumpTableThunk( std::vector<std::unique_ptr<TestingAssemblerBuffer>>* thunk_buffers) { #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 // To guarantee that the branch range lies within the near-call range, - // generate the thunk in the same (kMaxWasmCodeMemory-sized) buffer as the + // generate the thunk in the same (kMaxWasmCodeSpaceSize-sized) buffer as the // jump_target itself. // // Allocate a slot that we haven't already used. This is necessary because @@ -181,11 +181,13 @@ class JumpTablePatcher : public v8::base::Thread { // Then, repeatedly patch the jump table to jump to one of the two thunks. constexpr int kNumberOfPatchIterations = 64; for (int i = 0; i < kNumberOfPatchIterations; ++i) { - TRACE(" patcher %p patch slot " V8PRIxPTR_FMT " to thunk #%d\n", this, - slot_address, i % 2); + TRACE(" patcher %p patch slot " V8PRIxPTR_FMT + " to thunk #%d (" V8PRIxPTR_FMT ")\n", + this, slot_address, i % 2, thunks_[i % 2]); base::MutexGuard jump_table_guard(jump_table_mutex_); JumpTableAssembler::PatchJumpTableSlot( - slot_start_, slot_index_, thunks_[i % 2], WasmCode::kFlushICache); + slot_start_ + JumpTableAssembler::JumpSlotIndexToOffset(slot_index_), + kNullAddress, thunks_[i % 2]); } TRACE("Patcher %p is stopping ...\n", this); } @@ -219,11 +221,8 @@ TEST(JumpTablePatchingStress) { // is not reliable enough to guarantee that we can always achieve this with // separate allocations, so for Arm64 we generate all code in a single // kMaxMasmCodeMemory-sized chunk. - // - // TODO(wasm): Currently {kMaxWasmCodeMemory} limits code sufficiently, so - // that the jump table only supports {near_call} distances. - STATIC_ASSERT(kMaxWasmCodeMemory >= kJumpTableSize); - auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeMemory); + STATIC_ASSERT(kMaxWasmCodeSpaceSize >= kJumpTableSize); + auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeSpaceSize); byte* thunk_slot_buffer = buffer->start() + kBufferSlotStartOffset; #else auto buffer = AllocateAssemblerBuffer(kJumpTableSize); @@ -242,8 +241,9 @@ TEST(JumpTablePatchingStress) { std::vector<std::unique_ptr<TestingAssemblerBuffer>> thunk_buffers; // Patch the jump table slot to jump to itself. This will later be patched // by the patchers. - JumpTableAssembler::PatchJumpTableSlot( - slot_start, slot, slot_start + slot_offset, WasmCode::kFlushICache); + Address slot_addr = + slot_start + JumpTableAssembler::JumpSlotIndexToOffset(slot); + JumpTableAssembler::PatchJumpTableSlot(slot_addr, kNullAddress, slot_addr); // For each patcher, generate two thunks where this patcher can emit code // which finally jumps back to {slot} in the jump table. std::vector<Address> patcher_thunks; diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc index 3f96f8720f..09d1eb7fda 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc @@ -1502,7 +1502,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) { std::vector<byte> code; for (byte p = 0; p < num_params; p++) { - ADD_CODE(code, kExprGetLocal, p); + ADD_CODE(code, kExprLocalGet, p); } ADD_CODE(code, kExprI32Const, 0); ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO); @@ -1563,7 +1563,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) { // Store the result in a local. byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result)); - ADD_CODE(code, kExprSetLocal, local_index); + ADD_CODE(code, kExprLocalSet, local_index); // Store the result in memory. ADD_CODE(code, diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc index e794c00ece..d2ac3434df 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc @@ -13,11 +13,10 @@ namespace wasm { namespace test_run_wasm_bulk_memory { namespace { -void CheckMemoryEquals( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - size_t index, const std::vector<byte>& expected) { - const byte* mem_start = builder.raw_mem_start<byte>(); - const byte* mem_end = builder.raw_mem_end<byte>(); +void CheckMemoryEquals(TestingModuleBuilder* builder, size_t index, + const std::vector<byte>& expected) { + const byte* mem_start = builder->raw_mem_start<byte>(); + const byte* mem_end = builder->raw_mem_end<byte>(); size_t mem_size = mem_end - mem_start; CHECK_LE(index, mem_size); CHECK_LE(index + expected.size(), mem_size); @@ -26,11 +25,10 @@ void CheckMemoryEquals( } } -void CheckMemoryEqualsZero( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - size_t index, size_t length) { - const byte* mem_start = builder.raw_mem_start<byte>(); - const byte* mem_end = builder.raw_mem_end<byte>(); +void CheckMemoryEqualsZero(TestingModuleBuilder* builder, size_t index, + size_t length) { + const byte* mem_start = builder->raw_mem_start<byte>(); + const byte* mem_end = builder->raw_mem_end<byte>(); size_t mem_size = mem_end - mem_start; CHECK_LE(index, mem_size); CHECK_LE(index + length, mem_size); @@ -39,12 +37,11 @@ void CheckMemoryEqualsZero( } } -void CheckMemoryEqualsFollowedByZeroes( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - const std::vector<byte>& expected) { +void CheckMemoryEqualsFollowedByZeroes(TestingModuleBuilder* builder, + const std::vector<byte>& expected) { CheckMemoryEquals(builder, 0, expected); CheckMemoryEqualsZero(builder, expected.size(), - builder.mem_size() - expected.size()); + builder->mem_size() - expected.size()); } } // namespace @@ -60,24 +57,24 @@ WASM_EXEC_TEST(MemoryInit) { kExprI32Const, 0); // All zeroes. - CheckMemoryEqualsZero(r.builder(), 0, kWasmPageSize); + CheckMemoryEqualsZero(&r.builder(), 0, kWasmPageSize); // Copy all bytes from data segment 0, to memory at [10, 20). CHECK_EQ(0, r.Call(10, 0, 10)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy bytes in range [5, 10) from data segment 0, to memory at [0, 5). CHECK_EQ(0, r.Call(0, 5, 5)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy 0 bytes does nothing. CHECK_EQ(0, r.Call(10, 1, 0)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy 0 at end of memory region or data segment is OK. @@ -100,12 +97,12 @@ WASM_EXEC_TEST(MemoryInitOutOfBoundsData) { // Write all values up to the out-of-bounds write. CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, 0, 6)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 1, 2, 3, 4}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 1, 2, 3, 4}); // Write all values up to the out-of-bounds read. r.builder().BlankMemory(); CHECK_EQ(0xDEADBEEF, r.Call(0, 5, 6)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {5, 6, 7, 8, 9}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {5, 6, 7, 8, 9}); } WASM_EXEC_TEST(MemoryInitOutOfBounds) { @@ -155,13 +152,13 @@ WASM_EXEC_TEST(MemoryCopy) { // Copy from [1, 8] to [10, 16]. CHECK_EQ(0, r.Call(10, 1, 8)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77}); // Copy 0 bytes does nothing. CHECK_EQ(0, r.Call(10, 2, 0)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77}); // Copy 0 at end of memory region is OK. @@ -184,12 +181,12 @@ WASM_EXEC_TEST(MemoryCopyOverlapping) { // Copy from [0, 3] -> [2, 5]. The copy must not overwrite 30 before copying // it (i.e. cannot copy forward in this case). CHECK_EQ(0, r.Call(2, 0, 3)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 10, 20, 30}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 10, 20, 30}); // Copy from [2, 5] -> [0, 3]. The copy must not write the first 10 (i.e. // cannot copy backward in this case). CHECK_EQ(0, r.Call(0, 2, 3)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 30, 20, 30}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 30, 20, 30}); } WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) { @@ -209,21 +206,21 @@ WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) { // Copy with source < destination. Copy would happen backwards, // but the first byte to copy is out-of-bounds, so no data should be written. CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, 6)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); // Copy overlapping with destination < source. Copy will happen forwards, up // to the out-of-bounds access. r.builder().BlankMemory(); memcpy(mem + last_5_bytes, data, 5); CHECK_EQ(0xDEADBEEF, r.Call(0, last_5_bytes, kWasmPageSize)); - CheckMemoryEquals(r.builder(), 0, {11, 22, 33, 44, 55}); + CheckMemoryEquals(&r.builder(), 0, {11, 22, 33, 44, 55}); // Copy overlapping with source < destination. Copy would happen backwards, // but the first byte to copy is out-of-bounds, so no data should be written. r.builder().BlankMemory(); memcpy(mem, data, 5); CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, kWasmPageSize)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); } WASM_EXEC_TEST(MemoryCopyOutOfBounds) { @@ -265,15 +262,15 @@ WASM_EXEC_TEST(MemoryFill) { WASM_MEMORY_FILL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)), kExprI32Const, 0); CHECK_EQ(0, r.Call(1, 33, 5)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {0, 33, 33, 33, 33, 33}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 33, 33}); CHECK_EQ(0, r.Call(4, 66, 4)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 66, 66, 66, 66}); // Fill 0 bytes does nothing. CHECK_EQ(0, r.Call(4, 66, 0)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 66, 66, 66, 66}); // Fill 0 at end of memory region is OK. @@ -290,7 +287,7 @@ WASM_EXEC_TEST(MemoryFillValueWrapsToByte) { kExprI32Const, 0); CHECK_EQ(0, r.Call(0, 1000, 3)); const byte expected = 1000 & 255; - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {expected, expected, expected}); } @@ -304,7 +301,7 @@ WASM_EXEC_TEST(MemoryFillOutOfBoundsData) { kExprI32Const, 0); const byte v = 123; CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, v, 999)); - CheckMemoryEquals(r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v}); + CheckMemoryEquals(&r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v}); } WASM_EXEC_TEST(MemoryFillOutOfBounds) { @@ -408,14 +405,13 @@ void CheckTable(Isolate* isolate, Handle<WasmTableObject> table, Args... args) { template <typename WasmRunner, typename... Args> void CheckTableCall(Isolate* isolate, Handle<WasmTableObject> table, - WasmRunner& r, // NOLINT(runtime/references) - uint32_t function_index, Args... args) { + WasmRunner* r, uint32_t function_index, Args... args) { uint32_t args_length = static_cast<uint32_t>(sizeof...(args)); CHECK_EQ(table->current_length(), args_length); double expected[] = {args...}; for (uint32_t i = 0; i < args_length; ++i) { Handle<Object> buffer[] = {isolate->factory()->NewNumber(i)}; - r.CheckCallApplyViaJS(expected[i], function_index, buffer, 1); + r->CheckCallApplyViaJS(expected[i], function_index, buffer, 1); } } } // namespace @@ -462,7 +458,7 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) { isolate); const double null = 0xDEADBEEF; - CheckTableCall(isolate, table, r, call_index, null, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null); // 0 count is ok in bounds, and at end of regions. r.CheckCallViaJS(0, 0, 0, 0); @@ -471,19 +467,19 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) { // Test actual writes. r.CheckCallViaJS(0, 0, 0, 1); - CheckTableCall(isolate, table, r, call_index, 0, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, null, null, null, null); r.CheckCallViaJS(0, 0, 0, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, null, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, 1, null, null, null); r.CheckCallViaJS(0, 0, 0, 3); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, null, null); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 0, 1); r.CheckCallViaJS(0, 3, 1, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 1, 2); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 1, 2); r.CheckCallViaJS(0, 3, 2, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 2, 3); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 2, 3); r.CheckCallViaJS(0, 3, 3, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); } WASM_EXEC_TEST(TableInitElems0) { TestTableInitElems(execution_tier, 0); } @@ -534,15 +530,15 @@ void TestTableInitOob(ExecutionTier execution_tier, int table_index) { isolate); const double null = 0xDEADBEEF; - CheckTableCall(isolate, table, r, call_index, null, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null); // Write all values up to the out-of-bounds write. r.CheckCallViaJS(0xDEADBEEF, 3, 0, 3); - CheckTableCall(isolate, table, r, call_index, null, null, null, 0, 1); + CheckTableCall(isolate, table, &r, call_index, null, null, null, 0, 1); // Write all values up to the out-of-bounds read. r.CheckCallViaJS(0xDEADBEEF, 0, 3, 3); - CheckTableCall(isolate, table, r, call_index, 3, 4, null, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 3, 4, null, 0, 1); // 0-count is never oob. r.CheckCallViaJS(0, kTableSize + 1, 0, 0); @@ -696,21 +692,21 @@ void TestTableCopyCalls(ExecutionTier execution_tier, int table_dst, isolate); if (table_dst == table_src) { - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 1); - CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 1, 2); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 1, 2); } else { - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 1); - CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 0, 1); } } diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc index 4c1842b537..1b64135cb8 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc @@ -278,7 +278,7 @@ TEST(Breakpoint_I32Add) { static const int kNumBreakpoints = 3; byte code[] = {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; std::unique_ptr<int[]> offsets = - Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal, + Find(code, sizeof(code), kNumBreakpoints, kExprLocalGet, kExprLocalGet, kExprI32Add); WasmRunner<int32_t, uint32_t, uint32_t> r(ExecutionTier::kInterpreter); diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc index 51d97650d4..5f70ab6c7b 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc @@ -11,7 +11,6 @@ #include "src/utils/version.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" @@ -943,154 +942,6 @@ TEST(MemoryWithOOBEmptyDataSegment) { Cleanup(); } -// Utility to free the allocated memory for a buffer that is manually -// externalized in a test. -struct ManuallyExternalizedBuffer { - Isolate* isolate_; - Handle<JSArrayBuffer> buffer_; - void* allocation_base_; - size_t allocation_length_; - bool const should_free_; - - ManuallyExternalizedBuffer(JSArrayBuffer buffer, Isolate* isolate) - : isolate_(isolate), - buffer_(buffer, isolate), - allocation_base_(buffer.allocation_base()), - allocation_length_(buffer.allocation_length()), - should_free_(!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory( - buffer.backing_store())) { - if (!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory( - buffer.backing_store())) { - v8::Utils::ToLocal(buffer_)->Externalize(); - } - } - ~ManuallyExternalizedBuffer() { - if (should_free_) { - buffer_->FreeBackingStoreFromMainThread(); - } - } -}; - -TEST(Run_WasmModule_Buffer_Externalized_GrowMem) { - { - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - TestSignatures sigs; - v8::internal::AccountingAllocator allocator; - Zone zone(&allocator, ZONE_NAME); - - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); - ExportAsMain(f); - byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP, - WASM_MEMORY_SIZE}; - EMIT_CODE_WITH_END(f, code); - - ZoneBuffer buffer(&zone); - builder->WriteTo(&buffer); - testing::SetupIsolateForWasmModule(isolate); - ErrorThrower thrower(isolate, "Test"); - const Handle<WasmInstanceObject> instance = - CompileAndInstantiateForTesting( - isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end())) - .ToHandleChecked(); - Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); - - // Fake the Embedder flow by externalizing the array buffer. - ManuallyExternalizedBuffer buffer1(memory_object->array_buffer(), isolate); - - // Grow using the API. - uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4); - CHECK_EQ(16, result); - CHECK(buffer1.buffer_->was_detached()); // growing always detaches - CHECK_EQ(0, buffer1.buffer_->byte_length()); - - CHECK_NE(*buffer1.buffer_, memory_object->array_buffer()); - - // Fake the Embedder flow by externalizing the array buffer. - ManuallyExternalizedBuffer buffer2(memory_object->array_buffer(), isolate); - - // Grow using an internal WASM bytecode. - result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr); - CHECK_EQ(26, result); - CHECK(buffer2.buffer_->was_detached()); // growing always detaches - CHECK_EQ(0, buffer2.buffer_->byte_length()); - CHECK_NE(*buffer2.buffer_, memory_object->array_buffer()); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_GrowMemMemSize) { - { - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - Handle<WasmMemoryObject> mem_obj = - WasmMemoryObject::New(isolate, buffer, 100); - auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); - int32_t result = WasmMemoryObject::Grow(isolate, mem_obj, 0); - CHECK_EQ(16, result); - constexpr bool is_wasm_memory = true; - const JSArrayBuffer::Allocation allocation{contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory}; - JSArrayBuffer::FreeBackingStore(isolate, allocation); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_Detach) { - { - // Regression test for - // https://bugs.chromium.org/p/chromium/issues/detail?id=731046 - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); - wasm::DetachMemoryBuffer(isolate, buffer, true); - constexpr bool is_wasm_memory = true; - const JSArrayBuffer::Allocation allocation{contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory}; - JSArrayBuffer::FreeBackingStore(isolate, allocation); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) { - // Regresion test for https://crbug.com/813876 - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - Handle<WasmMemoryObject> mem = WasmMemoryObject::New(isolate, buffer, 128); - auto contents = v8::Utils::ToLocal(buffer)->Externalize(); - WasmMemoryObject::Grow(isolate, mem, 0); - constexpr bool is_wasm_memory = true; - JSArrayBuffer::FreeBackingStore( - isolate, JSArrayBuffer::Allocation(contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory)); - // Make sure we can write to the buffer without crashing - uint32_t* int_buffer = - reinterpret_cast<uint32_t*>(mem->array_buffer().backing_store()); - int_buffer[0] = 0; -} - -#if V8_TARGET_ARCH_64_BIT -TEST(Run_WasmModule_Reclaim_Memory) { - // Make sure we can allocate memories without running out of address space. - Isolate* isolate = CcTest::InitIsolateOnce(); - Handle<JSArrayBuffer> buffer; - for (int i = 0; i < 256; ++i) { - HandleScope scope(isolate); - CHECK(NewArrayBuffer(isolate, kWasmPageSize).ToHandle(&buffer)); - } -} -#endif - TEST(AtomicOpDisassembly) { { EXPERIMENTAL_FLAG_SCOPE(threads); @@ -1118,12 +969,15 @@ TEST(AtomicOpDisassembly) { ErrorThrower thrower(isolate, "Test"); auto enabled_features = WasmFeaturesFromIsolate(isolate); - MaybeHandle<WasmModuleObject> module_object = - isolate->wasm_engine()->SyncCompile( - isolate, enabled_features, &thrower, - ModuleWireBytes(buffer.begin(), buffer.end())); + Handle<WasmModuleObject> module_object = + isolate->wasm_engine() + ->SyncCompile(isolate, enabled_features, &thrower, + ModuleWireBytes(buffer.begin(), buffer.end())) + .ToHandleChecked(); + NativeModule* native_module = module_object->native_module(); + ModuleWireBytes wire_bytes(native_module->wire_bytes()); - module_object.ToHandleChecked()->DisassembleFunction(0); + DisassembleWasmFunction(native_module->module(), wire_bytes, 0); } Cleanup(); } diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc index b48321df40..d76c4c3643 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc @@ -184,13 +184,20 @@ T UnsignedGreaterEqual(T a, T b) { template <typename T> T LogicalShiftLeft(T a, int shift) { using UnsignedT = typename std::make_unsigned<T>::type; - return static_cast<UnsignedT>(a) << shift; + return static_cast<UnsignedT>(a) << (shift % (sizeof(T) * 8)); } template <typename T> T LogicalShiftRight(T a, int shift) { using UnsignedT = typename std::make_unsigned<T>::type; - return static_cast<UnsignedT>(a) >> shift; + return static_cast<UnsignedT>(a) >> (shift % (sizeof(T) * 8)); +} + +// Define our own ArithmeticShiftRight instead of using the one from utils.h +// because the shift amount needs to be taken modulo lane width. +template <typename T> +T ArithmeticShiftRight(T a, int shift) { + return a >> (shift % (sizeof(T) * 8)); } template <typename T> @@ -279,7 +286,7 @@ T Sqrt(T a) { return std::sqrt(a); } -#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 // only used for F64x2 tests below int64_t Equal(double a, double b) { return a == b ? -1 : 0; } @@ -292,14 +299,106 @@ int64_t GreaterEqual(double a, double b) { return a >= b ? -1 : 0; } int64_t Less(double a, double b) { return a < b ? -1 : 0; } int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +// Only used for qfma and qfms tests below. + +// FMOperation holds the params (a, b, c) for a Multiply-Add or +// Multiply-Subtract operation, and the expected result if the operation was +// fused, rounded only once for the entire operation, or unfused, rounded after +// multiply and again after add/subtract. +template <typename T> +struct FMOperation { + const T a; + const T b; + const T c; + const T fused_result; + const T unfused_result; +}; + +// large_n is large number that overflows T when multiplied by itself, this is a +// useful constant to test fused/unfused behavior. +template <typename T> +constexpr T large_n = T(0); + +template <> +constexpr double large_n<double> = 1e200; + +template <> +constexpr float large_n<float> = 1e20; + +// Fused Multiply-Add performs a + b * c. +template <typename T> +static constexpr FMOperation<T> qfma_array[] = { + {1.0f, 2.0f, 3.0f, 7.0f, 7.0f}, + // fused: a + b * c = -inf + (positive overflow) = -inf + // unfused: a + b * c = -inf + inf = NaN + {-std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>, + -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // fused: a + b * c = inf + (negative overflow) = inf + // unfused: a + b * c = inf + -inf = NaN + {std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>, + std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // NaN + {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}, + // -NaN + {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}}; + +template <typename T> +static constexpr Vector<const FMOperation<T>> qfma_vector() { + return ArrayVector(qfma_array<T>); +} + +// Fused Multiply-Subtract performs a - b * c. +template <typename T> +static constexpr FMOperation<T> qfms_array[]{ + {1.0f, 2.0f, 3.0f, -5.0f, -5.0f}, + // fused: a - b * c = inf - (positive overflow) = inf + // unfused: a - b * c = inf - inf = NaN + {std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>, + std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // fused: a - b * c = -inf - (negative overflow) = -inf + // unfused: a - b * c = -inf - -inf = NaN + {-std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>, + -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // NaN + {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}, + // -NaN + {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}}; + +template <typename T> +static constexpr Vector<const FMOperation<T>> qfms_vector() { + return ArrayVector(qfms_array<T>); +} + +// Fused results only when fma3 feature is enabled, and running on TurboFan. +bool ExpectFused(ExecutionTier tier) { +#ifdef V8_TARGET_ARCH_X64 + return CpuFeatures::IsSupported(FMA3) && (tier == ExecutionTier::kTurbofan); +#else + return (tier == ExecutionTier::kTurbofan); +#endif +} #endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 } // namespace -#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ - WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ - WASM_SIMD_##TYPE##_EXTRACT_LANE( \ - lane_index, WASM_GET_LOCAL(value))), \ +#define WASM_SIMD_CHECK_LANE_S(TYPE, value, LANE_TYPE, lane_value, lane_index) \ + WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ + WASM_SIMD_##TYPE##_EXTRACT_LANE( \ + lane_index, WASM_GET_LOCAL(value))), \ + WASM_RETURN1(WASM_ZERO)) + +// Unsigned Extracts are only available for I8x16, I16x8 types +#define WASM_SIMD_CHECK_LANE_U(TYPE, value, LANE_TYPE, lane_value, lane_index) \ + WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ + WASM_SIMD_##TYPE##_EXTRACT_LANE_U( \ + lane_index, WASM_GET_LOCAL(value))), \ WASM_RETURN1(WASM_ZERO)) #define TO_BYTE(val) static_cast<byte>(val) @@ -338,13 +437,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } #define WASM_SIMD_I16x8_SPLAT(x) WASM_SIMD_SPLAT(I16x8, x) #define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \ - x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane) + x, WASM_SIMD_OP(kExprI16x8ExtractLaneS), TO_BYTE(lane) +#define WASM_SIMD_I16x8_EXTRACT_LANE_U(lane, x) \ + x, WASM_SIMD_OP(kExprI16x8ExtractLaneU), TO_BYTE(lane) #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \ x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane) #define WASM_SIMD_I8x16_SPLAT(x) WASM_SIMD_SPLAT(I8x16, x) #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ - x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) + x, WASM_SIMD_OP(kExprI8x16ExtractLaneS), TO_BYTE(lane) +#define WASM_SIMD_I8x16_EXTRACT_LANE_U(lane, x) \ + x, WASM_SIMD_OP(kExprI8x16ExtractLaneU), TO_BYTE(lane) #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) @@ -357,8 +460,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } #define WASM_SIMD_LOAD_MEM(index) \ index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, ZERO_OFFSET +#define WASM_SIMD_LOAD_MEM_OFFSET(offset, index) \ + index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, offset #define WASM_SIMD_STORE_MEM(index, val) \ index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, ZERO_OFFSET +#define WASM_SIMD_STORE_MEM_OFFSET(offset, index, val) \ + index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, offset + +#define WASM_SIMD_F64x2_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfma) +#define WASM_SIMD_F64x2_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfms) +#define WASM_SIMD_F32x4_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfma) +#define WASM_SIMD_F32x4_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfms) // Runs tests of compiled code, using the interpreter as a reference. #define WASM_SIMD_COMPILED_TEST(name) \ @@ -589,10 +701,15 @@ void RunF32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WASM_SIMD_TEST(F32x4Abs) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Abs, std::abs); } + WASM_SIMD_TEST(F32x4Neg) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Neg, Negate); } +WASM_SIMD_TEST(F32x4Sqrt) { + RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Sqrt, Sqrt); +} + WASM_SIMD_TEST(F32x4RecipApprox) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipApprox, base::Recip, false /* !exact */); @@ -725,6 +842,57 @@ WASM_SIMD_TEST(F32x4Le) { } #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +WASM_SIMD_TEST_NO_LOWERING(F32x4Qfma) { + WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd); + // Set up global to hold mask output. + float* g = r.builder().AddGlobal<float>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMA( + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<float> x : qfma_vector<float>()) { + r.Call(x.a, x.b, x.c); + float expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 4; i++) { + float actual = ReadLittleEndianValue<float>(&g[i]); + CheckFloatResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} + +WASM_SIMD_TEST_NO_LOWERING(F32x4Qfms) { + WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd); + // Set up global to hold mask output. + float* g = r.builder().AddGlobal<float>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMS( + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<float> x : qfms_vector<float>()) { + r.Call(x.a, x.b, x.c); + float expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 4; i++) { + float actual = ReadLittleEndianValue<float>(&g[i]); + CheckFloatResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2Splat) { WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd); // Set up a global to hold output vector. @@ -803,7 +971,8 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2Neg) { void RunI64x2ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int64ShiftOp expected_op) { - for (int shift = 1; shift < 64; shift++) { + // Intentionally shift by 64, should be no-op. + for (int shift = 1; shift <= 64; shift++) { WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd); int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128); byte value = 0; @@ -918,6 +1087,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2GeU) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2GeU, UnsignedGreaterEqual); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { WasmRunner<int32_t, double> r(execution_tier, lower_simd); @@ -941,6 +1111,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) { WasmRunner<int64_t> r(execution_tier, lower_simd); BUILD(r, WASM_IF_ELSE_L( @@ -950,6 +1121,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) { WASM_I64V(1), WASM_I64V(0))); CHECK_EQ(1, r.Call()); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { WasmRunner<double, double> r(execution_tier, lower_simd); @@ -973,6 +1145,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) { WasmRunner<int64_t> r(execution_tier, lower_simd); BUILD(r, WASM_IF_ELSE_L( @@ -982,6 +1155,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) { WASM_I64V(1), WASM_I64V(0))); CHECK_EQ(1, r.Call()); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ReplaceLane) { WasmRunner<int32_t> r(execution_tier, lower_simd); @@ -1124,6 +1298,10 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Neg) { RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Neg, Negate); } +WASM_SIMD_TEST_NO_LOWERING(F64x2Sqrt) { + RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Sqrt, Sqrt); +} + void RunF64x2BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, DoubleBinOp expected_op) { WasmRunner<int32_t, double, double> r(execution_tier, lower_simd); @@ -1249,12 +1427,14 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Max) { RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Max, JSMax); } -#if V8_TARGET_ARCH_X64 +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2Mul) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Mul, base::MulWithWraparound); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#if V8_TARGET_ARCH_X64 WASM_SIMD_TEST_NO_LOWERING(I64x2MinS) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2MinS, Minimum); } @@ -1273,7 +1453,57 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2MaxU) { UnsignedMaximum); } #endif // V8_TARGET_ARCH_X64 + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +WASM_SIMD_TEST_NO_LOWERING(F64x2Qfma) { + WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd); + // Set up global to hold mask output. + double* g = r.builder().AddGlobal<double>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMA( + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<double> x : qfma_vector<double>()) { + r.Call(x.a, x.b, x.c); + double expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 2; i++) { + double actual = ReadLittleEndianValue<double>(&g[i]); + CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} + +WASM_SIMD_TEST_NO_LOWERING(F64x2Qfms) { + WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd); + // Set up global to hold mask output. + double* g = r.builder().AddGlobal<double>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMS( + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<double> x : qfms_vector<double>()) { + r.Call(x.a, x.b, x.c); + double expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 2; i++) { + double actual = ReadLittleEndianValue<double>(&g[i]); + CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} #endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 WASM_SIMD_TEST(I32x4Splat) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); @@ -1652,7 +1882,8 @@ WASM_SIMD_TEST(I32x4GeU) { void RunI32x4ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int32ShiftOp expected_op) { - for (int shift = 1; shift < 32; shift++) { + // Intentionally shift by 32, should be no-op. + for (int shift = 1; shift <= 32; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int32_t* g = r.builder().AddGlobal<int32_t>(kWasmS128); byte value = 0; @@ -1902,7 +2133,8 @@ WASM_SIMD_TEST(I16x8LeU) { void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int16ShiftOp expected_op) { - for (int shift = 1; shift < 16; shift++) { + // Intentionally shift by 16, should be no-op. + for (int shift = 1; shift <= 16; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int16_t* g = r.builder().AddGlobal<int16_t>(kWasmS128); byte value = 0; @@ -1917,7 +2149,7 @@ void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, FOR_INT16_INPUTS(x) { r.Call(x); - float expected = expected_op(x, shift); + int16_t expected = expected_op(x, shift); for (int i = 0; i < 8; i++) { CHECK_EQ(expected, ReadLittleEndianValue<int16_t>(&g[i])); } @@ -2118,7 +2350,8 @@ WASM_SIMD_TEST(I8x16Mul) { void RunI8x16ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int8ShiftOp expected_op) { - for (int shift = 1; shift < 8; shift++) { + // Intentionally shift by 8, should be no-op. + for (int shift = 1; shift <= 8; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int8_t* g = r.builder().AddGlobal<int8_t>(kWasmS128); byte value = 0; @@ -2184,10 +2417,10 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16ShrU) { format, WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2), \ WASM_SIMD_BINOP(kExprI##format##Ne, WASM_GET_LOCAL(mask), \ WASM_GET_LOCAL(zero)))), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 1), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 1), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 2), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \ \ CHECK_EQ(1, r.Call(0x12, 0x34)); \ } @@ -2222,10 +2455,10 @@ WASM_SIMD_SELECT_TEST(8x16) WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(src1), \ WASM_GET_LOCAL(src2), \ WASM_GET_LOCAL(mask))), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 1), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 2), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 1), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 2), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \ \ CHECK_EQ(1, r.Call(0x12, 0x34, 0x32)); \ } @@ -2454,6 +2687,62 @@ WASM_SIMD_TEST(S8x16Concat) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 +struct SwizzleTestArgs { + const Shuffle input; + const Shuffle indices; + const Shuffle expected; +}; + +static constexpr SwizzleTestArgs swizzle_test_args[] = { + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}, + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {15, 0, 14, 1, 13, 2, 12, 3, 11, 4, 10, 5, 9, 6, 8, 7}, + {0, 15, 1, 14, 2, 13, 3, 12, 4, 11, 5, 10, 6, 9, 7, 8}}, + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}, + {15, 13, 11, 9, 7, 5, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0}}, + // all indices are out of range + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {16, 17, 18, 19, 20, 124, 125, 126, 127, -1, -2, -3, -4, -5, -6, -7}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; + +static constexpr Vector<const SwizzleTestArgs> swizzle_test_vector = + ArrayVector(swizzle_test_args); + +WASM_SIMD_TEST(S8x16Swizzle) { + // RunBinaryLaneOpTest set up the two globals to be consecutive integers, + // [0-15] and [16-31]. Using [0-15] as the indices will not sufficiently test + // swizzle since the expected result is a no-op, using [16-31] will result in + // all 0s. + WasmRunner<int32_t> r(execution_tier, lower_simd); + static const int kElems = kSimd128Size / sizeof(uint8_t); + uint8_t* dst = r.builder().AddGlobal<uint8_t>(kWasmS128); + uint8_t* src0 = r.builder().AddGlobal<uint8_t>(kWasmS128); + uint8_t* src1 = r.builder().AddGlobal<uint8_t>(kWasmS128); + BUILD( + r, + WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(kExprS8x16Swizzle, WASM_GET_GLOBAL(1), + WASM_GET_GLOBAL(2))), + WASM_ONE); + + for (SwizzleTestArgs si : swizzle_test_vector) { + for (int i = 0; i < kElems; i++) { + WriteLittleEndianValue<uint8_t>(&src0[i], si.input[i]); + WriteLittleEndianValue<uint8_t>(&src1[i], si.indices[i]); + } + + CHECK_EQ(1, r.Call()); + + for (int i = 0; i < kElems; i++) { + CHECK_EQ(ReadLittleEndianValue<uint8_t>(&dst[i]), si.expected[i]); + } + } +} +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 + // Combine 3 shuffles a, b, and c by applying both a and b and then applying c // to those two results. Shuffle Combine(const Shuffle& a, const Shuffle& b, const Shuffle& c) { @@ -2487,7 +2776,7 @@ void AppendShuffle(const Shuffle& shuffle, std::vector<byte>* buffer) { for (size_t i = 0; i < kSimd128Size; ++i) buffer->push_back((shuffle[i])); } -void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references) +void BuildShuffle(const std::vector<Shuffle>& shuffles, std::vector<byte>* buffer) { // Perform the leaf shuffles on globals 0 and 1. size_t row_index = (shuffles.size() - 1) / 2; @@ -2504,7 +2793,7 @@ void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references) } row_index /= 2; } while (row_index != 0); - byte epilog[] = {kExprSetGlobal, static_cast<byte>(0), WASM_ONE}; + byte epilog[] = {kExprGlobalSet, static_cast<byte>(0), WASM_ONE}; for (size_t j = 0; j < arraysize(epilog); ++j) buffer->push_back(epilog[j]); } @@ -2895,11 +3184,34 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) { r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t)); // Load memory, store it, then reload it and extract the first lane. Use a // non-zero offset into the memory of 1 lane (4 bytes) to test indexing. - BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(4), WASM_SIMD_LOAD_MEM(WASM_I32V(4))), - WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(4)))); + BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(8), WASM_SIMD_LOAD_MEM(WASM_I32V(4))), + WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(8)))); + + FOR_INT32_INPUTS(i) { + int32_t expected = i; + r.builder().WriteMemory(&memory[1], expected); + CHECK_EQ(expected, r.Call()); + } +} + +WASM_SIMD_TEST(SimdLoadStoreLoadMemargOffset) { + WasmRunner<int32_t> r(execution_tier, lower_simd); + int32_t* memory = + r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t)); + constexpr byte offset_1 = 4; + constexpr byte offset_2 = 8; + // Load from memory at offset_1, store to offset_2, load from offset_2, and + // extract first lane. We use non-zero memarg offsets to test offset decoding. + BUILD( + r, + WASM_SIMD_STORE_MEM_OFFSET( + offset_2, WASM_ZERO, WASM_SIMD_LOAD_MEM_OFFSET(offset_1, WASM_ZERO)), + WASM_SIMD_I32x4_EXTRACT_LANE( + 0, WASM_SIMD_LOAD_MEM_OFFSET(offset_2, WASM_ZERO))); FOR_INT32_INPUTS(i) { int32_t expected = i; + // Index 1 of memory (int32_t) will be bytes 4 to 8. r.builder().WriteMemory(&memory[1], expected); CHECK_EQ(expected, r.Call()); } @@ -3040,8 +3352,48 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { UnsignedGreater); } +#define WASM_EXTRACT_I16x8_TEST(Sign, Type) \ + WASM_SIMD_TEST(I16X8ExtractLane##Sign) { \ + WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \ + byte int_val = r.AllocateLocal(kWasmI32); \ + byte simd_val = r.AllocateLocal(kWasmS128); \ + BUILD(r, \ + WASM_SET_LOCAL(simd_val, \ + WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(int_val))), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 0), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 2), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 4), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 6), WASM_ONE); \ + FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \ + } +WASM_EXTRACT_I16x8_TEST(S, UINT16) WASM_EXTRACT_I16x8_TEST(I, INT16) +#undef WASM_EXTRACT_I16x8_TEST + +#define WASM_EXTRACT_I8x16_TEST(Sign, Type) \ + WASM_SIMD_TEST(I8x16ExtractLane##Sign) { \ + WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \ + byte int_val = r.AllocateLocal(kWasmI32); \ + byte simd_val = r.AllocateLocal(kWasmS128); \ + BUILD(r, \ + WASM_SET_LOCAL(simd_val, \ + WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(int_val))), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 1), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 3), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 5), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 7), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 9), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 10), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 11), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 13), \ + WASM_ONE); \ + FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \ + } + WASM_EXTRACT_I8x16_TEST(S, UINT8) WASM_EXTRACT_I8x16_TEST(I, INT8) +#undef WASM_EXTRACT_I8x16_TEST + #undef WASM_SIMD_TEST -#undef WASM_SIMD_CHECK_LANE +#undef WASM_SIMD_CHECK_LANE_S +#undef WASM_SIMD_CHECK_LANE_U #undef TO_BYTE #undef WASM_SIMD_OP #undef WASM_SIMD_SPLAT @@ -3064,13 +3416,17 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { #undef WASM_SIMD_I32x4_REPLACE_LANE #undef WASM_SIMD_I16x8_SPLAT #undef WASM_SIMD_I16x8_EXTRACT_LANE +#undef WASM_SIMD_I16x8_EXTRACT_LANE_U #undef WASM_SIMD_I16x8_REPLACE_LANE #undef WASM_SIMD_I8x16_SPLAT #undef WASM_SIMD_I8x16_EXTRACT_LANE +#undef WASM_SIMD_I8x16_EXTRACT_LANE_U #undef WASM_SIMD_I8x16_REPLACE_LANE #undef WASM_SIMD_S8x16_SHUFFLE_OP #undef WASM_SIMD_LOAD_MEM +#undef WASM_SIMD_LOAD_MEM_OFFSET #undef WASM_SIMD_STORE_MEM +#undef WASM_SIMD_STORE_MEM_OFFSET #undef WASM_SIMD_SELECT_TEST #undef WASM_SIMD_NON_CANONICAL_SELECT_TEST #undef WASM_SIMD_COMPILED_TEST @@ -3078,6 +3434,10 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { #undef WASM_SIMD_TEST_NO_LOWERING #undef WASM_SIMD_ANYTRUE_TEST #undef WASM_SIMD_ALLTRUE_TEST +#undef WASM_SIMD_F64x2_QFMA +#undef WASM_SIMD_F64x2_QFMS +#undef WASM_SIMD_F32x4_QFMA +#undef WASM_SIMD_F32x4_QFMS } // namespace test_run_wasm_simd } // namespace wasm diff --git a/deps/v8/test/cctest/wasm/test-run-wasm.cc b/deps/v8/test/cctest/wasm/test-run-wasm.cc index 26df61ceb8..aa6195b8b3 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm.cc @@ -49,8 +49,8 @@ WASM_EXEC_TEST(Int32Const_many) { WASM_EXEC_TEST(GraphTrimming) { // This WebAssembly code requires graph trimming in the TurboFan compiler. WasmRunner<int32_t, int32_t> r(execution_tier); - BUILD(r, kExprGetLocal, 0, kExprGetLocal, 0, kExprGetLocal, 0, kExprI32RemS, - kExprI32Eq, kExprGetLocal, 0, kExprI32DivS, kExprUnreachable); + BUILD(r, kExprLocalGet, 0, kExprLocalGet, 0, kExprLocalGet, 0, kExprI32RemS, + kExprI32Eq, kExprLocalGet, 0, kExprI32DivS, kExprUnreachable); r.Call(1); } @@ -1810,18 +1810,18 @@ WASM_EXEC_TEST(CheckMachIntsZero) { BUILD(r, // -- /**/ kExprLoop, kLocalVoid, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprIf, kLocalVoid, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32LoadMem, 0, 0, // -- /* */ kExprIf, kLocalVoid, // -- /* */ kExprI32Const, 127, // -- /* */ kExprReturn, // -- /* */ kExprEnd, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32Const, 4, // -- /* */ kExprI32Sub, // -- - /* */ kExprTeeLocal, 0, // -- + /* */ kExprLocalTee, 0, // -- /* */ kExprBr, DEPTH_0, // -- /* */ kExprEnd, // -- /**/ kExprEnd, // -- @@ -2012,16 +2012,16 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { FunctionSig* sig = WasmOpcodes::Signature(opcode); if (sig->parameter_count() == 1) { - byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode), + byte code[] = {WASM_NO_LOCALS, kExprLocalGet, 0, static_cast<byte>(opcode), WASM_END}; TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code, code + arraysize(code)); } else { CHECK_EQ(2, sig->parameter_count()); byte code[] = {WASM_NO_LOCALS, - kExprGetLocal, + kExprLocalGet, 0, - kExprGetLocal, + kExprLocalGet, 1, static_cast<byte>(opcode), WASM_END}; @@ -2667,7 +2667,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) { // Store the result in a local. byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result)); - ADD_CODE(code, kExprSetLocal, local_index); + ADD_CODE(code, kExprLocalSet, local_index); // Store the result in memory. ADD_CODE(code, @@ -2761,10 +2761,11 @@ void RunMultiReturnSelect(ExecutionTier execution_tier, const T* inputs) { WASM_GET_LOCAL(3)), WASM_DROP); } else { - BUILD(r, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0), - WASM_GET_LOCAL(1), WASM_GET_LOCAL(2), - WASM_GET_LOCAL(3)), - kExprSetLocal, 0, WASM_DROP, WASM_GET_LOCAL(0)); + BUILD(r, + WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0), + WASM_GET_LOCAL(1), WASM_GET_LOCAL(2), + WASM_GET_LOCAL(3)), + kExprLocalSet, 0, WASM_DROP, WASM_GET_LOCAL(0)); } T expected = inputs[k == 0 ? i : j]; @@ -3330,7 +3331,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) { std::vector<byte> code; for (byte p = 0; p < num_params; ++p) { - ADD_CODE(code, kExprGetLocal, p); + ADD_CODE(code, kExprLocalGet, p); } ADD_CODE(code, kExprI32Const, 0); ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO); diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc index 795fa30e72..f9089b7821 100644 --- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc +++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc @@ -194,17 +194,17 @@ ZoneBuffer GetValidModuleBytes(Zone* zone) { WasmModuleBuilder builder(zone); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 1, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 1, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 2, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 2, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -317,17 +317,17 @@ ZoneBuffer GetModuleWithInvalidSection(Zone* zone) { WasmInitExpr(WasmInitExpr::kGlobalIndex, 12)); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 1, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 1, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 2, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 2, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -442,7 +442,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByModuleDecoder) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -481,7 +481,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByStreamingDecoder) { uint8_t code[] = { U32V_1(26), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -520,7 +520,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByCompiler) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -679,7 +679,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled1) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -713,7 +713,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled2) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -745,7 +745,7 @@ STREAM_TEST(TestAbortAfterCodeSection1) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -781,7 +781,7 @@ STREAM_TEST(TestAbortAfterCodeSection2) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -815,7 +815,7 @@ STREAM_TEST(TestAbortAfterCompilationError1) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -857,7 +857,7 @@ STREAM_TEST(TestAbortAfterCompilationError2) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -934,7 +934,7 @@ STREAM_TEST(TestModuleWithMultipleFunctions) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -970,7 +970,7 @@ STREAM_TEST(TestModuleWithDataSection) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -1016,7 +1016,7 @@ STREAM_TEST(TestModuleWithImportedFunction) { builder.AddImport(ArrayVector("Test"), sigs.i_iii()); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -1047,7 +1047,7 @@ STREAM_TEST(TestModuleWithErrorAfterDataSection) { U32V_1(1), // functions count U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, // some code + kExprLocalGet, // some code 0, // some code kExprEnd, // some code kDataSectionCode, // section code @@ -1133,7 +1133,7 @@ STREAM_TEST(TestSetModuleCompiledCallback) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc index e287b1139e..798e1d46da 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc @@ -22,10 +22,11 @@ namespace wasm { namespace { void CheckLocations( - WasmModuleObject module_object, debug::Location start, debug::Location end, + NativeModule* native_module, debug::Location start, debug::Location end, std::initializer_list<debug::Location> expected_locations_init) { std::vector<debug::BreakLocation> locations; - bool success = module_object.GetPossibleBreakpoints(start, end, &locations); + bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start, + end, &locations); CHECK(success); printf("got %d locations: ", static_cast<int>(locations.size())); @@ -45,10 +46,11 @@ void CheckLocations( } } -void CheckLocationsFail(WasmModuleObject module_object, debug::Location start, +void CheckLocationsFail(NativeModule* native_module, debug::Location start, debug::Location end) { std::vector<debug::BreakLocation> locations; - bool success = module_object.GetPossibleBreakpoints(start, end, &locations); + bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start, + end, &locations); CHECK(!success); } @@ -63,8 +65,12 @@ class BreakHandler : public debug::DebugDelegate { struct BreakPoint { int position; Action action; + std::function<void(void)> pre_action; BreakPoint(int position, Action action) - : position(position), action(action) {} + : position(position), action(action), pre_action([]() {}) {} + BreakPoint(int position, Action action, + std::function<void(void)> pre_action) + : position(position), action(action), pre_action(pre_action) {} }; explicit BreakHandler(Isolate* isolate, @@ -96,6 +102,7 @@ class BreakHandler : public debug::DebugDelegate { auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasmInterpreted(); CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset()); + expected_breaks_[count_].pre_action(); Action next_action = expected_breaks_[count_].action; switch (next_action) { case Continue: @@ -112,22 +119,21 @@ class BreakHandler : public debug::DebugDelegate { } }; -void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references) - int function_index, int byte_offset, - int expected_set_byte_offset = -1) { +Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index, + int byte_offset, + int expected_set_byte_offset = -1) { int func_offset = - runner.builder().GetFunctionAt(function_index)->code.offset(); + runner->builder().GetFunctionAt(function_index)->code.offset(); int code_offset = func_offset + byte_offset; if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset; - Handle<WasmInstanceObject> instance = runner.builder().instance_object(); - Handle<WasmModuleObject> module_object(instance->module_object(), - runner.main_isolate()); + Handle<WasmInstanceObject> instance = runner->builder().instance_object(); + Handle<Script> script(instance->module_object().script(), + runner->main_isolate()); static int break_index = 0; Handle<BreakPoint> break_point = - runner.main_isolate()->factory()->NewBreakPoint( - break_index++, runner.main_isolate()->factory()->empty_string()); - CHECK(WasmModuleObject::SetBreakPoint(module_object, &code_offset, - break_point)); + runner->main_isolate()->factory()->NewBreakPoint( + break_index++, runner->main_isolate()->factory()->empty_string()); + CHECK(WasmModuleObject::SetBreakPoint(script, &code_offset, break_point)); int set_byte_offset = code_offset - func_offset; CHECK_EQ(expected_set_byte_offset, set_byte_offset); // Also set breakpoint on the debug info of the instance directly, since the @@ -135,6 +141,24 @@ void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references) Handle<WasmDebugInfo> debug_info = WasmInstanceObject::GetOrCreateDebugInfo(instance); WasmDebugInfo::SetBreakpoint(debug_info, function_index, set_byte_offset); + + return break_point; +} + +void ClearBreakpoint(WasmRunnerBase* runner, int function_index, + int byte_offset, Handle<BreakPoint> break_point) { + int func_offset = + runner->builder().GetFunctionAt(function_index)->code.offset(); + int code_offset = func_offset + byte_offset; + Handle<WasmInstanceObject> instance = runner->builder().instance_object(); + Handle<Script> script(instance->module_object().script(), + runner->main_isolate()); + CHECK(WasmModuleObject::ClearBreakPoint(script, code_offset, break_point)); + // Also clear breakpoint on the debug info of the instance directly, since the + // instance chain is not setup properly in tests. + Handle<WasmDebugInfo> debug_info = + WasmInstanceObject::GetOrCreateDebugInfo(instance); + WasmDebugInfo::ClearBreakpoint(debug_info, function_index, byte_offset); } // Wrapper with operator<<. @@ -247,25 +271,25 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) { BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE)); WasmInstanceObject instance = *runner.builder().instance_object(); - WasmModuleObject module_object = instance.module_object(); + NativeModule* native_module = instance.module_object().native_module(); std::vector<debug::Location> locations; // Check all locations for function 0. - CheckLocations(module_object, {0, 0}, {1, 0}, + CheckLocations(native_module, {0, 0}, {1, 0}, {{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}}); // Check a range ending at an instruction. - CheckLocations(module_object, {0, 2}, {0, 4}, {{0, 2}}); + CheckLocations(native_module, {0, 2}, {0, 4}, {{0, 2}}); // Check a range ending one behind an instruction. - CheckLocations(module_object, {0, 2}, {0, 5}, {{0, 2}, {0, 4}}); + CheckLocations(native_module, {0, 2}, {0, 5}, {{0, 2}, {0, 4}}); // Check a range starting at an instruction. - CheckLocations(module_object, {0, 7}, {0, 8}, {{0, 7}}); + CheckLocations(native_module, {0, 7}, {0, 8}, {{0, 7}}); // Check from an instruction to beginning of next function. - CheckLocations(module_object, {0, 7}, {1, 0}, {{0, 7}}); + CheckLocations(native_module, {0, 7}, {1, 0}, {{0, 7}}); // Check from end of one function (no valid instruction position) to beginning // of next function. Must be empty, but not fail. - CheckLocations(module_object, {0, 8}, {1, 0}, {}); + CheckLocations(native_module, {0, 8}, {1, 0}, {}); // Check from one after the end of the function. Must fail. - CheckLocationsFail(module_object, {0, 9}, {1, 0}); + CheckLocationsFail(native_module, {0, 9}, {1, 0}); } WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) { @@ -276,7 +300,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) { Handle<JSFunction> main_fun_wrapper = runner.builder().WrapCode(runner.function_index()); - SetBreakpoint(runner, runner.function_index(), 4, 4); + SetBreakpoint(&runner, runner.function_index(), 4, 4); BreakHandler count_breaks(isolate, {{4, BreakHandler::Continue}}); @@ -298,7 +322,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) { runner.builder().WrapCode(runner.function_index()); // Set breakpoint at the first I32Const. - SetBreakpoint(runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 1, 1); BreakHandler count_breaks(isolate, { @@ -340,12 +364,12 @@ WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) { Handle<JSFunction> main_fun_wrapper = runner.builder().WrapCode(f2.function_index()); - // Set first breakpoint on the GetLocal (offset 19) before the Call. - SetBreakpoint(runner, f2.function_index(), 19, 19); + // Set first breakpoint on the LocalGet (offset 19) before the Call. + SetBreakpoint(&runner, f2.function_index(), 19, 19); BreakHandler count_breaks(isolate, { - {19, BreakHandler::StepIn}, // GetLocal + {19, BreakHandler::StepIn}, // LocalGet {21, BreakHandler::StepIn}, // Call {1, BreakHandler::StepOut}, // in f2 {23, BreakHandler::Continue} // After Call @@ -377,7 +401,7 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) { // Set breakpoint at the first instruction (7 bytes for local decls: num // entries + 3x<count, type>). - SetBreakpoint(runner, runner.function_index(), 7, 7); + SetBreakpoint(&runner, runner.function_index(), 7, 7); CollectValuesBreakHandler break_handler( isolate, @@ -401,6 +425,104 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) { CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 1, args).is_null()); } +WASM_COMPILED_EXEC_TEST(WasmRemoveBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + SetBreakpoint(&runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> to_delete = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + SetBreakpoint(&runner, runner.function_index(), 4, 4); + + BreakHandler count_breaks(isolate, {{1, BreakHandler::Continue}, + {2, BreakHandler::Continue, + [&runner, &to_delete]() { + ClearBreakpoint( + &runner, runner.function_index(), + 3, to_delete); + }}, + {4, BreakHandler::Continue}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + +WASM_COMPILED_EXEC_TEST(WasmRemoveLastBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + SetBreakpoint(&runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> to_delete = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + + BreakHandler count_breaks( + isolate, {{1, BreakHandler::Continue}, + {2, BreakHandler::Continue, [&runner, &to_delete]() { + ClearBreakpoint(&runner, runner.function_index(), 3, + to_delete); + }}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + +WASM_COMPILED_EXEC_TEST(WasmRemoveAllBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + Handle<BreakPoint> bp1 = + SetBreakpoint(&runner, runner.function_index(), 1, 1); + Handle<BreakPoint> bp2 = + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> bp3 = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + + BreakHandler count_breaks( + isolate, {{1, BreakHandler::Continue, [&runner, &bp1, &bp2, &bp3]() { + ClearBreakpoint(&runner, runner.function_index(), 1, bp1); + ClearBreakpoint(&runner, runner.function_index(), 3, bp3); + ClearBreakpoint(&runner, runner.function_index(), 2, bp2); + }}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + } // namespace wasm } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc index 299c039698..15267215e1 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc @@ -22,10 +22,8 @@ std::shared_ptr<NativeModule> NewModule(Isolate* isolate) { std::shared_ptr<WasmModule> module(new WasmModule); bool can_request_more = false; size_t size = 16384; - auto native_module = isolate->wasm_engine()->NewNativeModule( + return isolate->wasm_engine()->NewNativeModule( isolate, kAllWasmFeatures, size, can_request_more, std::move(module)); - native_module->SetRuntimeStubs(isolate); - return native_module; } TEST(CacheHit) { diff --git a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc index 736475ff55..75e927fafe 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc @@ -32,28 +32,27 @@ namespace { template <typename T> class ArgPassingHelper { public: - ArgPassingHelper( - WasmRunnerBase& runner, // NOLINT(runtime/references) - WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references) - std::initializer_list<uint8_t> bytes_inner_function, - std::initializer_list<uint8_t> bytes_outer_function, - const T& expected_lambda) - : isolate_(runner.main_isolate()), + ArgPassingHelper(WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler, + std::initializer_list<uint8_t> bytes_inner_function, + std::initializer_list<uint8_t> bytes_outer_function, + const T& expected_lambda) + : isolate_(runner->main_isolate()), expected_lambda_(expected_lambda), debug_info_(WasmInstanceObject::GetOrCreateDebugInfo( - runner.builder().instance_object())) { + runner->builder().instance_object())) { std::vector<uint8_t> inner_code{bytes_inner_function}; - inner_compiler.Build(inner_code.data(), - inner_code.data() + inner_code.size()); + inner_compiler->Build(inner_code.data(), + inner_code.data() + inner_code.size()); std::vector<uint8_t> outer_code{bytes_outer_function}; - runner.Build(outer_code.data(), outer_code.data() + outer_code.size()); + runner->Build(outer_code.data(), outer_code.data() + outer_code.size()); - int funcs_to_redict[] = {static_cast<int>(inner_compiler.function_index())}; - runner.builder().SetExecutable(); + int funcs_to_redict[] = { + static_cast<int>(inner_compiler->function_index())}; + runner->builder().SetExecutable(); WasmDebugInfo::RedirectToInterpreter(debug_info_, ArrayVector(funcs_to_redict)); - main_fun_wrapper_ = runner.builder().WrapCode(runner.function_index()); + main_fun_wrapper_ = runner->builder().WrapCode(runner->function_index()); } template <typename... Args> @@ -82,8 +81,7 @@ class ArgPassingHelper { template <typename T> static ArgPassingHelper<T> GetHelper( - WasmRunnerBase& runner, // NOLINT(runtime/references) - WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references) + WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler, std::initializer_list<uint8_t> bytes_inner_function, std::initializer_list<uint8_t> bytes_outer_function, const T& expected_lambda) { @@ -99,7 +97,7 @@ TEST(TestArgumentPassing_int32) { WasmFunctionCompiler& f2 = runner.NewFunction<int32_t, int32_t>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return 2*<0> + 1. WASM_I32_ADD(WASM_I32_MUL(WASM_I32V_1(2), WASM_GET_LOCAL(0)), WASM_ONE)}, {// Call f2 with param <0>. @@ -117,7 +115,7 @@ TEST(TestArgumentPassing_double_int64) { WasmFunctionCompiler& f2 = runner.NewFunction<double, int64_t>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return (double)<0>. WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))}, {// Call f2 with param (<0> | (<1> << 32)). @@ -150,7 +148,7 @@ TEST(TestArgumentPassing_int64_double) { WasmFunctionCompiler& f2 = runner.NewFunction<int64_t, double>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return (int64_t)<0>. WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))}, {// Call f2 with param <0>, convert returned value back to double. @@ -169,7 +167,7 @@ TEST(TestArgumentPassing_float_double) { WasmFunctionCompiler& f2 = runner.NewFunction<double, float>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return 2*(double)<0> + 1. WASM_F64_ADD( WASM_F64_MUL(WASM_F64(2), WASM_F64_CONVERT_F32(WASM_GET_LOCAL(0))), @@ -186,7 +184,7 @@ TEST(TestArgumentPassing_double_double) { WasmRunner<double, double, double> runner(ExecutionTier::kTurbofan); WasmFunctionCompiler& f2 = runner.NewFunction<double, double, double>(); - auto helper = GetHelper(runner, f2, + auto helper = GetHelper(&runner, &f2, {// Return <0> + <1>. WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}, {// Call f2 with params <0>, <1>. @@ -208,7 +206,7 @@ TEST(TestArgumentPassing_AllTypes) { runner.NewFunction<double, int32_t, int64_t, float, double>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, { // Convert all arguments to double, add them and return the sum. WASM_F64_ADD( // <0+1+2> + <3> diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc index 1ff2a899ad..c6486650ef 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc @@ -11,7 +11,6 @@ #include "src/utils/version.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" @@ -272,9 +271,8 @@ TEST(BlockWasmCodeGenAtDeserialization) { Cleanup(); } -namespace { - -void TestTransferrableWasmModules(bool should_share) { +UNINITIALIZED_TEST(CompiledWasmModulesTransfer) { + FlagScope<bool> flag_scope_engine(&FLAG_wasm_shared_engine, true); i::wasm::WasmEngine::InitializeOncePerProcess(); v8::internal::AccountingAllocator allocator; Zone zone(&allocator, ZONE_NAME); @@ -285,7 +283,7 @@ void TestTransferrableWasmModules(bool should_share) { v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); v8::Isolate* from_isolate = v8::Isolate::New(create_params); - std::vector<v8::WasmModuleObject::TransferrableModule> store; + std::vector<v8::CompiledWasmModule> store; std::shared_ptr<NativeModule> original_native_module; { v8::HandleScope scope(from_isolate); @@ -293,7 +291,7 @@ void TestTransferrableWasmModules(bool should_share) { Isolate* from_i_isolate = reinterpret_cast<Isolate*>(from_isolate); testing::SetupIsolateForWasmModule(from_i_isolate); - ErrorThrower thrower(from_i_isolate, "TestTransferrableWasmModules"); + ErrorThrower thrower(from_i_isolate, "TestCompiledWasmModulesTransfer"); auto enabled_features = WasmFeaturesFromIsolate(from_i_isolate); MaybeHandle<WasmModuleObject> maybe_module_object = from_i_isolate->wasm_engine()->SyncCompile( @@ -304,7 +302,7 @@ void TestTransferrableWasmModules(bool should_share) { v8::Local<v8::WasmModuleObject> v8_module = v8::Local<v8::WasmModuleObject>::Cast( v8::Utils::ToLocal(Handle<JSObject>::cast(module_object))); - store.push_back(v8_module->GetTransferrableModule()); + store.push_back(v8_module->GetCompiledModule()); original_native_module = module_object->shared_native_module(); } @@ -315,14 +313,13 @@ void TestTransferrableWasmModules(bool should_share) { LocalContext env(to_isolate); v8::MaybeLocal<v8::WasmModuleObject> transferred_module = - v8::WasmModuleObject::FromTransferrableModule(to_isolate, store[0]); + v8::WasmModuleObject::FromCompiledModule(to_isolate, store[0]); CHECK(!transferred_module.IsEmpty()); Handle<WasmModuleObject> module_object = Handle<WasmModuleObject>::cast( v8::Utils::OpenHandle(*transferred_module.ToLocalChecked())); std::shared_ptr<NativeModule> transferred_native_module = module_object->shared_native_module(); - bool is_sharing = (original_native_module == transferred_native_module); - CHECK_EQ(should_share, is_sharing); + CHECK_EQ(original_native_module, transferred_native_module); } to_isolate->Dispose(); } @@ -330,19 +327,6 @@ void TestTransferrableWasmModules(bool should_share) { from_isolate->Dispose(); } -} // namespace - -UNINITIALIZED_TEST(TransferrableWasmModulesCloned) { - FlagScope<bool> flag_scope_code(&FLAG_wasm_shared_code, false); - TestTransferrableWasmModules(false); -} - -UNINITIALIZED_TEST(TransferrableWasmModulesShared) { - FlagScope<bool> flag_scope_engine(&FLAG_wasm_shared_engine, true); - FlagScope<bool> flag_scope_code(&FLAG_wasm_shared_code, true); - TestTransferrableWasmModules(true); -} - #undef EMIT_CODE_WITH_END } // namespace test_wasm_serialization diff --git a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc index b5bacf57d4..2d6e930397 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc @@ -27,7 +27,7 @@ namespace test_wasm_shared_engine { class SharedEngine { public: explicit SharedEngine(size_t max_committed = kMaxWasmCodeMemory) - : wasm_engine_(base::make_unique<WasmEngine>()) {} + : wasm_engine_(std::make_unique<WasmEngine>()) {} ~SharedEngine() { // Ensure no remaining uses exist. CHECK(wasm_engine_.unique()); @@ -112,19 +112,19 @@ class SharedEngineIsolate { class SharedEngineThread : public v8::base::Thread { public: SharedEngineThread(SharedEngine* engine, - std::function<void(SharedEngineIsolate&)> callback) + std::function<void(SharedEngineIsolate*)> callback) : Thread(Options("SharedEngineThread")), engine_(engine), callback_(callback) {} void Run() override { SharedEngineIsolate isolate(engine_); - callback_(isolate); + callback_(&isolate); } private: SharedEngine* engine_; - std::function<void(SharedEngineIsolate&)> callback_; + std::function<void(SharedEngineIsolate*)> callback_; }; namespace { @@ -159,43 +159,39 @@ class MockInstantiationResolver : public InstantiationResultResolver { class MockCompilationResolver : public CompilationResultResolver { public: - MockCompilationResolver( - SharedEngineIsolate& isolate, // NOLINT(runtime/references) - Handle<Object>* out_instance) + MockCompilationResolver(SharedEngineIsolate* isolate, + Handle<Object>* out_instance) : isolate_(isolate), out_instance_(out_instance) {} void OnCompilationSucceeded(Handle<WasmModuleObject> result) override { - isolate_.isolate()->wasm_engine()->AsyncInstantiate( - isolate_.isolate(), - base::make_unique<MockInstantiationResolver>(out_instance_), result, - {}); + isolate_->isolate()->wasm_engine()->AsyncInstantiate( + isolate_->isolate(), + std::make_unique<MockInstantiationResolver>(out_instance_), result, {}); } void OnCompilationFailed(Handle<Object> error_reason) override { UNREACHABLE(); } private: - SharedEngineIsolate& isolate_; + SharedEngineIsolate* isolate_; Handle<Object>* out_instance_; }; -void PumpMessageLoop( - SharedEngineIsolate& isolate) { // NOLINT(runtime/references) +void PumpMessageLoop(SharedEngineIsolate* isolate) { v8::platform::PumpMessageLoop(i::V8::GetCurrentPlatform(), - isolate.v8_isolate(), + isolate->v8_isolate(), platform::MessageLoopBehavior::kWaitForWork); - isolate.isolate()->default_microtask_queue()->RunMicrotasks( - isolate.isolate()); + isolate->isolate()->default_microtask_queue()->RunMicrotasks( + isolate->isolate()); } Handle<WasmInstanceObject> CompileAndInstantiateAsync( - SharedEngineIsolate& isolate, // NOLINT(runtime/references) - ZoneBuffer* buffer) { - Handle<Object> maybe_instance = handle(Smi::kZero, isolate.isolate()); - auto enabled_features = WasmFeaturesFromIsolate(isolate.isolate()); + SharedEngineIsolate* isolate, ZoneBuffer* buffer) { + Handle<Object> maybe_instance = handle(Smi::kZero, isolate->isolate()); + auto enabled_features = WasmFeaturesFromIsolate(isolate->isolate()); constexpr const char* kAPIMethodName = "Test.CompileAndInstantiateAsync"; - isolate.isolate()->wasm_engine()->AsyncCompile( - isolate.isolate(), enabled_features, - base::make_unique<MockCompilationResolver>(isolate, &maybe_instance), + isolate->isolate()->wasm_engine()->AsyncCompile( + isolate->isolate(), enabled_features, + std::make_unique<MockCompilationResolver>(isolate, &maybe_instance), ModuleWireBytes(buffer->begin(), buffer->end()), true, kAPIMethodName); while (!maybe_instance->IsWasmInstanceObject()) PumpMessageLoop(isolate); Handle<WasmInstanceObject> instance = @@ -261,17 +257,19 @@ TEST(SharedEngineRunImported) { TEST(SharedEngineRunThreadedBuildingSync) { SharedEngine engine; - SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); - Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); + Handle<WasmInstanceObject> instance = + isolate->CompileAndInstantiate(buffer); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42); - Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); - CHECK_EQ(42, isolate.Run(instance)); + SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); + Handle<WasmInstanceObject> instance = + isolate->CompileAndInstantiate(buffer); + CHECK_EQ(42, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -281,19 +279,19 @@ TEST(SharedEngineRunThreadedBuildingSync) { TEST(SharedEngineRunThreadedBuildingAsync) { SharedEngine engine; - SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); + SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); Handle<WasmInstanceObject> instance = CompileAndInstantiateAsync(isolate, buffer); - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42); + SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); Handle<WasmInstanceObject> instance = CompileAndInstantiateAsync(isolate, buffer); - CHECK_EQ(42, isolate.Run(instance)); + CHECK_EQ(42, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -311,15 +309,15 @@ TEST(SharedEngineRunThreadedExecution) { Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); module = isolate.ExportInstance(instance); } - SharedEngineThread thread1(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread1(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread2(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); + CHECK_EQ(23, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -340,23 +338,23 @@ TEST(SharedEngineRunThreadedTierUp) { constexpr int kNumberOfThreads = 5; std::list<SharedEngineThread> threads; for (int i = 0; i < kNumberOfThreads; ++i) { - threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) { + threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { constexpr int kNumberOfIterations = 100; - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); for (int j = 0; j < kNumberOfIterations; ++j) { - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); } }); } - threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); + threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); WasmFeatures detected = kNoWasmFeatures; WasmCompilationUnit::CompileWasmFunction( - isolate.isolate(), module.get(), &detected, + isolate->isolate(), module.get(), &detected, &module->module()->functions[0], ExecutionTier::kTurbofan); - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); }); for (auto& thread : threads) CHECK(thread.Start()); for (auto& thread : threads) thread.Join(); diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc index 528d71f53c..09d64e5d97 100644 --- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc +++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc @@ -10,7 +10,6 @@ #include "src/wasm/graph-builder-interface.h" #include "src/wasm/module-compiler.h" #include "src/wasm/wasm-import-wrapper-cache.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-objects-inl.h" namespace v8 { @@ -75,29 +74,23 @@ byte* TestingModuleBuilder::AddMemory(uint32_t size, SharedFlag shared) { CHECK_NULL(mem_start_); CHECK_EQ(0, mem_size_); DCHECK(!instance_object_->has_memory_object()); - DCHECK_IMPLIES(test_module_->origin == kWasmOrigin, - size % kWasmPageSize == 0); + uint32_t initial_pages = RoundUp(size, kWasmPageSize) / kWasmPageSize; + uint32_t maximum_pages = (test_module_->maximum_pages != 0) + ? test_module_->maximum_pages + : initial_pages; test_module_->has_memory = true; - uint32_t max_size = - (test_module_->maximum_pages != 0) ? test_module_->maximum_pages : size; - uint32_t alloc_size = RoundUp(size, kWasmPageSize); - Handle<JSArrayBuffer> new_buffer; - if (shared == SharedFlag::kShared) { - CHECK(NewSharedArrayBuffer(isolate_, alloc_size, max_size) - .ToHandle(&new_buffer)); - } else { - CHECK(NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer)); - } - CHECK(!new_buffer.is_null()); - mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store()); - mem_size_ = size; - CHECK(size == 0 || mem_start_); - memset(mem_start_, 0, size); // Create the WasmMemoryObject. Handle<WasmMemoryObject> memory_object = - WasmMemoryObject::New(isolate_, new_buffer, max_size); + WasmMemoryObject::New(isolate_, initial_pages, maximum_pages, shared) + .ToHandleChecked(); instance_object_->set_memory_object(*memory_object); + + mem_start_ = + reinterpret_cast<byte*>(memory_object->array_buffer().backing_store()); + mem_size_ = size; + CHECK(size == 0 || mem_start_); + WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_); // TODO(wasm): Delete the following two lines when test-run-wasm will use a // multiple of kPageSize as memory size. At the moment, the effect of these @@ -328,7 +321,6 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() { auto native_module = isolate_->wasm_engine()->NewNativeModule( isolate_, enabled_features_, test_module_); native_module->SetWireBytes(OwnedVector<const uint8_t>()); - native_module->SetRuntimeStubs(isolate_); Handle<WasmModuleObject> module_object = WasmModuleObject::New(isolate_, std::move(native_module), script); @@ -487,7 +479,7 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode() { CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); OFStream os(tracing_scope.file()); - code->Disassemble("wasm wrapper", os); + code->Disassemble("wasm wrapper", os, isolate); } #endif } |