summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2020-05-05 09:19:02 +0200
committerMichaël Zasso <targos@protonmail.com>2020-05-12 16:12:13 +0200
commit1d6adf7432defeb39b751a19c68335e8afb0d8ee (patch)
tree7ab67931110b8d9db770d774c7a6d0d14c976c15 /deps/v8/test/unittests
parentaee36a04475a20c13663d1037aa6f175ff368bc7 (diff)
downloadnode-new-1d6adf7432defeb39b751a19c68335e8afb0d8ee.tar.gz
deps: update V8 to 8.3.110.9
PR-URL: https://github.com/nodejs/node/pull/32831 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'deps/v8/test/unittests')
-rw-r--r--deps/v8/test/unittests/BUILD.gn52
-rw-r--r--deps/v8/test/unittests/api/access-check-unittest.cc7
-rw-r--r--deps/v8/test/unittests/api/isolate-unittest.cc3
-rw-r--r--deps/v8/test/unittests/api/remote-object-unittest.cc3
-rw-r--r--deps/v8/test/unittests/api/v8-object-unittest.cc42
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-arm-unittest.cc10
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc15
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-ia32-unittest.cc21
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-mips-unittest.cc10
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-mips64-unittest.cc10
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-ppc-unittest.cc12
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-s390-unittest.cc10
-rw-r--r--deps/v8/test/unittests/assembler/turbo-assembler-x64-unittest.cc21
-rw-r--r--deps/v8/test/unittests/base/platform/platform-unittest.cc13
-rw-r--r--deps/v8/test/unittests/base/region-allocator-unittest.cc26
-rw-r--r--deps/v8/test/unittests/compiler/backend/instruction-selector-unittest.cc22
-rw-r--r--deps/v8/test/unittests/compiler/bytecode-analysis-unittest.cc8
-rw-r--r--deps/v8/test/unittests/compiler/constant-folding-reducer-unittest.cc109
-rw-r--r--deps/v8/test/unittests/compiler/graph-unittest.cc2
-rw-r--r--deps/v8/test/unittests/compiler/int64-lowering-unittest.cc12
-rw-r--r--deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc3
-rw-r--r--deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc70
-rw-r--r--deps/v8/test/unittests/compiler/node-cache-unittest.cc38
-rw-r--r--deps/v8/test/unittests/compiler/redundancy-elimination-unittest.cc14
-rw-r--r--deps/v8/test/unittests/compiler/state-values-utils-unittest.cc8
-rw-r--r--deps/v8/test/unittests/compiler/typer-unittest.cc116
-rw-r--r--deps/v8/test/unittests/execution/microtask-queue-unittest.cc145
-rw-r--r--deps/v8/test/unittests/heap/cppgc/allocation_unittest.cc42
-rw-r--r--deps/v8/test/unittests/heap/cppgc/finalizer-trait_unittest.cc118
-rw-r--r--deps/v8/test/unittests/heap/cppgc/garbage-collected_unittest.cc26
-rw-r--r--deps/v8/test/unittests/heap/cppgc/gc-info_unittest.cc153
-rw-r--r--deps/v8/test/unittests/heap/cppgc/heap-object-header_unittest.cc181
-rw-r--r--deps/v8/test/unittests/heap/cppgc/run-all-unittests.cc17
-rw-r--r--deps/v8/test/unittests/heap/cppgc/stack_unittest.cc256
-rw-r--r--deps/v8/test/unittests/heap/cppgc/tests.cc36
-rw-r--r--deps/v8/test/unittests/heap/cppgc/tests.h39
-rw-r--r--deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc15
-rw-r--r--deps/v8/test/unittests/heap/local-heap-unittest.cc38
-rw-r--r--deps/v8/test/unittests/heap/off-thread-factory-unittest.cc304
-rw-r--r--deps/v8/test/unittests/heap/safepoint-unittest.cc139
-rw-r--r--deps/v8/test/unittests/heap/scavenge-job-unittest.cc114
-rw-r--r--deps/v8/test/unittests/heap/worklist-unittest.cc15
-rw-r--r--deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc24
-rw-r--r--deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc20
-rw-r--r--deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc146
-rw-r--r--deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc118
-rw-r--r--deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc14
-rw-r--r--deps/v8/test/unittests/objects/value-serializer-unittest.cc9
-rw-r--r--deps/v8/test/unittests/profiler/strings-storage-unittest.cc49
-rw-r--r--deps/v8/test/unittests/test-utils.h9
-rw-r--r--deps/v8/test/unittests/torque/torque-unittest.cc142
-rw-r--r--deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc280
-rw-r--r--deps/v8/test/unittests/wasm/module-decoder-unittest.cc162
-rw-r--r--deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc4
54 files changed, 2494 insertions, 778 deletions
diff --git a/deps/v8/test/unittests/BUILD.gn b/deps/v8/test/unittests/BUILD.gn
index ab407c2fe6..f3b060e5da 100644
--- a/deps/v8/test/unittests/BUILD.gn
+++ b/deps/v8/test/unittests/BUILD.gn
@@ -7,7 +7,7 @@ import("../../gni/v8.gni")
if (is_fuchsia) {
import("//build/config/fuchsia/rules.gni")
- fuchsia_package("v8_unittests_pkg") {
+ cr_fuchsia_package("v8_unittests_pkg") {
testonly = true
binary = ":unittests"
package_name_override = "v8_unittests"
@@ -20,6 +20,52 @@ if (is_fuchsia) {
}
}
+# Stand-alone target for C++ GC unittests. This is used to ensure that it
+# builds without V8 as well. They are also included in the regular unittests
+# target for simplicity.
+v8_executable("cppgc_unittests") {
+ testonly = true
+
+ configs = [
+ "../..:external_config",
+ "../..:internal_config_base",
+ ]
+
+ sources = [ "heap/cppgc/run-all-unittests.cc" ]
+
+ deps = [
+ ":cppgc_unittests_sources",
+ "//testing/gmock",
+ "//testing/gtest",
+ ]
+}
+
+v8_source_set("cppgc_unittests_sources") {
+ testonly = true
+
+ sources = [
+ "heap/cppgc/allocation_unittest.cc",
+ "heap/cppgc/finalizer-trait_unittest.cc",
+ "heap/cppgc/garbage-collected_unittest.cc",
+ "heap/cppgc/gc-info_unittest.cc",
+ "heap/cppgc/heap-object-header_unittest.cc",
+ "heap/cppgc/stack_unittest.cc",
+ "heap/cppgc/tests.cc",
+ "heap/cppgc/tests.h",
+ ]
+
+ configs = [
+ "../..:external_config",
+ "../..:internal_config_base",
+ ]
+
+ deps = [
+ "../..:cppgc_for_testing",
+ "//testing/gmock",
+ "//testing/gtest",
+ ]
+}
+
v8_executable("unittests") {
testonly = true
@@ -29,6 +75,7 @@ v8_executable("unittests") {
#}],
deps = [
+ ":cppgc_unittests_sources",
":unittests_sources",
"../..:v8_for_testing",
"../..:v8_libbase",
@@ -170,12 +217,13 @@ v8_source_set("unittests_sources") {
"heap/heap-controller-unittest.cc",
"heap/heap-unittest.cc",
"heap/item-parallel-job-unittest.cc",
+ "heap/local-heap-unittest.cc",
"heap/marking-unittest.cc",
"heap/marking-worklist-unittest.cc",
"heap/memory-reducer-unittest.cc",
"heap/object-stats-unittest.cc",
"heap/off-thread-factory-unittest.cc",
- "heap/scavenge-job-unittest.cc",
+ "heap/safepoint-unittest.cc",
"heap/slot-set-unittest.cc",
"heap/spaces-unittest.cc",
"heap/unmapper-unittest.cc",
diff --git a/deps/v8/test/unittests/api/access-check-unittest.cc b/deps/v8/test/unittests/api/access-check-unittest.cc
index 3b63666f4b..cdcce68efd 100644
--- a/deps/v8/test/unittests/api/access-check-unittest.cc
+++ b/deps/v8/test/unittests/api/access-check-unittest.cc
@@ -19,8 +19,7 @@ bool AccessCheck(Local<Context> accessing_context,
MaybeLocal<Value> CompileRun(Isolate* isolate, const char* source) {
Local<String> source_string =
- String::NewFromUtf8(isolate, source, NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8(isolate, source).ToLocalChecked();
Local<Context> context = isolate->GetCurrentContext();
Local<Script> script =
Script::Compile(context, source_string).ToLocalChecked();
@@ -28,9 +27,7 @@ MaybeLocal<Value> CompileRun(Isolate* isolate, const char* source) {
}
v8::Local<v8::String> v8_str(const char* x) {
- return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
+ return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x).ToLocalChecked();
}
} // namespace
diff --git a/deps/v8/test/unittests/api/isolate-unittest.cc b/deps/v8/test/unittests/api/isolate-unittest.cc
index cda251f775..429d70617a 100644
--- a/deps/v8/test/unittests/api/isolate-unittest.cc
+++ b/deps/v8/test/unittests/api/isolate-unittest.cc
@@ -75,8 +75,7 @@ using IncumbentContextTest = TestWithIsolate;
// scenarios.
TEST_F(IncumbentContextTest, Basic) {
auto Str = [&](const char* s) {
- return String::NewFromUtf8(isolate(), s, NewStringType::kNormal)
- .ToLocalChecked();
+ return String::NewFromUtf8(isolate(), s).ToLocalChecked();
};
auto Run = [&](Local<Context> context, const char* script) {
Context::Scope scope(context);
diff --git a/deps/v8/test/unittests/api/remote-object-unittest.cc b/deps/v8/test/unittests/api/remote-object-unittest.cc
index 39434a8f9a..5fcc78bbe1 100644
--- a/deps/v8/test/unittests/api/remote-object-unittest.cc
+++ b/deps/v8/test/unittests/api/remote-object-unittest.cc
@@ -105,8 +105,7 @@ TEST_F(RemoteObjectTest, ClassOf) {
AccessCheck, NamedPropertyHandlerConfiguration(NamedGetter),
IndexedPropertyHandlerConfiguration());
constructor_template->SetClassName(
- String::NewFromUtf8(isolate(), "test_class", NewStringType::kNormal)
- .ToLocalChecked());
+ String::NewFromUtf8Literal(isolate(), "test_class"));
Local<Object> remote_object =
constructor_template->NewRemoteInstance().ToLocalChecked();
diff --git a/deps/v8/test/unittests/api/v8-object-unittest.cc b/deps/v8/test/unittests/api/v8-object-unittest.cc
index eb72d45263..a3c0c2574c 100644
--- a/deps/v8/test/unittests/api/v8-object-unittest.cc
+++ b/deps/v8/test/unittests/api/v8-object-unittest.cc
@@ -20,9 +20,7 @@ TEST_F(ObjectTest, SetAccessorWhenUnconfigurablePropAlreadyDefined) {
TryCatch try_catch(isolate());
Local<Object> global = context()->Global();
- Local<String> property_name =
- String::NewFromUtf8(isolate(), "foo", NewStringType::kNormal)
- .ToLocalChecked();
+ Local<String> property_name = String::NewFromUtf8Literal(isolate(), "foo");
PropertyDescriptor prop_desc;
prop_desc.set_configurable(false);
@@ -51,8 +49,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
Local<Signature> signature = Signature::New(isolate(), function_template);
Local<String> property_key =
- String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8Literal(isolate(), "property");
Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
isolate(),
[](const FunctionCallbackInfo<Value>& info) {
@@ -72,8 +69,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
Local<Function> interface_for_prototype =
function_template->GetFunction(prototype_context).ToLocalChecked();
Local<String> prototype_key =
- String::NewFromUtf8(isolate(), "prototype", NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8Literal(isolate(), "prototype");
Local<Object> prototype =
interface_for_prototype->Get(caller_context, prototype_key)
.ToLocalChecked()
@@ -91,9 +87,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
EXPECT_EQ(2, call_count);
// Test with a compiled version.
- Local<String> object_key =
- String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
- .ToLocalChecked();
+ Local<String> object_key = String::NewFromUtf8Literal(isolate(), "object");
caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
const char script[] =
"function f() { object.property; object.property = 0; } "
@@ -103,10 +97,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPrototype) {
"f();";
Context::Scope scope(caller_context);
internal::FLAG_allow_natives_syntax = true;
- Script::Compile(
- caller_context,
- String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
- .ToLocalChecked())
+ Script::Compile(caller_context, String::NewFromUtf8Literal(isolate(), script))
.ToLocalChecked()
->Run(caller_context)
.ToLocalChecked();
@@ -123,8 +114,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
Local<Signature> signature = Signature::New(isolate(), function_template);
Local<String> property_key =
- String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8Literal(isolate(), "property");
Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
isolate(),
[](const FunctionCallbackInfo<Value>& info) {
@@ -149,9 +139,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
EXPECT_EQ(2, call_count);
// Test with a compiled version.
- Local<String> object_key =
- String::NewFromUtf8(isolate(), "object", NewStringType::kNormal)
- .ToLocalChecked();
+ Local<String> object_key = String::NewFromUtf8Literal(isolate(), "object");
caller_context->Global()->Set(caller_context, object_key, object).ToChecked();
const char script[] =
"function f() { object.property; object.property = 0; } "
@@ -161,10 +149,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnPlatformObject) {
"f();";
Context::Scope scope(caller_context);
internal::FLAG_allow_natives_syntax = true;
- Script::Compile(
- caller_context,
- String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
- .ToLocalChecked())
+ Script::Compile(caller_context, String::NewFromUtf8Literal(isolate(), script))
.ToLocalChecked()
->Run(caller_context)
.ToLocalChecked();
@@ -180,8 +165,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate());
Local<String> property_key =
- String::NewFromUtf8(isolate(), "property", NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8Literal(isolate(), "property");
Local<FunctionTemplate> get_or_set = FunctionTemplate::New(
isolate(),
[](const FunctionCallbackInfo<Value>& info) {
@@ -204,8 +188,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
// Test with a compiled version.
Local<String> interface_key =
- String::NewFromUtf8(isolate(), "Interface", NewStringType::kNormal)
- .ToLocalChecked();
+ String::NewFromUtf8Literal(isolate(), "Interface");
caller_context->Global()
->Set(caller_context, interface_key, interface)
.ToChecked();
@@ -217,10 +200,7 @@ TEST_F(LapContextTest, CurrentContextInLazyAccessorOnInterface) {
"f();";
Context::Scope scope(caller_context);
internal::FLAG_allow_natives_syntax = true;
- Script::Compile(
- caller_context,
- String::NewFromUtf8(isolate(), script, v8::NewStringType::kNormal)
- .ToLocalChecked())
+ Script::Compile(caller_context, String::NewFromUtf8Literal(isolate(), script))
.ToLocalChecked()
->Run(caller_context)
.ToLocalChecked();
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-arm-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-arm-unittest.cc
index 76dd04d77c..2c0c01701c 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-arm-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-arm-unittest.cc
@@ -32,14 +32,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -49,8 +50,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
@@ -60,7 +62,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
index 02a6a8e763..0a9ac748c0 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-arm64-unittest.cc
@@ -32,14 +32,17 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
+ __ CodeEntry();
+
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -49,10 +52,13 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
+ __ CodeEntry();
+
// Fail if the first parameter is 17.
__ Mov(w1, Immediate(17));
__ Cmp(w0, w1); // 1st parameter is in {w0}.
@@ -60,7 +66,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
@@ -113,6 +119,7 @@ TEST_P(TurboAssemblerTestMoveObjectAndSlot, MoveObjectAndSlot) {
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ CodeEntry();
__ Push(x0, padreg);
__ Mov(test_case.object, x1);
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-ia32-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-ia32-unittest.cc
index 548cb34fc7..f0cb96d47d 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-ia32-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-ia32-unittest.cc
@@ -5,6 +5,7 @@
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
+#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
@@ -16,26 +17,30 @@ namespace internal {
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
-TEST(TurboAssemblerTest, TestHardAbort) {
+class TurboAssemblerTest : public TestWithIsolate {};
+
+TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
- auto f = GeneratedCode<void>::FromBuffer(nullptr, buffer->start());
+ auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, "abort: no reason");
}
-TEST(TurboAssemblerTest, TestCheck) {
+TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
@@ -45,9 +50,9 @@ TEST(TurboAssemblerTest, TestCheck) {
__ ret(0);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
- auto f = GeneratedCode<void, int>::FromBuffer(nullptr, buffer->start());
+ auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-mips-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-mips-unittest.cc
index 5ea6b2f3f8..b8a645e6a7 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-mips-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-mips-unittest.cc
@@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -39,8 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter (in {a0}) is 17.
@@ -48,7 +50,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-mips64-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-mips64-unittest.cc
index fe9e815981..c954ffcc65 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-mips64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-mips64-unittest.cc
@@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -39,8 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter (in {a0}) is 17.
@@ -48,7 +50,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-ppc-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-ppc-unittest.cc
index 51744bd92d..08c205c2ea 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-ppc-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-ppc-unittest.cc
@@ -22,15 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
-
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -40,9 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
-
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
@@ -52,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-s390-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-s390-unittest.cc
index 959ec03157..b0c398f571 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-s390-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-s390-unittest.cc
@@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@@ -39,8 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
@@ -50,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
diff --git a/deps/v8/test/unittests/assembler/turbo-assembler-x64-unittest.cc b/deps/v8/test/unittests/assembler/turbo-assembler-x64-unittest.cc
index 621f598f75..43dd6b79d6 100644
--- a/deps/v8/test/unittests/assembler/turbo-assembler-x64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/turbo-assembler-x64-unittest.cc
@@ -5,6 +5,7 @@
#include "src/codegen/macro-assembler.h"
#include "src/execution/simulator.h"
#include "test/common/assembler-tester.h"
+#include "test/unittests/test-utils.h"
#include "testing/gtest-support.h"
namespace v8 {
@@ -16,26 +17,30 @@ namespace internal {
// a buffer and executing them. These tests do not initialize the
// V8 library, create a context, or use any V8 objects.
-TEST(TurboAssemblerTest, TestHardAbort) {
+class TurboAssemblerTest : public TestWithIsolate {};
+
+TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
- auto f = GeneratedCode<void>::FromBuffer(nullptr, buffer->start());
+ auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
ASSERT_DEATH_IF_SUPPORTED({ f.Call(); }, "abort: no reason");
}
-TEST(TurboAssemblerTest, TestCheck) {
+TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
- TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
+ TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
+ __ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
@@ -45,9 +50,9 @@ TEST(TurboAssemblerTest, TestCheck) {
__ ret(0);
CodeDesc desc;
- tasm.GetCode(nullptr, &desc);
+ tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
- auto f = GeneratedCode<void, int>::FromBuffer(nullptr, buffer->start());
+ auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
f.Call(0);
f.Call(18);
diff --git a/deps/v8/test/unittests/base/platform/platform-unittest.cc b/deps/v8/test/unittests/base/platform/platform-unittest.cc
index 27154b3c24..b447778b49 100644
--- a/deps/v8/test/unittests/base/platform/platform-unittest.cc
+++ b/deps/v8/test/unittests/base/platform/platform-unittest.cc
@@ -83,5 +83,18 @@ TEST_F(ThreadLocalStorageTest, DoTest) {
Join();
}
+TEST(StackTest, GetStackStart) { EXPECT_NE(nullptr, Stack::GetStackStart()); }
+
+TEST(StackTest, GetCurrentStackPosition) {
+ EXPECT_NE(nullptr, Stack::GetCurrentStackPosition());
+}
+
+TEST(StackTest, StackVariableInBounds) {
+ void* dummy;
+ ASSERT_GT(Stack::GetStackStart(), Stack::GetCurrentStackPosition());
+ EXPECT_GT(Stack::GetStackStart(), Stack::GetStackSlot(&dummy));
+ EXPECT_LT(Stack::GetCurrentStackPosition(), Stack::GetStackSlot(&dummy));
+}
+
} // namespace base
} // namespace v8
diff --git a/deps/v8/test/unittests/base/region-allocator-unittest.cc b/deps/v8/test/unittests/base/region-allocator-unittest.cc
index caec4894c9..df154ff4f3 100644
--- a/deps/v8/test/unittests/base/region-allocator-unittest.cc
+++ b/deps/v8/test/unittests/base/region-allocator-unittest.cc
@@ -14,9 +14,7 @@ using Address = RegionAllocator::Address;
using v8::internal::KB;
using v8::internal::MB;
-class RegionAllocatorTest : public ::testing::TestWithParam<int> {};
-
-TEST_P(RegionAllocatorTest, SimpleAllocateRegionAt) {
+TEST(RegionAllocatorTest, SimpleAllocateRegionAt) {
const size_t kPageSize = 4 * KB;
const size_t kPageCount = 16;
const size_t kSize = kPageSize * kPageCount;
@@ -50,7 +48,7 @@ TEST_P(RegionAllocatorTest, SimpleAllocateRegionAt) {
CHECK_EQ(ra.AllocateRegion(kSize), kBegin);
}
-TEST_P(RegionAllocatorTest, SimpleAllocateRegion) {
+TEST(RegionAllocatorTest, SimpleAllocateRegion) {
const size_t kPageSize = 4 * KB;
const size_t kPageCount = 16;
const size_t kSize = kPageSize * kPageCount;
@@ -79,7 +77,7 @@ TEST_P(RegionAllocatorTest, SimpleAllocateRegion) {
CHECK_EQ(ra.free_size(), 0);
}
-TEST_P(RegionAllocatorTest, AllocateRegionRandom) {
+TEST(RegionAllocatorTest, AllocateRegionRandom) {
const size_t kPageSize = 8 * KB;
const size_t kPageCountLog = 16;
const size_t kPageCount = (size_t{1} << kPageCountLog);
@@ -87,7 +85,7 @@ TEST_P(RegionAllocatorTest, AllocateRegionRandom) {
const Address kBegin = static_cast<Address>(153 * MB);
const Address kEnd = kBegin + kSize;
- base::RandomNumberGenerator rng(GetParam());
+ base::RandomNumberGenerator rng(::testing::FLAGS_gtest_random_seed);
RegionAllocator ra(kBegin, kSize, kPageSize);
std::set<Address> allocated_pages;
@@ -123,7 +121,7 @@ TEST_P(RegionAllocatorTest, AllocateRegionRandom) {
CHECK_EQ(ra.AllocateRegion(kPageSize), RegionAllocator::kAllocationFailure);
}
-TEST_P(RegionAllocatorTest, AllocateBigRegions) {
+TEST(RegionAllocatorTest, AllocateBigRegions) {
const size_t kPageSize = 4 * KB;
const size_t kPageCountLog = 10;
const size_t kPageCount = (size_t{1} << kPageCountLog) - 1;
@@ -153,7 +151,7 @@ TEST_P(RegionAllocatorTest, AllocateBigRegions) {
CHECK_EQ(ra.free_size(), 0);
}
-TEST_P(RegionAllocatorTest, MergeLeftToRightCoalecsingRegions) {
+TEST(RegionAllocatorTest, MergeLeftToRightCoalecsingRegions) {
const size_t kPageSize = 4 * KB;
const size_t kPageCountLog = 10;
const size_t kPageCount = (size_t{1} << kPageCountLog);
@@ -187,8 +185,8 @@ TEST_P(RegionAllocatorTest, MergeLeftToRightCoalecsingRegions) {
CHECK_EQ(ra.free_size(), 0);
}
-TEST_P(RegionAllocatorTest, MergeRightToLeftCoalecsingRegions) {
- base::RandomNumberGenerator rng(GetParam());
+TEST(RegionAllocatorTest, MergeRightToLeftCoalecsingRegions) {
+ base::RandomNumberGenerator rng(::testing::FLAGS_gtest_random_seed);
const size_t kPageSize = 4 * KB;
const size_t kPageCountLog = 10;
const size_t kPageCount = (size_t{1} << kPageCountLog);
@@ -236,7 +234,7 @@ TEST_P(RegionAllocatorTest, MergeRightToLeftCoalecsingRegions) {
CHECK_EQ(ra.AllocateRegion(kSize), kBegin);
}
-TEST_P(RegionAllocatorTest, Fragmentation) {
+TEST(RegionAllocatorTest, Fragmentation) {
const size_t kPageSize = 64 * KB;
const size_t kPageCount = 9;
const size_t kSize = kPageSize * kPageCount;
@@ -283,7 +281,7 @@ TEST_P(RegionAllocatorTest, Fragmentation) {
CHECK_EQ(ra.AllocateRegion(kSize), kBegin);
}
-TEST_P(RegionAllocatorTest, FindRegion) {
+TEST(RegionAllocatorTest, FindRegion) {
const size_t kPageSize = 4 * KB;
const size_t kPageCount = 16;
const size_t kSize = kPageSize * kPageCount;
@@ -322,7 +320,7 @@ TEST_P(RegionAllocatorTest, FindRegion) {
}
}
-TEST_P(RegionAllocatorTest, TrimRegion) {
+TEST(RegionAllocatorTest, TrimRegion) {
const size_t kPageSize = 4 * KB;
const size_t kPageCount = 64;
const size_t kSize = kPageSize * kPageCount;
@@ -352,7 +350,5 @@ TEST_P(RegionAllocatorTest, TrimRegion) {
CHECK_EQ(ra.AllocateRegion(kSize), kBegin);
}
-INSTANTIATE_TEST_SUITE_P(RegionAllocatorTest, RegionAllocatorTest,
- testing::Values(123));
} // namespace base
} // namespace v8
diff --git a/deps/v8/test/unittests/compiler/backend/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/backend/instruction-selector-unittest.cc
index 95191819a8..9607aa94a9 100644
--- a/deps/v8/test/unittests/compiler/backend/instruction-selector-unittest.cc
+++ b/deps/v8/test/unittests/compiler/backend/instruction-selector-unittest.cc
@@ -338,7 +338,8 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
Node* context = m.Parameter(2);
ZoneVector<MachineType> int32_type(1, MachineType::Int32(), zone());
- ZoneVector<MachineType> empty_types(zone());
+ ZoneVector<MachineType> tagged_type(1, MachineType::AnyTagged(), zone());
+ ZoneVector<MachineType> empty_type(zone());
auto call_descriptor = Linkage::GetJSCallDescriptor(
zone(), false, 1,
@@ -349,9 +350,10 @@ TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
m.common()->TypedStateValues(&int32_type, SparseInputMask::Dense()),
m.Int32Constant(1));
Node* locals = m.AddNode(
- m.common()->TypedStateValues(&empty_types, SparseInputMask::Dense()));
+ m.common()->TypedStateValues(&empty_type, SparseInputMask::Dense()));
Node* stack = m.AddNode(
- m.common()->TypedStateValues(&empty_types, SparseInputMask::Dense()));
+ m.common()->TypedStateValues(&tagged_type, SparseInputMask::Dense()),
+ m.UndefinedConstant());
Node* context_sentinel = m.Int32Constant(0);
Node* state_node = m.AddNode(
m.common()->FrameState(bailout_id, OutputFrameStateCombine::PokeAt(0),
@@ -487,7 +489,6 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
Node* context2 = m.Int32Constant(46);
ZoneVector<MachineType> int32_type(1, MachineType::Int32(), zone());
- ZoneVector<MachineType> int32x2_type(2, MachineType::Int32(), zone());
ZoneVector<MachineType> float64_type(1, MachineType::Float64(), zone());
Callable callable = Builtins::CallableFor(isolate(), Builtins::kToObject);
@@ -518,8 +519,8 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
m.common()->TypedStateValues(&float64_type, SparseInputMask::Dense()),
m.Float64Constant(0.25));
Node* stack2 = m.AddNode(
- m.common()->TypedStateValues(&int32x2_type, SparseInputMask::Dense()),
- m.Int32Constant(44), m.Int32Constant(45));
+ m.common()->TypedStateValues(&int32_type, SparseInputMask::Dense()),
+ m.Int32Constant(44));
Node* state_node =
m.AddNode(m.common()->FrameState(bailout_id_before,
OutputFrameStateCombine::PokeAt(0),
@@ -550,7 +551,7 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
1 + // Code object.
1 + // Poison index.
1 + // Frame state deopt id
- 6 + // One input for each value in frame state + context.
+ 5 + // One input for each value in frame state + context.
5 + // One input for each value in the parent frame state + context.
1 + // Function.
1; // Context.
@@ -576,17 +577,16 @@ TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) {
// Values from the nested frame.
EXPECT_EQ(1u, desc_before->parameters_count());
EXPECT_EQ(1u, desc_before->locals_count());
- EXPECT_EQ(2u, desc_before->stack_count());
+ EXPECT_EQ(1u, desc_before->stack_count());
EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(9)));
EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(10)));
EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(11)));
EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(12)));
- EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(13)));
// Function.
- EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(14)));
+ EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13)));
// Context.
- EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(15)));
+ EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(14)));
// Continuation.
EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
diff --git a/deps/v8/test/unittests/compiler/bytecode-analysis-unittest.cc b/deps/v8/test/unittests/compiler/bytecode-analysis-unittest.cc
index d3c81344f2..c6fe8948bc 100644
--- a/deps/v8/test/unittests/compiler/bytecode-analysis-unittest.cc
+++ b/deps/v8/test/unittests/compiler/bytecode-analysis-unittest.cc
@@ -256,7 +256,7 @@ TEST_F(BytecodeAnalysisTest, SimpleLoop) {
expected_liveness.emplace_back("L..L", "L.L.");
loop_builder.BindContinueTarget();
- loop_builder.JumpToHeader(0);
+ loop_builder.JumpToHeader(0, nullptr);
expected_liveness.emplace_back("L.L.", "L.L.");
}
@@ -361,7 +361,7 @@ TEST_F(BytecodeAnalysisTest, DiamondInLoop) {
builder.Bind(&end_label);
loop_builder.BindContinueTarget();
- loop_builder.JumpToHeader(0);
+ loop_builder.JumpToHeader(0, nullptr);
expected_liveness.emplace_back("L...", "L...");
}
@@ -433,12 +433,12 @@ TEST_F(BytecodeAnalysisTest, KillingLoopInsideLoop) {
expected_liveness.emplace_back("LL.L", "LL..");
inner_loop_builder.BindContinueTarget();
- inner_loop_builder.JumpToHeader(1);
+ inner_loop_builder.JumpToHeader(1, &loop_builder);
expected_liveness.emplace_back(".L..", ".L..");
}
loop_builder.BindContinueTarget();
- loop_builder.JumpToHeader(0);
+ loop_builder.JumpToHeader(0, nullptr);
expected_liveness.emplace_back("LL..", "LL..");
}
diff --git a/deps/v8/test/unittests/compiler/constant-folding-reducer-unittest.cc b/deps/v8/test/unittests/compiler/constant-folding-reducer-unittest.cc
index dee5c56e82..4f3d05173d 100644
--- a/deps/v8/test/unittests/compiler/constant-folding-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/constant-folding-reducer-unittest.cc
@@ -80,6 +80,12 @@ class ConstantFoldingReducerTest : public TypedGraphTest {
return reducer.Reduce(node);
}
+ Node* UseValue(Node* node) {
+ Node* start = graph()->NewNode(common()->Start(1));
+ Node* zero = graph()->NewNode(common()->NumberConstant(0));
+ return graph()->NewNode(common()->Return(), zero, node, start, start);
+ }
+
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
JSHeapBroker* broker() { return &broker_; }
@@ -91,20 +97,26 @@ class ConstantFoldingReducerTest : public TypedGraphTest {
TEST_F(ConstantFoldingReducerTest, ParameterWithMinusZero) {
{
- Reduction r = Reduce(Parameter(
- Type::NewConstant(broker(), factory()->minus_zero_value(), zone())));
+ Node* node = Parameter(
+ Type::Constant(broker(), factory()->minus_zero_value(), zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(-0.0));
}
{
- Reduction r = Reduce(Parameter(Type::MinusZero()));
+ Node* node = Parameter(Type::MinusZero());
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(-0.0));
}
{
- Reduction r = Reduce(Parameter(Type::Union(
+ Node* node = Parameter(Type::Union(
Type::MinusZero(),
- Type::NewConstant(broker(), factory()->NewNumber(0), zone()), zone())));
+ Type::Constant(broker(), factory()->NewNumber(0), zone()), zone()));
+ UseValue(node);
+ Reduction r = Reduce(node);
EXPECT_FALSE(r.Changed());
}
}
@@ -112,14 +124,18 @@ TEST_F(ConstantFoldingReducerTest, ParameterWithMinusZero) {
TEST_F(ConstantFoldingReducerTest, ParameterWithNull) {
Handle<HeapObject> null = factory()->null_value();
{
- Reduction r = Reduce(Parameter(Type::NewConstant(broker(), null, zone())));
+ Node* node = Parameter(Type::Constant(broker(), null, zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsHeapConstant(null));
+ EXPECT_THAT(use_value->InputAt(1), IsHeapConstant(null));
}
{
- Reduction r = Reduce(Parameter(Type::Null()));
+ Node* node = Parameter(Type::Null());
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsHeapConstant(null));
+ EXPECT_THAT(use_value->InputAt(1), IsHeapConstant(null));
}
}
@@ -129,51 +145,62 @@ TEST_F(ConstantFoldingReducerTest, ParameterWithNaN) {
std::numeric_limits<double>::signaling_NaN()};
TRACED_FOREACH(double, nan, kNaNs) {
Handle<Object> constant = factory()->NewNumber(nan);
- Reduction r =
- Reduce(Parameter(Type::NewConstant(broker(), constant, zone())));
+ Node* node = Parameter(Type::Constant(broker(), constant, zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
{
- Reduction r = Reduce(
- Parameter(Type::NewConstant(broker(), factory()->nan_value(), zone())));
+ Node* node =
+ Parameter(Type::Constant(broker(), factory()->nan_value(), zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
{
- Reduction r = Reduce(Parameter(Type::NaN()));
+ Node* node = Parameter(Type::NaN());
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(IsNaN()));
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithPlainNumber) {
TRACED_FOREACH(double, value, kFloat64Values) {
Handle<Object> constant = factory()->NewNumber(value);
- Reduction r =
- Reduce(Parameter(Type::NewConstant(broker(), constant, zone())));
+ Node* node = Parameter(Type::Constant(broker(), constant, zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(value));
}
TRACED_FOREACH(double, value, kIntegerValues) {
- Reduction r = Reduce(Parameter(Type::Range(value, value, zone())));
+ Node* node = Parameter(Type::Range(value, value, zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+ EXPECT_THAT(use_value->InputAt(1), IsNumberConstant(value));
}
}
TEST_F(ConstantFoldingReducerTest, ParameterWithUndefined) {
Handle<HeapObject> undefined = factory()->undefined_value();
{
- Reduction r = Reduce(Parameter(Type::Undefined()));
+ Node* node = Parameter(Type::Undefined());
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
+ EXPECT_THAT(use_value->InputAt(1), IsUndefinedConstant());
}
{
- Reduction r =
- Reduce(Parameter(Type::NewConstant(broker(), undefined, zone())));
+ Node* node = Parameter(Type::Constant(broker(), undefined, zone()));
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsHeapConstant(undefined));
+ EXPECT_THAT(use_value->InputAt(1), IsUndefinedConstant());
}
}
@@ -193,8 +220,8 @@ TEST_F(ConstantFoldingReducerTest, ToBooleanWithFalsish) {
Type::Union(
Type::Undetectable(),
Type::Union(
- Type::NewConstant(
- broker(), factory()->false_value(), zone()),
+ Type::Constant(broker(), factory()->false_value(),
+ zone()),
Type::Range(0.0, 0.0, zone()), zone()),
zone()),
zone()),
@@ -202,28 +229,34 @@ TEST_F(ConstantFoldingReducerTest, ToBooleanWithFalsish) {
zone()),
zone()),
0);
- Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
+ Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFalseConstant());
+ EXPECT_THAT(use_value->InputAt(1), IsFalseConstant());
}
TEST_F(ConstantFoldingReducerTest, ToBooleanWithTruish) {
Node* input = Parameter(
Type::Union(
- Type::NewConstant(broker(), factory()->true_value(), zone()),
+ Type::Constant(broker(), factory()->true_value(), zone()),
Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
zone()),
0);
- Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
+ Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsTrueConstant());
+ EXPECT_THAT(use_value->InputAt(1), IsTrueConstant());
}
TEST_F(ConstantFoldingReducerTest, ToBooleanWithNonZeroPlainNumber) {
Node* input = Parameter(Type::Range(1, V8_INFINITY, zone()), 0);
- Reduction r = Reduce(graph()->NewNode(simplified()->ToBoolean(), input));
+ Node* node = graph()->NewNode(simplified()->ToBoolean(), input);
+ Node* use_value = UseValue(node);
+ Reduction r = Reduce(node);
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsTrueConstant());
+ EXPECT_THAT(use_value->InputAt(1), IsTrueConstant());
}
} // namespace constant_folding_reducer_unittest
diff --git a/deps/v8/test/unittests/compiler/graph-unittest.cc b/deps/v8/test/unittests/compiler/graph-unittest.cc
index 0008eadaf9..0d825dc60b 100644
--- a/deps/v8/test/unittests/compiler/graph-unittest.cc
+++ b/deps/v8/test/unittests/compiler/graph-unittest.cc
@@ -66,7 +66,7 @@ Node* GraphTest::NumberConstant(volatile double value) {
Node* GraphTest::HeapConstant(const Handle<HeapObject>& value) {
Node* node = graph()->NewNode(common()->HeapConstant(value));
- Type type = Type::NewConstant(broker(), value, zone());
+ Type type = Type::Constant(broker(), value, zone());
NodeProperties::SetType(node, type);
return node;
}
diff --git a/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc b/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc
index 7e927ea078..30e24b0aa4 100644
--- a/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc
@@ -1016,10 +1016,8 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseBigIntToI64) {
StubCallMode::kCallCodeObject); // stub call mode
auto lowering_special_case = std::make_unique<Int64LoweringSpecialCase>();
- lowering_special_case->bigint_to_i64_call_descriptor =
- bigint_to_i64_call_descriptor;
- lowering_special_case->bigint_to_i32_pair_call_descriptor =
- bigint_to_i32_pair_call_descriptor;
+ lowering_special_case->replacements.insert(
+ {bigint_to_i64_call_descriptor, bigint_to_i32_pair_call_descriptor});
Node* call_node =
graph()->NewNode(common()->Call(bigint_to_i64_call_descriptor), target,
@@ -1064,10 +1062,8 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseI64ToBigInt) {
StubCallMode::kCallCodeObject); // stub call mode
auto lowering_special_case = std::make_unique<Int64LoweringSpecialCase>();
- lowering_special_case->i64_to_bigint_call_descriptor =
- i64_to_bigint_call_descriptor;
- lowering_special_case->i32_pair_to_bigint_call_descriptor =
- i32_pair_to_bigint_call_descriptor;
+ lowering_special_case->replacements.insert(
+ {i64_to_bigint_call_descriptor, i32_pair_to_bigint_call_descriptor});
Node* call = graph()->NewNode(common()->Call(i64_to_bigint_call_descriptor),
target, i64, start(), start());
diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
index eed74f6181..fe5a02e3f2 100644
--- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -174,8 +174,7 @@ TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
Reduction r = Reduce(
graph()->NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
lhs, the_hole, context, effect, control));
- ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFalseConstant());
+ ASSERT_FALSE(r.Changed());
}
}
diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
index bcf0a7101c..c3659032cf 100644
--- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -1058,6 +1058,76 @@ TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
}
}
+// -----------------------------------------------------------------------------
+// Word32Equal
+
+TEST_F(MachineOperatorReducerTest,
+ Word32EqualWithShiftedMaskedValueAndConstant) {
+ // ((x >> K1) & K2) == K3 => (x & (K2 << K1)) == (K3 << K1)
+ Node* const p0 = Parameter(0);
+ TRACED_FOREACH(uint32_t, mask, kUint32Values) {
+ TRACED_FOREACH(uint32_t, rhs, kUint32Values) {
+ TRACED_FORRANGE(uint32_t, shift_bits, 1, 31) {
+ Node* node = graph()->NewNode(
+ machine()->Word32Equal(),
+ graph()->NewNode(machine()->Word32And(),
+ graph()->NewNode(machine()->Word32Shr(), p0,
+ Uint32Constant(shift_bits)),
+ Uint32Constant(mask)),
+ Uint32Constant(rhs));
+ Reduction r = Reduce(node);
+ uint32_t new_mask = mask << shift_bits;
+ uint32_t new_rhs = rhs << shift_bits;
+ if (new_mask >> shift_bits == mask && new_rhs >> shift_bits == rhs) {
+ ASSERT_TRUE(r.Changed());
+ // The left-hand side of the equality is now a Word32And operation,
+ // unless the mask is zero in which case the newly-created Word32And
+ // is immediately reduced away.
+ Matcher<Node*> lhs = mask == 0
+ ? IsInt32Constant(0)
+ : IsWord32And(p0, IsInt32Constant(new_mask));
+ EXPECT_THAT(r.replacement(),
+ IsWord32Equal(lhs, IsInt32Constant(new_rhs)));
+ } else {
+ ASSERT_FALSE(r.Changed());
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Branch
+
+TEST_F(MachineOperatorReducerTest, BranchWithShiftedMaskedValue) {
+ // Branch condition (x >> K1) & K2 => x & (K2 << K1)
+ Node* const p0 = Parameter(0);
+ TRACED_FOREACH(uint32_t, mask, kUint32Values) {
+ TRACED_FORRANGE(uint32_t, shift_bits, 1, 31) {
+ Node* node = graph()->NewNode(
+ common()->Branch(),
+ graph()->NewNode(machine()->Word32And(),
+ graph()->NewNode(machine()->Word32Shr(), p0,
+ Uint32Constant(shift_bits)),
+ Uint32Constant(mask)),
+ graph()->start());
+ Reduction r = Reduce(node);
+ uint32_t new_mask = mask << shift_bits;
+ if (new_mask >> shift_bits == mask) {
+ ASSERT_TRUE(r.Changed());
+ // The branch condition is now a Word32And operation, unless the mask is
+ // zero in which case the newly-created Word32And is immediately reduced
+ // away.
+ Matcher<Node*> lhs = mask == 0
+ ? IsInt32Constant(0)
+ : IsWord32And(p0, IsInt32Constant(new_mask));
+ EXPECT_THAT(r.replacement(), IsBranch(lhs, graph()->start()));
+ } else {
+ ASSERT_FALSE(r.Changed());
+ }
+ }
+ }
+}
// -----------------------------------------------------------------------------
// Int32Sub
diff --git a/deps/v8/test/unittests/compiler/node-cache-unittest.cc b/deps/v8/test/unittests/compiler/node-cache-unittest.cc
index 10118c3a41..777652db1b 100644
--- a/deps/v8/test/unittests/compiler/node-cache-unittest.cc
+++ b/deps/v8/test/unittests/compiler/node-cache-unittest.cc
@@ -17,13 +17,13 @@ namespace node_cache_unittest {
using NodeCacheTest = GraphTest;
TEST_F(NodeCacheTest, Int32Constant_back_to_back) {
- Int32NodeCache cache;
+ Int32NodeCache cache(zone());
for (int i = -2000000000; i < 2000000000; i += 3315177) {
- Node** pos = cache.Find(zone(), i);
+ Node** pos = cache.Find(i);
ASSERT_TRUE(pos != nullptr);
for (int j = 0; j < 3; j++) {
- Node** npos = cache.Find(zone(), i);
+ Node** npos = cache.Find(i);
EXPECT_EQ(pos, npos);
}
}
@@ -31,38 +31,38 @@ TEST_F(NodeCacheTest, Int32Constant_back_to_back) {
TEST_F(NodeCacheTest, Int32Constant_five) {
- Int32NodeCache cache;
+ Int32NodeCache cache(zone());
int32_t constants[] = {static_cast<int32_t>(0x80000000), -77, 0, 1, -1};
Node* nodes[arraysize(constants)];
for (size_t i = 0; i < arraysize(constants); i++) {
int32_t k = constants[i];
Node* node = graph()->NewNode(common()->Int32Constant(k));
- *cache.Find(zone(), k) = nodes[i] = node;
+ *cache.Find(k) = nodes[i] = node;
}
for (size_t i = 0; i < arraysize(constants); i++) {
int32_t k = constants[i];
- EXPECT_EQ(nodes[i], *cache.Find(zone(), k));
+ EXPECT_EQ(nodes[i], *cache.Find(k));
}
}
TEST_F(NodeCacheTest, Int32Constant_hits) {
- Int32NodeCache cache;
+ Int32NodeCache cache(zone());
const int32_t kSize = 1500;
Node** nodes = zone()->NewArray<Node*>(kSize);
for (int i = 0; i < kSize; i++) {
int32_t v = i * -55;
nodes[i] = graph()->NewNode(common()->Int32Constant(v));
- *cache.Find(zone(), v) = nodes[i];
+ *cache.Find(v) = nodes[i];
}
int hits = 0;
for (int i = 0; i < kSize; i++) {
int32_t v = i * -55;
- Node** pos = cache.Find(zone(), v);
+ Node** pos = cache.Find(v);
if (*pos != nullptr) {
EXPECT_EQ(nodes[i], *pos);
hits++;
@@ -73,13 +73,13 @@ TEST_F(NodeCacheTest, Int32Constant_hits) {
TEST_F(NodeCacheTest, Int64Constant_back_to_back) {
- Int64NodeCache cache;
+ Int64NodeCache cache(zone());
for (int64_t i = -2000000000; i < 2000000000; i += 3315177) {
- Node** pos = cache.Find(zone(), i);
+ Node** pos = cache.Find(i);
ASSERT_TRUE(pos != nullptr);
for (int j = 0; j < 3; j++) {
- Node** npos = cache.Find(zone(), i);
+ Node** npos = cache.Find(i);
EXPECT_EQ(pos, npos);
}
}
@@ -87,20 +87,20 @@ TEST_F(NodeCacheTest, Int64Constant_back_to_back) {
TEST_F(NodeCacheTest, Int64Constant_hits) {
- Int64NodeCache cache;
+ Int64NodeCache cache(zone());
const int32_t kSize = 1500;
Node** nodes = zone()->NewArray<Node*>(kSize);
for (int i = 0; i < kSize; i++) {
int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
nodes[i] = graph()->NewNode(common()->Int32Constant(i));
- *cache.Find(zone(), v) = nodes[i];
+ *cache.Find(v) = nodes[i];
}
int hits = 0;
for (int i = 0; i < kSize; i++) {
int64_t v = static_cast<int64_t>(i) * static_cast<int64_t>(5003001);
- Node** pos = cache.Find(zone(), v);
+ Node** pos = cache.Find(v);
if (*pos != nullptr) {
EXPECT_EQ(nodes[i], *pos);
hits++;
@@ -111,13 +111,13 @@ TEST_F(NodeCacheTest, Int64Constant_hits) {
TEST_F(NodeCacheTest, GetCachedNodes_int32) {
- Int32NodeCache cache;
+ Int32NodeCache cache(zone());
int32_t constants[] = {0, 311, 12, 13, 14, 555, -555, -44, -33, -22, -11,
0, 311, 311, 412, 412, 11, 11, -33, -33, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
int32_t k = constants[i];
- Node** pos = cache.Find(zone(), k);
+ Node** pos = cache.Find(k);
if (*pos != nullptr) {
ZoneVector<Node*> nodes(zone());
cache.GetCachedNodes(&nodes);
@@ -134,13 +134,13 @@ TEST_F(NodeCacheTest, GetCachedNodes_int32) {
TEST_F(NodeCacheTest, GetCachedNodes_int64) {
- Int64NodeCache cache;
+ Int64NodeCache cache(zone());
int64_t constants[] = {0, 311, 12, 13, 14, 555, -555, -44, -33, -22, -11,
0, 311, 311, 412, 412, 11, 11, -33, -33, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
int64_t k = constants[i];
- Node** pos = cache.Find(zone(), k);
+ Node** pos = cache.Find(k);
if (*pos != nullptr) {
ZoneVector<Node*> nodes(zone());
cache.GetCachedNodes(&nodes);
diff --git a/deps/v8/test/unittests/compiler/redundancy-elimination-unittest.cc b/deps/v8/test/unittests/compiler/redundancy-elimination-unittest.cc
index 62135dddce..9dda52ed8e 100644
--- a/deps/v8/test/unittests/compiler/redundancy-elimination-unittest.cc
+++ b/deps/v8/test/unittests/compiler/redundancy-elimination-unittest.cc
@@ -754,16 +754,18 @@ TEST_F(RedundancyEliminationTest, CheckedUint64Bounds) {
Node* effect = graph()->start();
Node* control = graph()->start();
- Node* check1 = effect =
- graph()->NewNode(simplified()->CheckedUint64Bounds(feedback1), index,
- length, effect, control);
+ Node* check1 = effect = graph()->NewNode(
+ simplified()->CheckedUint64Bounds(
+ feedback1, CheckBoundsParameters::kDeoptOnOutOfBounds),
+ index, length, effect, control);
Reduction r1 = Reduce(check1);
ASSERT_TRUE(r1.Changed());
EXPECT_EQ(r1.replacement(), check1);
- Node* check2 = effect =
- graph()->NewNode(simplified()->CheckedUint64Bounds(feedback2), index,
- length, effect, control);
+ Node* check2 = effect = graph()->NewNode(
+ simplified()->CheckedUint64Bounds(
+ feedback2, CheckBoundsParameters::kDeoptOnOutOfBounds),
+ index, length, effect, control);
Reduction r2 = Reduce(check2);
ASSERT_TRUE(r2.Changed());
EXPECT_EQ(r2.replacement(), check1);
diff --git a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
index e6ba7696c5..c24b2f2d97 100644
--- a/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
+++ b/deps/v8/test/unittests/compiler/state-values-utils-unittest.cc
@@ -153,11 +153,13 @@ TEST_F(StateValuesIteratorTest, TreeFromVectorWithLiveness) {
// Check the tree contents with vector.
int i = 0;
- for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) {
+ for (StateValuesAccess::iterator it =
+ StateValuesAccess(values_node).begin();
+ !it.done(); ++it) {
if (liveness.Contains(i)) {
- EXPECT_THAT(node.node, IsInt32Constant(i));
+ EXPECT_THAT(it.node(), IsInt32Constant(i));
} else {
- EXPECT_EQ(node.node, nullptr);
+ EXPECT_EQ(it.node(), nullptr);
}
i++;
}
diff --git a/deps/v8/test/unittests/compiler/typer-unittest.cc b/deps/v8/test/unittests/compiler/typer-unittest.cc
index bfb65e7c5f..8ecee3f8a1 100644
--- a/deps/v8/test/unittests/compiler/typer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/typer-unittest.cc
@@ -175,7 +175,7 @@ class TyperTest : public TypedGraphTest {
for (int x1 = lmin; x1 < lmin + width; x1++) {
for (int x2 = rmin; x2 < rmin + width; x2++) {
double result_value = opfun(x1, x2);
- Type result_type = Type::NewConstant(
+ Type result_type = Type::Constant(
&broker_, isolate()->factory()->NewNumber(result_value),
zone());
EXPECT_TRUE(result_type.Is(expected_type));
@@ -197,7 +197,7 @@ class TyperTest : public TypedGraphTest {
double x1 = RandomInt(r1.AsRange());
double x2 = RandomInt(r2.AsRange());
double result_value = opfun(x1, x2);
- Type result_type = Type::NewConstant(
+ Type result_type = Type::Constant(
&broker_, isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type.Is(expected_type));
}
@@ -205,13 +205,13 @@ class TyperTest : public TypedGraphTest {
// Test extreme cases.
double x1 = +1e-308;
double x2 = -1e-308;
- Type r1 = Type::NewConstant(&broker_, isolate()->factory()->NewNumber(x1),
- zone());
- Type r2 = Type::NewConstant(&broker_, isolate()->factory()->NewNumber(x2),
- zone());
+ Type r1 =
+ Type::Constant(&broker_, isolate()->factory()->NewNumber(x1), zone());
+ Type r2 =
+ Type::Constant(&broker_, isolate()->factory()->NewNumber(x2), zone());
Type expected_type = TypeBinaryOp(op, r1, r2);
double result_value = opfun(x1, x2);
- Type result_type = Type::NewConstant(
+ Type result_type = Type::Constant(
&broker_, isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type.Is(expected_type));
}
@@ -226,11 +226,11 @@ class TyperTest : public TypedGraphTest {
double x1 = RandomInt(r1.AsRange());
double x2 = RandomInt(r2.AsRange());
bool result_value = opfun(x1, x2);
- Type result_type = Type::NewConstant(
- &broker_,
- result_value ? isolate()->factory()->true_value()
- : isolate()->factory()->false_value(),
- zone());
+ Type result_type =
+ Type::Constant(&broker_,
+ result_value ? isolate()->factory()->true_value()
+ : isolate()->factory()->false_value(),
+ zone());
EXPECT_TRUE(result_type.Is(expected_type));
}
}
@@ -246,7 +246,7 @@ class TyperTest : public TypedGraphTest {
int32_t x1 = static_cast<int32_t>(RandomInt(r1.AsRange()));
int32_t x2 = static_cast<int32_t>(RandomInt(r2.AsRange()));
double result_value = opfun(x1, x2);
- Type result_type = Type::NewConstant(
+ Type result_type = Type::Constant(
&broker_, isolate()->factory()->NewNumber(result_value), zone());
EXPECT_TRUE(result_type.Is(expected_type));
}
@@ -585,6 +585,96 @@ SIMPLIFIED_NUMBER_BINOP_LIST(TEST_MONOTONICITY)
SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(TEST_MONOTONICITY)
#undef TEST_MONOTONICITY
+TEST_F(TyperTest, Manual_Operation_NumberMax) {
+ BinaryTyper t = [&](Type type1, Type type2) {
+ return operation_typer_.NumberMax(type1, type2);
+ };
+
+ Type zero = Type::Constant(0, zone());
+ Type zero_or_minuszero = Type::Union(zero, Type::MinusZero(), zone());
+ Type dot_five = Type::Constant(0.5, zone());
+
+ Type a = t(Type::MinusZero(), Type::MinusZero());
+ CHECK(Type::MinusZero().Is(a));
+
+ Type b = t(Type::MinusZero(), zero_or_minuszero);
+ CHECK(Type::MinusZero().Is(b));
+ CHECK(zero.Is(b));
+ CHECK(a.Is(b));
+
+ Type c = t(zero_or_minuszero, Type::MinusZero());
+ CHECK(Type::MinusZero().Is(c));
+ CHECK(zero.Is(c));
+ CHECK(a.Is(c));
+
+ Type d = t(zero_or_minuszero, zero_or_minuszero);
+ CHECK(Type::MinusZero().Is(d));
+ CHECK(zero.Is(d));
+ CHECK(b.Is(d));
+ CHECK(c.Is(d));
+
+ Type e =
+ t(Type::MinusZero(), Type::Union(Type::MinusZero(), dot_five, zone()));
+ CHECK(Type::MinusZero().Is(e));
+ CHECK(dot_five.Is(e));
+ CHECK(a.Is(e));
+
+ Type f = t(Type::MinusZero(), zero);
+ CHECK(zero.Is(f));
+ CHECK(f.Is(b));
+
+ Type g = t(zero, Type::MinusZero());
+ CHECK(zero.Is(g));
+ CHECK(g.Is(c));
+}
+
+TEST_F(TyperTest, Manual_Operation_NumberMin) {
+ BinaryTyper t = [&](Type type1, Type type2) {
+ return operation_typer_.NumberMin(type1, type2);
+ };
+
+ Type zero = Type::Constant(0, zone());
+ Type zero_or_minuszero = Type::Union(zero, Type::MinusZero(), zone());
+ Type one = Type::Constant(1, zone());
+ Type minus_dot_five = Type::Constant(-0.5, zone());
+
+ Type a = t(Type::MinusZero(), Type::MinusZero());
+ CHECK(Type::MinusZero().Is(a));
+
+ Type b = t(Type::MinusZero(), zero_or_minuszero);
+ CHECK(Type::MinusZero().Is(b));
+ CHECK(zero.Is(b));
+ CHECK(a.Is(b));
+
+ Type c = t(zero_or_minuszero, Type::MinusZero());
+ CHECK(Type::MinusZero().Is(c));
+ CHECK(zero.Is(c));
+ CHECK(a.Is(c));
+
+ Type d = t(zero_or_minuszero, zero_or_minuszero);
+ CHECK(Type::MinusZero().Is(d));
+ CHECK(zero.Is(d));
+ CHECK(b.Is(d));
+ CHECK(c.Is(d));
+
+ Type e = t(Type::MinusZero(),
+ Type::Union(Type::MinusZero(), minus_dot_five, zone()));
+ CHECK(Type::MinusZero().Is(e));
+ CHECK(minus_dot_five.Is(e));
+ CHECK(a.Is(e));
+
+ Type f = t(Type::MinusZero(), zero);
+ CHECK(Type::MinusZero().Is(f));
+ CHECK(f.Is(b));
+
+ Type g = t(zero, Type::MinusZero());
+ CHECK(Type::MinusZero().Is(g));
+ CHECK(g.Is(c));
+
+ Type h = t(one, Type::MinusZero());
+ CHECK(Type::MinusZero().Is(h));
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
index 6cb9df0895..3b59b7cf35 100644
--- a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
+++ b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
@@ -30,10 +30,10 @@ void RunStdFunction(void* data) {
}
template <typename TMixin>
-class WithFinalizationGroupMixin : public TMixin {
+class WithFinalizationRegistryMixin : public TMixin {
public:
- WithFinalizationGroupMixin() = default;
- ~WithFinalizationGroupMixin() override = default;
+ WithFinalizationRegistryMixin() = default;
+ ~WithFinalizationRegistryMixin() override = default;
static void SetUpTestCase() {
CHECK_NULL(save_flags_);
@@ -54,21 +54,29 @@ class WithFinalizationGroupMixin : public TMixin {
private:
static SaveFlags* save_flags_;
- DISALLOW_COPY_AND_ASSIGN(WithFinalizationGroupMixin);
+ DISALLOW_COPY_AND_ASSIGN(WithFinalizationRegistryMixin);
};
template <typename TMixin>
-SaveFlags* WithFinalizationGroupMixin<TMixin>::save_flags_ = nullptr;
-
-using TestWithNativeContextAndFinalizationGroup = //
- WithInternalIsolateMixin< //
- WithContextMixin< //
- WithFinalizationGroupMixin< //
- WithIsolateScopeMixin< //
- WithSharedIsolateMixin< //
+SaveFlags* WithFinalizationRegistryMixin<TMixin>::save_flags_ = nullptr;
+
+using TestWithNativeContextAndFinalizationRegistry = //
+ WithInternalIsolateMixin< //
+ WithContextMixin< //
+ WithFinalizationRegistryMixin< //
+ WithIsolateScopeMixin< //
+ WithSharedIsolateMixin< //
::testing::Test>>>>>;
-class MicrotaskQueueTest : public TestWithNativeContextAndFinalizationGroup {
+namespace {
+
+void DummyPromiseHook(PromiseHookType type, Local<Promise> promise,
+ Local<Value> parent) {}
+
+} // namespace
+
+class MicrotaskQueueTest : public TestWithNativeContextAndFinalizationRegistry,
+ public ::testing::WithParamInterface<bool> {
public:
template <typename F>
Handle<Microtask> NewMicrotask(F&& f) {
@@ -82,6 +90,12 @@ class MicrotaskQueueTest : public TestWithNativeContextAndFinalizationGroup {
void SetUp() override {
microtask_queue_ = MicrotaskQueue::New(isolate());
native_context()->set_microtask_queue(microtask_queue());
+
+ if (GetParam()) {
+ // Use a PromiseHook to switch the implementation to ResolvePromise
+ // runtime, instead of ResolvePromise builtin.
+ v8_isolate()->SetPromiseHook(&DummyPromiseHook);
+ }
}
void TearDown() override {
@@ -126,7 +140,7 @@ class RecordingVisitor : public RootVisitor {
};
// Sanity check. Ensure a microtask is stored in a queue and run.
-TEST_F(MicrotaskQueueTest, EnqueueAndRun) {
+TEST_P(MicrotaskQueueTest, EnqueueAndRun) {
bool ran = false;
EXPECT_EQ(0, microtask_queue()->capacity());
EXPECT_EQ(0, microtask_queue()->size());
@@ -142,7 +156,7 @@ TEST_F(MicrotaskQueueTest, EnqueueAndRun) {
}
// Check for a buffer growth.
-TEST_F(MicrotaskQueueTest, BufferGrowth) {
+TEST_P(MicrotaskQueueTest, BufferGrowth) {
int count = 0;
// Enqueue and flush the queue first to have non-zero |start_|.
@@ -176,7 +190,7 @@ TEST_F(MicrotaskQueueTest, BufferGrowth) {
}
// MicrotaskQueue instances form a doubly linked list.
-TEST_F(MicrotaskQueueTest, InstanceChain) {
+TEST_P(MicrotaskQueueTest, InstanceChain) {
ClearTestMicrotaskQueue();
MicrotaskQueue* default_mtq = isolate()->default_microtask_queue();
@@ -207,7 +221,7 @@ TEST_F(MicrotaskQueueTest, InstanceChain) {
// Pending Microtasks in MicrotaskQueues are strong roots. Ensure they are
// visited exactly once.
-TEST_F(MicrotaskQueueTest, VisitRoot) {
+TEST_P(MicrotaskQueueTest, VisitRoot) {
// Ensure that the ring buffer has separate in-use region.
for (int i = 0; i < MicrotaskQueue::kMinimumCapacity / 2 + 1; ++i) {
microtask_queue()->EnqueueMicrotask(*NewMicrotask([] {}));
@@ -233,7 +247,7 @@ TEST_F(MicrotaskQueueTest, VisitRoot) {
EXPECT_EQ(expected, actual);
}
-TEST_F(MicrotaskQueueTest, PromiseHandlerContext) {
+TEST_P(MicrotaskQueueTest, PromiseHandlerContext) {
Local<v8::Context> v8_context2 = v8::Context::New(v8_isolate());
Local<v8::Context> v8_context3 = v8::Context::New(v8_isolate());
Local<v8::Context> v8_context4 = v8::Context::New(v8_isolate());
@@ -327,7 +341,7 @@ TEST_F(MicrotaskQueueTest, PromiseHandlerContext) {
v8_context2->DetachGlobal();
}
-TEST_F(MicrotaskQueueTest, DetachGlobal_Enqueue) {
+TEST_P(MicrotaskQueueTest, DetachGlobal_Enqueue) {
EXPECT_EQ(0, microtask_queue()->size());
// Detach MicrotaskQueue from the current context.
@@ -339,7 +353,7 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_Enqueue) {
EXPECT_EQ(0, microtask_queue()->size());
}
-TEST_F(MicrotaskQueueTest, DetachGlobal_Run) {
+TEST_P(MicrotaskQueueTest, DetachGlobal_Run) {
EXPECT_EQ(0, microtask_queue()->size());
// Enqueue microtasks to the current context.
@@ -377,18 +391,7 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_Run) {
}
}
-namespace {
-
-void DummyPromiseHook(PromiseHookType type, Local<Promise> promise,
- Local<Value> parent) {}
-
-} // namespace
-
-TEST_F(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
- // Use a PromiseHook to switch the implementation to ResolvePromise runtime,
- // instead of ResolvePromise builtin.
- v8_isolate()->SetPromiseHook(&DummyPromiseHook);
-
+TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
RunJS(
"var resolve;"
"var promise = new Promise(r => { resolve = r; });"
@@ -410,7 +413,71 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
EXPECT_EQ(0, microtask_queue()->size());
}
-TEST_F(MicrotaskQueueTest, DetachGlobal_HandlerContext) {
+TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
+ Handle<JSArray> result = RunJS<JSArray>(
+ "let result = [false];"
+ "result");
+ Handle<JSFunction> then = RunJS<JSFunction>("() => { result[0] = true; }");
+
+ Handle<JSPromise> stale_promise;
+
+ {
+ // Create a context with its own microtask queue.
+ std::unique_ptr<MicrotaskQueue> sub_microtask_queue =
+ MicrotaskQueue::New(isolate());
+ Local<v8::Context> sub_context = v8::Context::New(
+ v8_isolate(),
+ /* extensions= */ nullptr,
+ /* global_template= */ MaybeLocal<ObjectTemplate>(),
+ /* global_object= */ MaybeLocal<Value>(),
+ /* internal_fields_deserializer= */ DeserializeInternalFieldsCallback(),
+ sub_microtask_queue.get());
+
+ {
+ v8::Context::Scope scope(sub_context);
+ CHECK(sub_context->Global()
+ ->Set(sub_context, NewString("then"),
+ Utils::ToLocal(Handle<JSReceiver>::cast(then)))
+ .FromJust());
+
+ ASSERT_EQ(0, microtask_queue()->size());
+ ASSERT_EQ(0, sub_microtask_queue->size());
+ ASSERT_TRUE(Object::GetElement(isolate(), result, 0)
+ .ToHandleChecked()
+ ->IsFalse());
+
+ // With a regular thenable, a microtask is queued on the sub-context.
+ RunJS<JSPromise>("Promise.resolve({ then: cb => cb(1) })");
+ EXPECT_EQ(0, microtask_queue()->size());
+ EXPECT_EQ(1, sub_microtask_queue->size());
+ EXPECT_TRUE(Object::GetElement(isolate(), result, 0)
+ .ToHandleChecked()
+ ->IsFalse());
+
+ // But when the `then` method comes from another context, a microtask is
+ // instead queued on the main context.
+ stale_promise = RunJS<JSPromise>("Promise.resolve({ then })");
+ EXPECT_EQ(1, microtask_queue()->size());
+ EXPECT_EQ(1, sub_microtask_queue->size());
+ EXPECT_TRUE(Object::GetElement(isolate(), result, 0)
+ .ToHandleChecked()
+ ->IsFalse());
+ }
+
+ sub_context->DetachGlobal();
+ }
+
+ EXPECT_EQ(1, microtask_queue()->size());
+ EXPECT_TRUE(
+ Object::GetElement(isolate(), result, 0).ToHandleChecked()->IsFalse());
+
+ EXPECT_EQ(1, microtask_queue()->RunMicrotasks(isolate()));
+ EXPECT_EQ(0, microtask_queue()->size());
+ EXPECT_TRUE(
+ Object::GetElement(isolate(), result, 0).ToHandleChecked()->IsTrue());
+}
+
+TEST_P(MicrotaskQueueTest, DetachGlobal_HandlerContext) {
// EnqueueMicrotask should use the context associated to the handler instead
// of the current context. E.g.
// // At Context A.
@@ -489,7 +556,7 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_HandlerContext) {
.FromJust());
}
-TEST_F(MicrotaskQueueTest, DetachGlobal_Chain) {
+TEST_P(MicrotaskQueueTest, DetachGlobal_Chain) {
Handle<JSPromise> stale_rejected_promise;
Local<v8::Context> sub_context = v8::Context::New(v8_isolate());
@@ -516,7 +583,7 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_Chain) {
Object::GetElement(isolate(), result, 0).ToHandleChecked()->IsTrue());
}
-TEST_F(MicrotaskQueueTest, DetachGlobal_InactiveHandler) {
+TEST_P(MicrotaskQueueTest, DetachGlobal_InactiveHandler) {
Local<v8::Context> sub_context = v8::Context::New(v8_isolate());
Utils::OpenHandle(*sub_context)
->native_context()
@@ -558,7 +625,7 @@ TEST_F(MicrotaskQueueTest, DetachGlobal_InactiveHandler) {
Object::GetElement(isolate(), result, 1).ToHandleChecked()->IsFalse());
}
-TEST_F(MicrotaskQueueTest, MicrotasksScope) {
+TEST_P(MicrotaskQueueTest, MicrotasksScope) {
ASSERT_NE(isolate()->default_microtask_queue(), microtask_queue());
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kScoped);
@@ -574,5 +641,11 @@ TEST_F(MicrotaskQueueTest, MicrotasksScope) {
EXPECT_TRUE(ran);
}
+INSTANTIATE_TEST_SUITE_P(
+ , MicrotaskQueueTest, ::testing::Values(false, true),
+ [](const ::testing::TestParamInfo<MicrotaskQueueTest::ParamType>& info) {
+ return info.param ? "runtime" : "builtin";
+ });
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/cppgc/allocation_unittest.cc b/deps/v8/test/unittests/heap/cppgc/allocation_unittest.cc
new file mode 100644
index 0000000000..3a02ae1721
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/allocation_unittest.cc
@@ -0,0 +1,42 @@
+// Copyright 2020 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 "include/cppgc/allocation.h"
+
+#include <memory>
+
+#include "src/heap/cppgc/heap.h"
+#include "test/unittests/heap/cppgc/tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+
+TEST(GCBasicHeapTest, CreateAndDestroyHeap) {
+ std::unique_ptr<Heap> heap{Heap::Create()};
+}
+
+namespace {
+
+class Foo : public GarbageCollected<Foo> {
+ public:
+ static size_t destructor_callcount;
+
+ Foo() { destructor_callcount = 0; }
+ ~Foo() { destructor_callcount++; }
+};
+
+size_t Foo::destructor_callcount;
+
+class GCAllocationTest : public testing::TestWithHeap {};
+
+} // namespace
+
+TEST_F(GCAllocationTest, MakeGarbageCollectedAndReclaim) {
+ MakeGarbageCollected<Foo>(GetHeap());
+ EXPECT_EQ(0u, Foo::destructor_callcount);
+ internal::Heap::From(GetHeap())->CollectGarbage();
+ EXPECT_EQ(1u, Foo::destructor_callcount);
+}
+
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/finalizer-trait_unittest.cc b/deps/v8/test/unittests/heap/cppgc/finalizer-trait_unittest.cc
new file mode 100644
index 0000000000..91a255e727
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/finalizer-trait_unittest.cc
@@ -0,0 +1,118 @@
+// Copyright 2020 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 "include/cppgc/finalizer-trait.h"
+#include <type_traits>
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace internal {
+
+namespace {
+
+// Trivially destructible types.
+class TypeWithoutDestructor final {};
+class TypeWithPrimitive final {
+ public:
+ int foo = 0;
+};
+
+class InvokeCounter {
+ public:
+ static size_t kCallcount;
+ static void Reset() { kCallcount = 0; }
+ static void Invoke() { kCallcount++; }
+};
+
+size_t InvokeCounter::kCallcount = 0;
+
+// Regular C++ use cases.
+
+class TypeWithDestructor final : public InvokeCounter {
+ public:
+ ~TypeWithDestructor() { Invoke(); }
+};
+
+class TypeWithVirtualDestructorBase {
+ public:
+ virtual ~TypeWithVirtualDestructorBase() = default;
+};
+
+class TypeWithVirtualDestructorChild final
+ : public TypeWithVirtualDestructorBase,
+ public InvokeCounter {
+ public:
+ ~TypeWithVirtualDestructorChild() final { Invoke(); }
+};
+
+// Manual dispatch to avoid vtables.
+
+class TypeWithCustomFinalizationMethod final : public InvokeCounter {
+ public:
+ void FinalizeGarbageCollectedObject() { Invoke(); }
+};
+
+class TypeWithCustomFinalizationMethodAtBase {
+ public:
+ void FinalizeGarbageCollectedObject();
+};
+
+class TypeWithCustomFinalizationMethodAtBaseChild
+ : public TypeWithCustomFinalizationMethodAtBase,
+ public InvokeCounter {
+ public:
+ ~TypeWithCustomFinalizationMethodAtBaseChild() { Invoke(); }
+};
+
+void TypeWithCustomFinalizationMethodAtBase::FinalizeGarbageCollectedObject() {
+ // The test knows that base is only inherited by a single child. In practice
+ // users can maintain a map of valid types in already existing storage.
+ static_cast<TypeWithCustomFinalizationMethodAtBaseChild*>(this)
+ ->~TypeWithCustomFinalizationMethodAtBaseChild();
+}
+
+template <typename Type>
+void ExpectFinalizerIsInvoked(Type* object) {
+ InvokeCounter::Reset();
+ EXPECT_NE(nullptr, FinalizerTrait<Type>::kCallback);
+ FinalizerTrait<Type>::kCallback(object);
+ EXPECT_EQ(1u, InvokeCounter::kCallcount);
+ operator delete(object);
+}
+
+} // namespace
+
+TEST(FinalizerTrait, TypeWithoutDestructorHasNoFinalizer) {
+ static_assert(std::is_trivially_destructible<TypeWithoutDestructor>::value,
+ "trivially destructible");
+ EXPECT_EQ(nullptr, FinalizerTrait<TypeWithoutDestructor>::kCallback);
+}
+
+TEST(FinalizerTrait, TypeWithPrimitiveHasNoFinalizer) {
+ static_assert(std::is_trivially_destructible<TypeWithPrimitive>::value,
+ "trivially destructible");
+ EXPECT_EQ(nullptr, FinalizerTrait<TypeWithPrimitive>::kCallback);
+}
+
+TEST(FinalizerTrait, FinalizerForTypeWithDestructor) {
+ ExpectFinalizerIsInvoked(new TypeWithDestructor());
+}
+
+TEST(FinalizerTrait, FinalizerForTypeWithVirtualBaseDtor) {
+ TypeWithVirtualDestructorBase* base = new TypeWithVirtualDestructorChild();
+ ExpectFinalizerIsInvoked(base);
+}
+
+TEST(FinalizerTrait, FinalizerForCustomFinalizationMethod) {
+ ExpectFinalizerIsInvoked(new TypeWithCustomFinalizationMethod());
+}
+
+TEST(FinalizerTrait, FinalizerForCustomFinalizationMethodInBase) {
+ TypeWithCustomFinalizationMethodAtBase* base =
+ new TypeWithCustomFinalizationMethodAtBaseChild();
+ ExpectFinalizerIsInvoked(base);
+}
+
+} // namespace internal
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/garbage-collected_unittest.cc b/deps/v8/test/unittests/heap/cppgc/garbage-collected_unittest.cc
new file mode 100644
index 0000000000..5098bdf48e
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/garbage-collected_unittest.cc
@@ -0,0 +1,26 @@
+// Copyright 2020 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 "include/cppgc/garbage-collected.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace internal {
+
+namespace {
+
+class GCed : public GarbageCollected<GCed> {};
+class NotGCed {};
+
+} // namespace
+
+TEST(GarbageCollectedTest, GarbageCollectedTrait) {
+ EXPECT_FALSE(IsGarbageCollectedType<int>::value);
+ EXPECT_FALSE(IsGarbageCollectedType<NotGCed>::value);
+ EXPECT_TRUE(IsGarbageCollectedType<GCed>::value);
+}
+
+} // namespace internal
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/gc-info_unittest.cc b/deps/v8/test/unittests/heap/cppgc/gc-info_unittest.cc
new file mode 100644
index 0000000000..e7bfb5a7fe
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/gc-info_unittest.cc
@@ -0,0 +1,153 @@
+// Copyright 2020 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 "include/cppgc/gc-info.h"
+
+#include "include/cppgc/platform.h"
+#include "src/base/page-allocator.h"
+#include "src/base/platform/platform.h"
+#include "src/heap/cppgc/gc-info-table.h"
+#include "test/unittests/heap/cppgc/tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace internal {
+
+TEST(GCInfoTableTest, InitialEmpty) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ EXPECT_EQ(GCInfoTable::kMinIndex, table.NumberOfGCInfosForTesting());
+}
+
+TEST(GCInfoTableTest, ResizeToMaxIndex) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
+ i++) {
+ GCInfoIndex index = table.RegisterNewGCInfo(info);
+ EXPECT_EQ(i, index);
+ }
+}
+
+TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ // Create GCInfoTable::kMaxIndex entries.
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
+ i++) {
+ table.RegisterNewGCInfo(info);
+ }
+ EXPECT_DEATH_IF_SUPPORTED(table.RegisterNewGCInfo(info), "");
+}
+
+TEST(GCInfoTableDeathTest, OldTableAreaIsReadOnly) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ // Use up all slots until limit.
+ GCInfoIndex limit = table.LimitForTesting();
+ // Bail out if initial limit is already the maximum because of large committed
+ // pages. In this case, nothing can be comitted as read-only.
+ if (limit == GCInfoTable::kMaxIndex) {
+ return;
+ }
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < limit; i++) {
+ table.RegisterNewGCInfo(info);
+ }
+ EXPECT_EQ(limit, table.LimitForTesting());
+ table.RegisterNewGCInfo(info);
+ EXPECT_NE(limit, table.LimitForTesting());
+ // Old area is now read-only.
+ auto& first_slot = table.TableSlotForTesting(GCInfoTable::kMinIndex);
+ EXPECT_DEATH_IF_SUPPORTED(first_slot.finalize = nullptr, "");
+}
+
+namespace {
+
+class ThreadRegisteringGCInfoObjects final : public v8::base::Thread {
+ public:
+ ThreadRegisteringGCInfoObjects(GCInfoTable* table,
+ GCInfoIndex num_registrations)
+ : v8::base::Thread(Options("Thread registering GCInfo objects.")),
+ table_(table),
+ num_registrations_(num_registrations) {}
+
+ void Run() final {
+ GCInfo info = {nullptr, false};
+ for (GCInfoIndex i = 0; i < num_registrations_; i++) {
+ table_->RegisterNewGCInfo(info);
+ }
+ }
+
+ private:
+ GCInfoTable* table_;
+ GCInfoIndex num_registrations_;
+};
+
+} // namespace
+
+TEST(GCInfoTableTest, MultiThreadedResizeToMaxIndex) {
+ constexpr size_t num_threads = 4;
+ constexpr size_t main_thread_initialized = 2;
+ constexpr size_t gc_infos_to_register =
+ (GCInfoTable::kMaxIndex - 1) -
+ (GCInfoTable::kMinIndex + main_thread_initialized);
+ static_assert(gc_infos_to_register % num_threads == 0,
+ "must sum up to kMaxIndex");
+ constexpr size_t gc_infos_per_thread = gc_infos_to_register / num_threads;
+
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ for (size_t i = 0; i < main_thread_initialized; i++) {
+ table.RegisterNewGCInfo(info);
+ }
+
+ v8::base::Thread* threads[num_threads];
+ for (size_t i = 0; i < num_threads; i++) {
+ threads[i] =
+ new ThreadRegisteringGCInfoObjects(&table, gc_infos_per_thread);
+ }
+ for (size_t i = 0; i < num_threads; i++) {
+ CHECK(threads[i]->Start());
+ }
+ for (size_t i = 0; i < num_threads; i++) {
+ threads[i]->Join();
+ delete threads[i];
+ }
+}
+
+// Tests using the global table and GCInfoTrait.
+
+namespace {
+
+class GCInfoTraitTest : public testing::TestWithPlatform {};
+
+class BasicType final {};
+class OtherBasicType final {};
+
+} // namespace
+
+TEST_F(GCInfoTraitTest, IndexInBounds) {
+ const GCInfoIndex index = GCInfoTrait<BasicType>::Index();
+ EXPECT_GT(GCInfoTable::kMaxIndex, index);
+ EXPECT_LE(GCInfoTable::kMinIndex, index);
+}
+
+TEST_F(GCInfoTraitTest, TraitReturnsSameIndexForSameType) {
+ const GCInfoIndex index1 = GCInfoTrait<BasicType>::Index();
+ const GCInfoIndex index2 = GCInfoTrait<BasicType>::Index();
+ EXPECT_EQ(index1, index2);
+}
+
+TEST_F(GCInfoTraitTest, TraitReturnsDifferentIndexForDifferentTypes) {
+ const GCInfoIndex index1 = GCInfoTrait<BasicType>::Index();
+ const GCInfoIndex index2 = GCInfoTrait<OtherBasicType>::Index();
+ EXPECT_NE(index1, index2);
+}
+
+} // namespace internal
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/heap-object-header_unittest.cc b/deps/v8/test/unittests/heap/cppgc/heap-object-header_unittest.cc
new file mode 100644
index 0000000000..b062489cb3
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/heap-object-header_unittest.cc
@@ -0,0 +1,181 @@
+// Copyright 2020 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/heap/cppgc/heap-object-header.h"
+
+#include <atomic>
+#include <memory>
+
+#include "include/cppgc/allocation.h"
+#include "src/base/atomic-utils.h"
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+#include "src/heap/cppgc/globals.h"
+#include "src/heap/cppgc/heap-object-header-inl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace internal {
+
+TEST(HeapObjectHeaderTest, Constructor) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_EQ(kSize, header.GetSize());
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_TRUE(header.IsInConstruction());
+ EXPECT_FALSE(header.IsMarked());
+}
+
+TEST(HeapObjectHeaderTest, Payload) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_EQ(reinterpret_cast<ConstAddress>(&header) + sizeof(HeapObjectHeader),
+ header.Payload());
+}
+
+TEST(HeapObjectHeaderTest, GetGCInfoIndex) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_EQ(kGCInfoIndex,
+ header.GetGCInfoIndex<HeapObjectHeader::AccessMode::kAtomic>());
+}
+
+TEST(HeapObjectHeaderTest, GetSize) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity * 23;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_EQ(kSize, header.GetSize());
+ EXPECT_EQ(kSize, header.GetSize<HeapObjectHeader::AccessMode::kAtomic>());
+}
+
+TEST(HeapObjectHeaderTest, IsLargeObject) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity * 23;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_EQ(false, header.IsLargeObject());
+ EXPECT_EQ(false,
+ header.IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>());
+ HeapObjectHeader large_header(0, kGCInfoIndex + 1);
+ EXPECT_EQ(true, large_header.IsLargeObject());
+ EXPECT_EQ(
+ true,
+ large_header.IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>());
+}
+
+TEST(HeapObjectHeaderTest, MarkObjectAsFullyConstructed) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_TRUE(header.IsInConstruction());
+ header.MarkAsFullyConstructed();
+ EXPECT_FALSE(header.IsInConstruction());
+ // Size shares the same bitfield and should be unaffected by
+ // MarkObjectAsFullyConstructed.
+ EXPECT_EQ(kSize, header.GetSize());
+}
+
+TEST(HeapObjectHeaderTest, TryMark) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity * 7;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_FALSE(header.IsMarked());
+ EXPECT_TRUE(header.TryMarkAtomic());
+ // GCInfoIndex shares the same bitfield and should be unaffected by
+ // TryMarkAtomic.
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_FALSE(header.TryMarkAtomic());
+ // GCInfoIndex shares the same bitfield and should be unaffected by
+ // TryMarkAtomic.
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_TRUE(header.IsMarked());
+}
+
+TEST(HeapObjectHeaderTest, Unmark) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = kAllocationGranularity * 7;
+ HeapObjectHeader header(kSize, kGCInfoIndex);
+ EXPECT_FALSE(header.IsMarked());
+ EXPECT_TRUE(header.TryMarkAtomic());
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_TRUE(header.IsMarked());
+ header.Unmark();
+ // GCInfoIndex shares the same bitfield and should be unaffected by Unmark.
+ EXPECT_EQ(kGCInfoIndex, header.GetGCInfoIndex());
+ EXPECT_FALSE(header.IsMarked());
+ HeapObjectHeader header2(kSize, kGCInfoIndex);
+ EXPECT_FALSE(header2.IsMarked());
+ EXPECT_TRUE(header2.TryMarkAtomic());
+ EXPECT_TRUE(header2.IsMarked());
+ header2.Unmark<HeapObjectHeader::AccessMode::kAtomic>();
+ // GCInfoIndex shares the same bitfield and should be unaffected by Unmark.
+ EXPECT_EQ(kGCInfoIndex, header2.GetGCInfoIndex());
+ EXPECT_FALSE(header2.IsMarked());
+}
+
+namespace {
+
+struct Payload {
+ volatile size_t value{5};
+};
+
+class ConcurrentGCThread final : public v8::base::Thread {
+ public:
+ explicit ConcurrentGCThread(HeapObjectHeader* header, Payload* payload)
+ : v8::base::Thread(Options("Thread accessing object.")),
+ header_(header),
+ payload_(payload) {}
+
+ void Run() final {
+ while (header_->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
+ }
+ USE(v8::base::AsAtomicPtr(const_cast<size_t*>(&payload_->value))
+ ->load(std::memory_order_relaxed));
+ }
+
+ private:
+ HeapObjectHeader* header_;
+ Payload* payload_;
+};
+
+} // namespace
+
+TEST(HeapObjectHeaderTest, ConstructionBitProtectsNonAtomicWrites) {
+ // Object publishing: Test checks that non-atomic stores in the payload can be
+ // guarded using MarkObjectAsFullyConstructed/IsInConstruction. The test
+ // relies on TSAN to find data races.
+ constexpr size_t kSize =
+ (sizeof(HeapObjectHeader) + sizeof(Payload) + kAllocationMask) &
+ ~kAllocationMask;
+ typename std::aligned_storage<kSize, kAllocationGranularity>::type data;
+ HeapObjectHeader* header = new (&data) HeapObjectHeader(kSize, 1);
+ ConcurrentGCThread gc_thread(header,
+ reinterpret_cast<Payload*>(header->Payload()));
+ CHECK(gc_thread.Start());
+ new (header->Payload()) Payload();
+ header->MarkAsFullyConstructed();
+ gc_thread.Join();
+}
+
+#ifdef DEBUG
+
+TEST(HeapObjectHeaderDeathTest, ConstructorTooLargeSize) {
+ constexpr GCInfoIndex kGCInfoIndex = 17;
+ constexpr size_t kSize = HeapObjectHeader::kMaxSize + 1;
+ EXPECT_DEATH_IF_SUPPORTED(HeapObjectHeader header(kSize, kGCInfoIndex), "");
+}
+
+TEST(HeapObjectHeaderDeathTest, ConstructorTooLargeGCInfoIndex) {
+ constexpr GCInfoIndex kGCInfoIndex = GCInfoTable::kMaxIndex + 1;
+ constexpr size_t kSize = kAllocationGranularity;
+ EXPECT_DEATH_IF_SUPPORTED(HeapObjectHeader header(kSize, kGCInfoIndex), "");
+}
+
+#endif // DEBUG
+
+} // namespace internal
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/run-all-unittests.cc b/deps/v8/test/unittests/heap/cppgc/run-all-unittests.cc
new file mode 100644
index 0000000000..cdc862e309
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/run-all-unittests.cc
@@ -0,0 +1,17 @@
+// Copyright 2020 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 "testing/gmock/include/gmock/gmock.h"
+
+int main(int argc, char** argv) {
+ // Don't catch SEH exceptions and continue as the following tests might hang
+ // in an broken environment on windows.
+ testing::GTEST_FLAG(catch_exceptions) = false;
+
+ // Most unit-tests are multi-threaded, so enable thread-safe death-tests.
+ testing::FLAGS_gtest_death_test_style = "threadsafe";
+
+ testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/deps/v8/test/unittests/heap/cppgc/stack_unittest.cc b/deps/v8/test/unittests/heap/cppgc/stack_unittest.cc
new file mode 100644
index 0000000000..435c06f83f
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/stack_unittest.cc
@@ -0,0 +1,256 @@
+// Copyright 2020 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/heap/cppgc/stack.h"
+
+#include <memory>
+#include <ostream>
+
+#include "include/v8config.h"
+#include "src/base/platform/platform.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if V8_OS_LINUX && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
+#include <xmmintrin.h>
+#endif
+
+namespace cppgc {
+namespace internal {
+
+namespace {
+
+class GCStackTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ stack_.reset(new Stack(v8::base::Stack::GetStackStart()));
+ }
+
+ void TearDown() override { stack_.reset(); }
+
+ Stack* GetStack() const { return stack_.get(); }
+
+ private:
+ std::unique_ptr<Stack> stack_;
+};
+
+} // namespace
+
+TEST_F(GCStackTest, IsOnStackForStackValue) {
+ void* dummy;
+ EXPECT_TRUE(GetStack()->IsOnStack(&dummy));
+}
+
+TEST_F(GCStackTest, IsOnStackForHeapValue) {
+ auto dummy = std::make_unique<int>();
+ EXPECT_FALSE(GetStack()->IsOnStack(dummy.get()));
+}
+
+#ifdef CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
+
+namespace {
+
+class StackScanner final : public StackVisitor {
+ public:
+ struct Container {
+ std::unique_ptr<int> value;
+ };
+
+ StackScanner() : container_(new Container{}) {
+ container_->value = std::make_unique<int>();
+ }
+
+ void VisitPointer(const void* address) final {
+ if (address == container_->value.get()) found_ = true;
+ }
+
+ void Reset() { found_ = false; }
+ bool found() const { return found_; }
+ int* needle() const { return container_->value.get(); }
+
+ private:
+ std::unique_ptr<Container> container_;
+ bool found_ = false;
+};
+
+} // namespace
+
+TEST_F(GCStackTest, IteratePointersFindsOnStackValue) {
+ auto scanner = std::make_unique<StackScanner>();
+
+ // No check that the needle is initially not found as on some platforms it
+ // may be part of the redzone or temporaries after setting it up throuhg
+ // StackScanner.
+ {
+ int* volatile tmp = scanner->needle();
+ USE(tmp);
+ GetStack()->IteratePointers(scanner.get());
+ EXPECT_TRUE(scanner->found());
+ }
+}
+
+TEST_F(GCStackTest, IteratePointersFindsOnStackValuePotentiallyUnaligned) {
+ auto scanner = std::make_unique<StackScanner>();
+
+ // No check that the needle is initially not found as on some platforms it
+ // may be part of the redzone or temporaries after setting it up throuhg
+ // StackScanner.
+ {
+ char a = 'c';
+ USE(a);
+ int* volatile tmp = scanner->needle();
+ USE(tmp);
+ GetStack()->IteratePointers(scanner.get());
+ EXPECT_TRUE(scanner->found());
+ }
+}
+
+namespace {
+
+void RecursivelyPassOnParameter(int* volatile p1, int* volatile p2,
+ int* volatile p3, int* volatile p4,
+ int* volatile p5, int* volatile p6,
+ int* volatile p7, int* volatile p8,
+ Stack* stack, StackVisitor* visitor) {
+ if (p1) {
+ RecursivelyPassOnParameter(nullptr, p1, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, stack, visitor);
+ } else if (p2) {
+ RecursivelyPassOnParameter(nullptr, nullptr, p2, nullptr, nullptr, nullptr,
+ nullptr, nullptr, stack, visitor);
+ } else if (p3) {
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, p3, nullptr, nullptr,
+ nullptr, nullptr, stack, visitor);
+ } else if (p4) {
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, nullptr, p4, nullptr,
+ nullptr, nullptr, stack, visitor);
+ } else if (p5) {
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, nullptr, nullptr, p5,
+ nullptr, nullptr, stack, visitor);
+ } else if (p6) {
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, p6, nullptr, stack, visitor);
+ } else if (p7) {
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, p7, stack, visitor);
+ } else if (p8) {
+ stack->IteratePointers(visitor);
+ }
+}
+
+} // namespace
+
+TEST_F(GCStackTest, IteratePointersFindsParameter) {
+ auto scanner = std::make_unique<StackScanner>();
+ // No check that the needle is initially not found as on some platforms it
+ // may be part of the redzone or temporaries after setting it up throuhg
+ // StackScanner.
+ RecursivelyPassOnParameter(nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, scanner->needle(), GetStack(),
+ scanner.get());
+ EXPECT_TRUE(scanner->found());
+}
+
+TEST_F(GCStackTest, IteratePointersFindsParameterInNestedFunction) {
+ auto scanner = std::make_unique<StackScanner>();
+ // No check that the needle is initially not found as on some platforms it
+ // may be part of the redzone or temporaries after setting it up throuhg
+ // StackScanner.
+ RecursivelyPassOnParameter(scanner->needle(), nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, GetStack(),
+ scanner.get());
+ EXPECT_TRUE(scanner->found());
+}
+
+// The following test uses inline assembly and has been checked to work on clang
+// to verify that the stack-scanning trampoline pushes callee-saved registers.
+//
+// The test uses a macro loop as asm() can only be passed string literals.
+#ifdef __clang__
+#ifdef V8_TARGET_ARCH_X64
+#ifdef V8_OS_WIN
+
+// Excluded from test: rbp
+#define FOR_ALL_CALLEE_SAVED_REGS(V) \
+ V("rdi") \
+ V("rsi") \
+ V("rbx") \
+ V("r12") \
+ V("r13") \
+ V("r14") \
+ V("r15")
+
+#else // !V8_OS_WIN
+
+// Excluded from test: rbp
+#define FOR_ALL_CALLEE_SAVED_REGS(V) \
+ V("rbx") \
+ V("r12") \
+ V("r13") \
+ V("r14") \
+ V("r15")
+
+#endif // !V8_OS_WIN
+#endif // V8_TARGET_ARCH_X64
+#endif // __clang__
+
+#ifdef FOR_ALL_CALLEE_SAVED_REGS
+
+TEST_F(GCStackTest, IteratePointersFindsCalleeSavedRegisters) {
+ auto scanner = std::make_unique<StackScanner>();
+
+ // No check that the needle is initially not found as on some platforms it
+ // may be part of the redzone or temporaries after setting it up throuhg
+ // StackScanner.
+
+// First, clear all callee-saved registers.
+#define CLEAR_REGISTER(reg) asm("mov $0, %%" reg : : : reg);
+
+ FOR_ALL_CALLEE_SAVED_REGS(CLEAR_REGISTER)
+#undef CLEAR_REGISTER
+
+ // Keep local raw pointers to keep instruction sequences small below.
+ auto* local_stack = GetStack();
+ auto* local_scanner = scanner.get();
+
+// Moves |local_scanner->needle()| into a callee-saved register, leaving the
+// callee-saved register as the only register referencing the needle.
+// (Ignoring implementation-dependent dirty registers/stack.)
+#define KEEP_ALIVE_FROM_CALLEE_SAVED(reg) \
+ local_scanner->Reset(); \
+ /* This moves the temporary into the calee-saved register. */ \
+ asm("mov %0, %%" reg : : "r"(local_scanner->needle()) : reg); \
+ /* Register is unprotected from here till the actual invocation. */ \
+ local_stack->IteratePointers(local_scanner); \
+ EXPECT_TRUE(local_scanner->found()) \
+ << "pointer in callee-saved register not found. register: " << reg \
+ << std::endl; \
+ /* Clear out the register again */ \
+ asm("mov $0, %%" reg : : : reg);
+
+ FOR_ALL_CALLEE_SAVED_REGS(KEEP_ALIVE_FROM_CALLEE_SAVED)
+#undef KEEP_ALIVE_FROM_CALLEE_SAVED
+#undef FOR_ALL_CALLEE_SAVED_REGS
+}
+#endif // FOR_ALL_CALLEE_SAVED_REGS
+
+#if V8_OS_LINUX && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
+class CheckStackAlignmentVisitor final : public StackVisitor {
+ public:
+ void VisitPointer(const void*) final {
+ float f[4] = {0.};
+ volatile auto xmm = ::_mm_load_ps(f);
+ USE(xmm);
+ }
+};
+
+TEST_F(GCStackTest, StackAlignment) {
+ auto checker = std::make_unique<CheckStackAlignmentVisitor>();
+ GetStack()->IteratePointers(checker.get());
+}
+#endif // V8_OS_LINUX && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64)
+
+#endif // CPPGC_SUPPORTS_CONSERVATIVE_STACK_SCAN
+
+} // namespace internal
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/tests.cc b/deps/v8/test/unittests/heap/cppgc/tests.cc
new file mode 100644
index 0000000000..e67ac730d6
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/tests.cc
@@ -0,0 +1,36 @@
+// Copyright 2020 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 "test/unittests/heap/cppgc/tests.h"
+
+namespace cppgc {
+namespace testing {
+
+// static
+std::unique_ptr<cppgc::PageAllocator> TestWithPlatform::page_allocator_;
+
+// static
+void TestWithPlatform::SetUpTestSuite() {
+ page_allocator_.reset(new v8::base::PageAllocator());
+ cppgc::InitializePlatform(page_allocator_.get());
+}
+
+// static
+void TestWithPlatform::TearDownTestSuite() {
+ cppgc::ShutdownPlatform();
+ page_allocator_.reset();
+}
+
+void TestWithHeap::SetUp() {
+ heap_ = Heap::Create();
+ TestWithPlatform::SetUp();
+}
+
+void TestWithHeap::TearDown() {
+ heap_.reset();
+ TestWithPlatform::TearDown();
+}
+
+} // namespace testing
+} // namespace cppgc
diff --git a/deps/v8/test/unittests/heap/cppgc/tests.h b/deps/v8/test/unittests/heap/cppgc/tests.h
new file mode 100644
index 0000000000..d21f256444
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/tests.h
@@ -0,0 +1,39 @@
+// Copyright 2020 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_UNITTESTS_HEAP_CPPGC_TESTS_H_
+#define V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
+
+#include "include/cppgc/heap.h"
+#include "include/cppgc/platform.h"
+#include "src/base/page-allocator.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace testing {
+
+class TestWithPlatform : public ::testing::Test {
+ protected:
+ static void SetUpTestSuite();
+ static void TearDownTestSuite();
+
+ private:
+ static std::unique_ptr<cppgc::PageAllocator> page_allocator_;
+};
+
+class TestWithHeap : public TestWithPlatform {
+ protected:
+ void SetUp() override;
+ void TearDown() override;
+
+ Heap* GetHeap() const { return heap_.get(); }
+
+ private:
+ std::unique_ptr<cppgc::Heap> heap_;
+};
+
+} // namespace testing
+} // namespace cppgc
+
+#endif // V8_UNITTESTS_HEAP_CPPGC_TESTS_H_
diff --git a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
index b3901d74b0..c46ee35095 100644
--- a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
+++ b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc
@@ -30,7 +30,6 @@ class GCIdleTimeHandlerTest : public ::testing::Test {
static const size_t kSizeOfObjects = 100 * MB;
static const size_t kMarkCompactSpeed = 200 * KB;
- static const size_t kMarkingSpeed = 200 * KB;
private:
GCIdleTimeHandler handler_;
@@ -74,20 +73,6 @@ TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
}
-TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
- size_t idle_time_ms = 16;
- EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
- idle_time_ms, 0, 0));
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
- size_t idle_time_ms = 1;
- EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
- idle_time_ms, kSizeOfObjects, kMarkingSpeed));
-}
-
-
TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
if (!handler()->Enabled()) return;
GCIdleTimeHeapState heap_state = DefaultHeapState();
diff --git a/deps/v8/test/unittests/heap/local-heap-unittest.cc b/deps/v8/test/unittests/heap/local-heap-unittest.cc
new file mode 100644
index 0000000000..bf6aad6efc
--- /dev/null
+++ b/deps/v8/test/unittests/heap/local-heap-unittest.cc
@@ -0,0 +1,38 @@
+// Copyright 2020 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/heap/local-heap.h"
+#include "src/heap/heap.h"
+#include "src/heap/safepoint.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+using LocalHeapTest = TestWithIsolate;
+
+TEST_F(LocalHeapTest, Initialize) {
+ Heap* heap = i_isolate()->heap();
+
+ {
+ LocalHeap lh1(heap);
+ CHECK(heap->safepoint()->ContainsLocalHeap(&lh1));
+ LocalHeap lh2(heap);
+ CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
+
+ {
+ LocalHeap lh3(heap);
+ CHECK(heap->safepoint()->ContainsLocalHeap(&lh3));
+ }
+
+ CHECK(heap->safepoint()->ContainsLocalHeap(&lh1));
+ CHECK(heap->safepoint()->ContainsLocalHeap(&lh2));
+ }
+
+ CHECK(!heap->safepoint()->ContainsAnyLocalHeap());
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/heap/off-thread-factory-unittest.cc b/deps/v8/test/unittests/heap/off-thread-factory-unittest.cc
index 2c7bd639a8..0592d7b2db 100644
--- a/deps/v8/test/unittests/heap/off-thread-factory-unittest.cc
+++ b/deps/v8/test/unittests/heap/off-thread-factory-unittest.cc
@@ -8,65 +8,139 @@
#include <memory>
#include "src/ast/ast-value-factory.h"
+#include "src/ast/ast.h"
+#include "src/ast/scopes.h"
+#include "src/common/assert-scope.h"
+#include "src/common/globals.h"
+#include "src/execution/off-thread-isolate.h"
#include "src/handles/handles-inl.h"
#include "src/handles/handles.h"
-#include "src/heap/off-thread-factory.h"
+#include "src/heap/off-thread-factory-inl.h"
#include "src/objects/fixed-array.h"
+#include "src/objects/script.h"
+#include "src/objects/shared-function-info.h"
#include "src/objects/string.h"
+#include "src/parsing/parse-info.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
+#include "src/parsing/scanner-character-streams.h"
+#include "src/parsing/scanner.h"
+#include "src/strings/unicode-inl.h"
+#include "src/utils/utils.h"
#include "test/unittests/test-utils.h"
namespace v8 {
namespace internal {
+class OffThreadIsolate;
+
+namespace {
+
+std::vector<uint16_t> DecodeUtf8(const std::string& string) {
+ if (string.empty()) return {};
+
+ auto utf8_data =
+ Vector<const uint8_t>::cast(VectorOf(string.data(), string.length()));
+ Utf8Decoder decoder(utf8_data);
+
+ std::vector<uint16_t> utf16(decoder.utf16_length());
+ decoder.Decode(&utf16[0], utf8_data);
+
+ return utf16;
+}
+
+} // namespace
+
class OffThreadFactoryTest : public TestWithIsolateAndZone {
public:
OffThreadFactoryTest()
- : TestWithIsolateAndZone(), off_thread_factory_(isolate()) {}
+ : TestWithIsolateAndZone(),
+ parse_info_(isolate()),
+ off_thread_isolate_(isolate(), parse_info_.zone()) {}
+
+ FunctionLiteral* ParseProgram(const char* source) {
+ auto utf16_source = DecodeUtf8(source);
- OffThreadFactory* off_thread_factory() { return &off_thread_factory_; }
+ // Normally this would be an external string or whatever, we don't have to
+ // worry about it for now.
+ source_string_ =
+ factory()->NewStringFromUtf8(CStrVector(source)).ToHandleChecked();
+
+ parse_info_.set_character_stream(
+ ScannerStream::ForTesting(utf16_source.data(), utf16_source.size()));
+ parse_info_.set_toplevel();
+ parse_info_.set_allow_lazy_parsing();
+
+ {
+ DisallowHeapAllocation no_allocation;
+ DisallowHandleAllocation no_handles;
+ DisallowHeapAccess no_heap_access;
+
+ Parser parser(parse_info());
+ parser.InitializeEmptyScopeChain(parse_info());
+ parser.ParseOnBackground(parse_info());
+
+ CHECK(DeclarationScope::Analyze(parse_info()));
+ }
+
+ parse_info()->ast_value_factory()->Internalize(off_thread_isolate());
+ DeclarationScope::AllocateScopeInfos(parse_info(), off_thread_isolate());
+
+ script_ = parse_info_.CreateScript(off_thread_isolate(),
+ off_thread_factory()->empty_string(),
+ ScriptOriginOptions());
+
+ // Create the SFI list on the script so that SFI SetScript works.
+ Handle<WeakFixedArray> infos = off_thread_factory()->NewWeakFixedArray(
+ parse_info()->max_function_literal_id() + 1, AllocationType::kOld);
+ script_->set_shared_function_infos(*infos);
+
+ return parse_info()->literal();
+ }
+
+ ParseInfo* parse_info() { return &parse_info_; }
+
+ Handle<Script> script() { return script_; }
+
+ OffThreadIsolate* off_thread_isolate() { return &off_thread_isolate_; }
+ OffThreadFactory* off_thread_factory() {
+ return off_thread_isolate()->factory();
+ }
// We only internalize strings which are referred to in other slots, so create
// a wrapper pointing at the off_thread_string.
- OffThreadHandle<FixedArray> WrapString(OffThreadHandle<String> string) {
+ Handle<FixedArray> WrapString(Handle<String> string) {
// TODO(leszeks): Replace with a different factory method (e.g. FixedArray)
// once OffThreadFactory supports it.
return off_thread_factory()->StringWrapperForTest(string);
}
private:
- OffThreadFactory off_thread_factory_;
+ ParseInfo parse_info_;
+ OffThreadIsolate off_thread_isolate_;
+ Handle<String> source_string_;
+ Handle<Script> script_;
};
-TEST_F(OffThreadFactoryTest, HandleOrOffThreadHandle_IsNullWhenConstructed) {
- // Default constructed HandleOrOffThreadHandles should be considered both null
- // and uninitialized.
- EXPECT_TRUE(HandleOrOffThreadHandle<HeapObject>().is_null());
-#ifdef DEBUG
- EXPECT_TRUE(!HandleOrOffThreadHandle<HeapObject>().is_initialized());
-#endif
-
- // Default constructed HandleOrOffThreadHandles should work as both null
- // handles and null off-thread handles.
- EXPECT_TRUE(HandleOrOffThreadHandle<HeapObject>().get<Factory>().is_null());
- EXPECT_TRUE(
- HandleOrOffThreadHandle<HeapObject>().get<OffThreadFactory>().is_null());
-}
-
TEST_F(OffThreadFactoryTest, OneByteInternalizedString_IsAddedToStringTable) {
Vector<const uint8_t> string_vector = StaticCharVector("foo");
uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
string_vector.begin(), string_vector.length(), HashSeed(isolate()));
- OffThreadHandle<String> off_thread_string =
- off_thread_factory()->NewOneByteInternalizedString(string_vector,
- hash_field);
+ FixedArray off_thread_wrapper;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
- OffThreadHandle<FixedArray> off_thread_wrapper =
- off_thread_factory()->StringWrapperForTest(off_thread_string);
+ Handle<String> off_thread_string =
+ off_thread_factory()->NewOneByteInternalizedString(string_vector,
+ hash_field);
- off_thread_factory()->FinishOffThread();
+ off_thread_wrapper =
+ *off_thread_factory()->StringWrapperForTest(off_thread_string);
+ off_thread_factory()->FinishOffThread();
+ }
- Handle<FixedArray> wrapper = handle(*off_thread_wrapper, isolate());
+ Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
@@ -92,22 +166,25 @@ TEST_F(OffThreadFactoryTest,
uint32_t hash_field = StringHasher::HashSequentialString<uint8_t>(
string_vector.begin(), string_vector.length(), HashSeed(isolate()));
- OffThreadHandle<String> off_thread_string_1 =
- off_thread_factory()->NewOneByteInternalizedString(string_vector,
- hash_field);
- OffThreadHandle<String> off_thread_string_2 =
- off_thread_factory()->NewOneByteInternalizedString(string_vector,
- hash_field);
-
- OffThreadHandle<FixedArray> off_thread_wrapper_1 =
- WrapString(off_thread_string_1);
- OffThreadHandle<FixedArray> off_thread_wrapper_2 =
- WrapString(off_thread_string_2);
-
- off_thread_factory()->FinishOffThread();
+ FixedArray off_thread_wrapper_1;
+ FixedArray off_thread_wrapper_2;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
+
+ Handle<String> off_thread_string_1 =
+ off_thread_factory()->NewOneByteInternalizedString(string_vector,
+ hash_field);
+ Handle<String> off_thread_string_2 =
+ off_thread_factory()->NewOneByteInternalizedString(string_vector,
+ hash_field);
+
+ off_thread_wrapper_1 = *WrapString(off_thread_string_1);
+ off_thread_wrapper_2 = *WrapString(off_thread_string_2);
+ off_thread_factory()->FinishOffThread();
+ }
- Handle<FixedArray> wrapper_1 = handle(*off_thread_wrapper_1, isolate());
- Handle<FixedArray> wrapper_2 = handle(*off_thread_wrapper_2, isolate());
+ Handle<FixedArray> wrapper_1 = handle(off_thread_wrapper_1, isolate());
+ Handle<FixedArray> wrapper_2 = handle(off_thread_wrapper_2, isolate());
off_thread_factory()->Publish(isolate());
Handle<String> string_1 = handle(String::cast(wrapper_1->get(0)), isolate());
@@ -124,14 +201,17 @@ TEST_F(OffThreadFactoryTest, AstRawString_IsInternalized) {
const AstRawString* raw_string = ast_value_factory.GetOneByteString("foo");
- ast_value_factory.Internalize(off_thread_factory());
+ FixedArray off_thread_wrapper;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
- OffThreadHandle<FixedArray> off_thread_wrapper =
- WrapString(raw_string->string().get<OffThreadFactory>());
+ ast_value_factory.Internalize(off_thread_isolate());
- off_thread_factory()->FinishOffThread();
+ off_thread_wrapper = *WrapString(raw_string->string());
+ off_thread_factory()->FinishOffThread();
+ }
- Handle<FixedArray> wrapper = handle(*off_thread_wrapper, isolate());
+ Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
@@ -144,20 +224,24 @@ TEST_F(OffThreadFactoryTest, AstConsString_CreatesConsString) {
AstValueFactory ast_value_factory(zone(), isolate()->ast_string_constants(),
HashSeed(isolate()));
- const AstRawString* foo_string = ast_value_factory.GetOneByteString("foo");
- const AstRawString* bar_string =
- ast_value_factory.GetOneByteString("bar-plus-padding-for-length");
- const AstConsString* foobar_string =
- ast_value_factory.NewConsString(foo_string, bar_string);
+ FixedArray off_thread_wrapper;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
- ast_value_factory.Internalize(off_thread_factory());
+ const AstRawString* foo_string = ast_value_factory.GetOneByteString("foo");
+ const AstRawString* bar_string =
+ ast_value_factory.GetOneByteString("bar-plus-padding-for-length");
+ AstConsString* foobar_string =
+ ast_value_factory.NewConsString(foo_string, bar_string);
- OffThreadHandle<FixedArray> off_thread_wrapper =
- WrapString(foobar_string->string().get<OffThreadFactory>());
+ ast_value_factory.Internalize(off_thread_isolate());
- off_thread_factory()->FinishOffThread();
+ off_thread_wrapper =
+ *WrapString(foobar_string->GetString(off_thread_isolate()));
+ off_thread_factory()->FinishOffThread();
+ }
- Handle<FixedArray> wrapper = handle(*off_thread_wrapper, isolate());
+ Handle<FixedArray> wrapper = handle(off_thread_wrapper, isolate());
off_thread_factory()->Publish(isolate());
Handle<String> string = handle(String::cast(wrapper->get(0)), isolate());
@@ -167,5 +251,111 @@ TEST_F(OffThreadFactoryTest, AstConsString_CreatesConsString) {
"foobar-plus-padding-for-length")));
}
+TEST_F(OffThreadFactoryTest, EmptyScript) {
+ FunctionLiteral* program = ParseProgram("");
+
+ SharedFunctionInfo shared;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
+
+ shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
+ program, script(), true);
+
+ off_thread_factory()->FinishOffThread();
+ }
+
+ Handle<SharedFunctionInfo> root_sfi = handle(shared, isolate());
+ off_thread_factory()->Publish(isolate());
+
+ EXPECT_EQ(root_sfi->function_literal_id(), 0);
+}
+
+TEST_F(OffThreadFactoryTest, LazyFunction) {
+ FunctionLiteral* program = ParseProgram("function lazy() {}");
+ FunctionLiteral* lazy = program->scope()
+ ->declarations()
+ ->AtForTest(0)
+ ->AsFunctionDeclaration()
+ ->fun();
+
+ SharedFunctionInfo shared;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
+
+ shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
+ lazy, script(), true);
+
+ off_thread_factory()->FinishOffThread();
+ }
+
+ Handle<SharedFunctionInfo> lazy_sfi = handle(shared, isolate());
+ off_thread_factory()->Publish(isolate());
+
+ EXPECT_EQ(lazy_sfi->function_literal_id(), 1);
+ EXPECT_TRUE(lazy_sfi->Name().IsOneByteEqualTo(CStrVector("lazy")));
+ EXPECT_FALSE(lazy_sfi->is_compiled());
+ EXPECT_TRUE(lazy_sfi->HasUncompiledDataWithoutPreparseData());
+}
+
+TEST_F(OffThreadFactoryTest, EagerFunction) {
+ FunctionLiteral* program = ParseProgram("(function eager() {})");
+ FunctionLiteral* eager = program->body()
+ ->at(0)
+ ->AsExpressionStatement()
+ ->expression()
+ ->AsFunctionLiteral();
+
+ SharedFunctionInfo shared;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
+
+ shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
+ eager, script(), true);
+
+ off_thread_factory()->FinishOffThread();
+ }
+
+ Handle<SharedFunctionInfo> eager_sfi = handle(shared, isolate());
+ off_thread_factory()->Publish(isolate());
+
+ EXPECT_EQ(eager_sfi->function_literal_id(), 1);
+ EXPECT_TRUE(eager_sfi->Name().IsOneByteEqualTo(CStrVector("eager")));
+ EXPECT_FALSE(eager_sfi->HasUncompiledData());
+ // TODO(leszeks): Allocate bytecode and enable these checks.
+ // EXPECT_TRUE(eager_sfi->is_compiled());
+ // EXPECT_TRUE(eager_sfi->HasBytecodeArray());
+}
+
+TEST_F(OffThreadFactoryTest, ImplicitNameFunction) {
+ FunctionLiteral* program = ParseProgram("let implicit_name = function() {}");
+ FunctionLiteral* implicit_name = program->body()
+ ->at(0)
+ ->AsBlock()
+ ->statements()
+ ->at(0)
+ ->AsExpressionStatement()
+ ->expression()
+ ->AsAssignment()
+ ->value()
+ ->AsFunctionLiteral();
+
+ SharedFunctionInfo shared;
+ {
+ OffThreadHandleScope handle_scope(off_thread_isolate());
+
+ shared = *off_thread_factory()->NewSharedFunctionInfoForLiteral(
+ implicit_name, script(), true);
+
+ off_thread_factory()->FinishOffThread();
+ }
+
+ Handle<SharedFunctionInfo> implicit_name_sfi = handle(shared, isolate());
+ off_thread_factory()->Publish(isolate());
+
+ EXPECT_EQ(implicit_name_sfi->function_literal_id(), 1);
+ EXPECT_TRUE(
+ implicit_name_sfi->Name().IsOneByteEqualTo(CStrVector("implicit_name")));
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/safepoint-unittest.cc b/deps/v8/test/unittests/heap/safepoint-unittest.cc
new file mode 100644
index 0000000000..462992f5fd
--- /dev/null
+++ b/deps/v8/test/unittests/heap/safepoint-unittest.cc
@@ -0,0 +1,139 @@
+// Copyright 2020 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/heap/safepoint.h"
+#include "src/base/platform/mutex.h"
+#include "src/base/platform/platform.h"
+#include "src/heap/heap.h"
+#include "src/heap/local-heap.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+using SafepointTest = TestWithIsolate;
+
+TEST_F(SafepointTest, ReachSafepointWithoutLocalHeaps) {
+ Heap* heap = i_isolate()->heap();
+ bool run = false;
+ {
+ SafepointScope scope(heap);
+ run = true;
+ }
+ CHECK(run);
+}
+
+class ParkedThread final : public v8::base::Thread {
+ public:
+ ParkedThread(Heap* heap, base::Mutex* mutex)
+ : v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
+ heap_(heap),
+ mutex_(mutex) {}
+
+ void Run() override {
+ LocalHeap local_heap(heap_);
+
+ if (mutex_) {
+ ParkedScope scope(&local_heap);
+ base::MutexGuard guard(mutex_);
+ }
+ }
+
+ Heap* heap_;
+ base::Mutex* mutex_;
+};
+
+TEST_F(SafepointTest, StopParkedThreads) {
+ Heap* heap = i_isolate()->heap();
+
+ int safepoints = 0;
+
+ const int kThreads = 10;
+ const int kRuns = 5;
+
+ for (int run = 0; run < kRuns; run++) {
+ base::Mutex mutex;
+ std::vector<ParkedThread*> threads;
+
+ mutex.Lock();
+
+ for (int i = 0; i < kThreads; i++) {
+ ParkedThread* thread =
+ new ParkedThread(heap, i % 2 == 0 ? &mutex : nullptr);
+ CHECK(thread->Start());
+ threads.push_back(thread);
+ }
+
+ {
+ SafepointScope scope(heap);
+ safepoints++;
+ }
+ mutex.Unlock();
+
+ for (ParkedThread* thread : threads) {
+ thread->Join();
+ delete thread;
+ }
+ }
+
+ CHECK_EQ(safepoints, kRuns);
+}
+
+static const int kRuns = 10000;
+
+class RunningThread final : public v8::base::Thread {
+ public:
+ RunningThread(Heap* heap, std::atomic<int>* counter)
+ : v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
+ heap_(heap),
+ counter_(counter) {}
+
+ void Run() override {
+ LocalHeap local_heap(heap_);
+
+ for (int i = 0; i < kRuns; i++) {
+ counter_->fetch_add(1);
+ if (i % 100 == 0) local_heap.Safepoint();
+ }
+ }
+
+ Heap* heap_;
+ std::atomic<int>* counter_;
+};
+
+TEST_F(SafepointTest, StopRunningThreads) {
+ Heap* heap = i_isolate()->heap();
+
+ const int kThreads = 10;
+ const int kRuns = 5;
+ const int kSafepoints = 3;
+ int safepoint_count = 0;
+
+ for (int run = 0; run < kRuns; run++) {
+ std::atomic<int> counter(0);
+ std::vector<RunningThread*> threads;
+
+ for (int i = 0; i < kThreads; i++) {
+ RunningThread* thread = new RunningThread(heap, &counter);
+ CHECK(thread->Start());
+ threads.push_back(thread);
+ }
+
+ for (int i = 0; i < kSafepoints; i++) {
+ SafepointScope scope(heap);
+ safepoint_count++;
+ }
+
+ for (RunningThread* thread : threads) {
+ thread->Join();
+ delete thread;
+ }
+ }
+
+ CHECK_EQ(safepoint_count, kRuns * kSafepoints);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/heap/scavenge-job-unittest.cc b/deps/v8/test/unittests/heap/scavenge-job-unittest.cc
deleted file mode 100644
index 36d089f03b..0000000000
--- a/deps/v8/test/unittests/heap/scavenge-job-unittest.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2014 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 <limits>
-
-#include "src/common/globals.h"
-#include "src/heap/scavenge-job.h"
-#include "src/utils/utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace v8 {
-namespace internal {
-
-const size_t kScavengeSpeedInBytesPerMs = 500 * KB;
-const size_t kNewSpaceCapacity = 8 * MB;
-
-
-TEST(ScavengeJob, AllocationLimitEmptyNewSpace) {
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(
- kScavengeSpeedInBytesPerMs, 0, kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, AllocationLimitFullNewSpace) {
- EXPECT_TRUE(ScavengeJob::ReachedIdleAllocationLimit(
- kScavengeSpeedInBytesPerMs, kNewSpaceCapacity, kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, AllocationLimitUnknownScavengeSpeed) {
- size_t expected_size = ScavengeJob::kInitialScavengeSpeedInBytesPerMs *
- ScavengeJob::kAverageIdleTimeMs -
- ScavengeJob::kBytesAllocatedBeforeNextIdleTask;
- expected_size = Max(expected_size, ScavengeJob::kMinAllocationLimit);
-
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(0, expected_size - 1,
- kNewSpaceCapacity));
- EXPECT_TRUE(ScavengeJob::ReachedIdleAllocationLimit(0, expected_size,
- kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, AllocationLimitLowScavengeSpeed) {
- size_t scavenge_speed = 1 * KB;
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(
- scavenge_speed, ScavengeJob::kMinAllocationLimit - 1, kNewSpaceCapacity));
- EXPECT_TRUE(ScavengeJob::ReachedIdleAllocationLimit(
- scavenge_speed, ScavengeJob::kMinAllocationLimit, kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, AllocationLimitAverageScavengeSpeed) {
- size_t expected_size =
- kScavengeSpeedInBytesPerMs * ScavengeJob::kAverageIdleTimeMs -
- ScavengeJob::kBytesAllocatedBeforeNextIdleTask;
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(
- kScavengeSpeedInBytesPerMs, ScavengeJob::kMinAllocationLimit,
- kNewSpaceCapacity));
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(
- kScavengeSpeedInBytesPerMs, expected_size - 1, kNewSpaceCapacity));
- EXPECT_TRUE(ScavengeJob::ReachedIdleAllocationLimit(
- kScavengeSpeedInBytesPerMs, expected_size, kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, AllocationLimitHighScavengeSpeed) {
- size_t scavenge_speed = kNewSpaceCapacity;
- size_t expected_size =
- static_cast<size_t>(
- kNewSpaceCapacity *
- ScavengeJob::kMaxAllocationLimitAsFractionOfNewSpace) -
- ScavengeJob::kBytesAllocatedBeforeNextIdleTask;
- EXPECT_FALSE(ScavengeJob::ReachedIdleAllocationLimit(
- scavenge_speed, expected_size - 1, kNewSpaceCapacity));
- EXPECT_TRUE(ScavengeJob::ReachedIdleAllocationLimit(
- scavenge_speed, expected_size + 1, kNewSpaceCapacity));
-}
-
-
-TEST(ScavengeJob, EnoughIdleTimeForScavengeUnknownScavengeSpeed) {
- size_t scavenge_speed = ScavengeJob::kInitialScavengeSpeedInBytesPerMs;
- size_t new_space_size = 1 * MB;
- size_t expected_time = (new_space_size + scavenge_speed - 1) / scavenge_speed;
- EXPECT_TRUE(
- ScavengeJob::EnoughIdleTimeForScavenge(expected_time, 0, new_space_size));
- EXPECT_FALSE(ScavengeJob::EnoughIdleTimeForScavenge(expected_time - 1, 0,
- new_space_size));
-}
-
-
-TEST(ScavengeJob, EnoughIdleTimeForScavengeLowScavengeSpeed) {
- size_t scavenge_speed = 1 * KB;
- size_t new_space_size = 1 * MB;
- size_t expected_time = (new_space_size + scavenge_speed - 1) / scavenge_speed;
- EXPECT_TRUE(ScavengeJob::EnoughIdleTimeForScavenge(
- expected_time, scavenge_speed, new_space_size));
- EXPECT_FALSE(ScavengeJob::EnoughIdleTimeForScavenge(
- expected_time - 1, scavenge_speed, new_space_size));
-}
-
-
-TEST(ScavengeJob, EnoughIdleTimeForScavengeHighScavengeSpeed) {
- size_t scavenge_speed = kNewSpaceCapacity;
- size_t new_space_size = 1 * MB;
- size_t expected_time = (new_space_size + scavenge_speed - 1) / scavenge_speed;
- EXPECT_TRUE(ScavengeJob::EnoughIdleTimeForScavenge(
- expected_time, scavenge_speed, new_space_size));
- EXPECT_FALSE(ScavengeJob::EnoughIdleTimeForScavenge(
- expected_time - 1, scavenge_speed, new_space_size));
-}
-
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/test/unittests/heap/worklist-unittest.cc b/deps/v8/test/unittests/heap/worklist-unittest.cc
index b7e1231424..a12dcb0cee 100644
--- a/deps/v8/test/unittests/heap/worklist-unittest.cc
+++ b/deps/v8/test/unittests/heap/worklist-unittest.cc
@@ -148,13 +148,16 @@ TEST(WorkListTest, LocalPushStaysPrivate) {
SomeObject dummy;
SomeObject* retrieved = nullptr;
EXPECT_TRUE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
EXPECT_TRUE(worklist_view1.Push(&dummy));
EXPECT_FALSE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
EXPECT_FALSE(worklist_view2.Pop(&retrieved));
EXPECT_EQ(nullptr, retrieved);
EXPECT_TRUE(worklist_view1.Pop(&retrieved));
EXPECT_EQ(&dummy, retrieved);
EXPECT_TRUE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
}
TEST(WorkListTest, GlobalUpdateNull) {
@@ -168,6 +171,7 @@ TEST(WorkListTest, GlobalUpdateNull) {
EXPECT_TRUE(worklist_view.Push(object));
worklist.Update([](SomeObject* object, SomeObject** out) { return false; });
EXPECT_TRUE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
}
TEST(WorkListTest, GlobalUpdate) {
@@ -209,6 +213,7 @@ TEST(WorkListTest, FlushToGlobalPushSegment) {
objectA = reinterpret_cast<SomeObject*>(&objectA);
EXPECT_TRUE(worklist_view0.Push(objectA));
worklist.FlushToGlobal(0);
+ EXPECT_EQ(1U, worklist.GlobalPoolSize());
EXPECT_TRUE(worklist_view1.Pop(&object));
}
@@ -223,6 +228,7 @@ TEST(WorkListTest, FlushToGlobalPopSegment) {
EXPECT_TRUE(worklist_view0.Push(objectA));
EXPECT_TRUE(worklist_view0.Pop(&object));
worklist.FlushToGlobal(0);
+ EXPECT_EQ(1U, worklist.GlobalPoolSize());
EXPECT_TRUE(worklist_view1.Pop(&object));
}
@@ -235,8 +241,10 @@ TEST(WorkListTest, Clear) {
EXPECT_TRUE(worklist_view.Push(object));
}
EXPECT_TRUE(worklist_view.Push(object));
+ EXPECT_EQ(1U, worklist.GlobalPoolSize());
worklist.Clear();
EXPECT_TRUE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
}
TEST(WorkListTest, SingleSegmentSteal) {
@@ -252,6 +260,7 @@ TEST(WorkListTest, SingleSegmentSteal) {
EXPECT_TRUE(worklist_view1.Push(nullptr));
EXPECT_TRUE(worklist_view1.Pop(&retrieved));
EXPECT_EQ(nullptr, retrieved);
+ EXPECT_EQ(1U, worklist.GlobalPoolSize());
// Stealing.
for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
EXPECT_TRUE(worklist_view2.Pop(&retrieved));
@@ -259,6 +268,7 @@ TEST(WorkListTest, SingleSegmentSteal) {
EXPECT_FALSE(worklist_view1.Pop(&retrieved));
}
EXPECT_TRUE(worklist.IsEmpty());
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
}
TEST(WorkListTest, MultipleSegmentsStolen) {
@@ -280,11 +290,13 @@ TEST(WorkListTest, MultipleSegmentsStolen) {
EXPECT_TRUE(worklist_view1.Push(&dummy3));
EXPECT_TRUE(worklist_view1.Pop(&retrieved));
EXPECT_EQ(&dummy3, retrieved);
+ EXPECT_EQ(2U, worklist.GlobalPoolSize());
// Stealing.
EXPECT_TRUE(worklist_view2.Pop(&retrieved));
SomeObject* const expect_bag2 = retrieved;
EXPECT_TRUE(worklist_view3.Pop(&retrieved));
SomeObject* const expect_bag3 = retrieved;
+ EXPECT_EQ(0U, worklist.GlobalPoolSize());
EXPECT_NE(expect_bag2, expect_bag3);
EXPECT_TRUE(expect_bag2 == &dummy1 || expect_bag2 == &dummy2);
EXPECT_TRUE(expect_bag3 == &dummy1 || expect_bag3 == &dummy2);
@@ -313,10 +325,13 @@ TEST(WorkListTest, MergeGlobalPool) {
EXPECT_TRUE(worklist_view1.Push(nullptr));
EXPECT_TRUE(worklist_view1.Pop(&retrieved));
EXPECT_EQ(nullptr, retrieved);
+ EXPECT_EQ(1U, worklist1.GlobalPoolSize());
// Merging global pool into a new Worklist.
TestWorklist worklist2;
TestWorklist::View worklist_view2(&worklist2, 0);
+ EXPECT_EQ(0U, worklist2.GlobalPoolSize());
worklist2.MergeGlobalPool(&worklist1);
+ EXPECT_EQ(1U, worklist2.GlobalPoolSize());
EXPECT_FALSE(worklist2.IsEmpty());
for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
EXPECT_TRUE(worklist_view2.Pop(&retrieved));
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
index 7591a30f6b..cc7ca63061 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
@@ -79,8 +79,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreAccumulatorInRegister(wide);
// Emit Ldar and Star taking care to foil the register optimizer.
- builder.StackCheck(0)
- .LoadAccumulatorWithRegister(other)
+ builder.LoadAccumulatorWithRegister(other)
.BinaryOperation(Token::ADD, reg, 1)
.StoreAccumulatorInRegister(reg)
.LoadNull();
@@ -312,7 +311,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.Bind(&after_jump10)
.JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &after_jump11)
.Bind(&after_jump11)
- .JumpLoop(&loop_header, 0)
+ .JumpLoop(&loop_header, 0, 0)
.Bind(&after_loop);
}
@@ -343,9 +342,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit set pending message bytecode.
builder.SetPendingMessage();
- // Emit stack check bytecode.
- builder.StackCheck(0);
-
// Emit throw and re-throw in it's own basic block so that the rest of the
// code isn't omitted due to being dead.
BytecodeLabel after_throw, after_rethrow;
@@ -447,7 +443,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Generate BytecodeArray.
scope.SetScriptScopeInfo(factory->NewScopeInfo(1));
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> the_array = builder.ToBytecodeArray(isolate());
CHECK_EQ(the_array->frame_size(),
builder.total_register_count() * kSystemPointerSize);
@@ -535,7 +531,11 @@ TEST_F(BytecodeArrayBuilderTest, Parameters) {
Register receiver(builder.Receiver());
Register param8(builder.Parameter(8));
+#ifdef V8_REVERSE_JSARGS
+ CHECK_EQ(receiver.index() - param8.index(), 9);
+#else
CHECK_EQ(param8.index() - receiver.index(), 9);
+#endif
}
TEST_F(BytecodeArrayBuilderTest, Constants) {
@@ -560,7 +560,7 @@ TEST_F(BytecodeArrayBuilderTest, Constants) {
.LoadLiteral(nan)
.Return();
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate());
// Should only have one entry for each identical constant.
EXPECT_EQ(4, array->constant_pool().length());
@@ -706,12 +706,14 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
BytecodeLoopHeader loop_header;
builder.JumpIfNull(&after_loop)
.Bind(&loop_header)
- .JumpLoop(&loop_header, 0)
+ .JumpLoop(&loop_header, 0, 0)
.Bind(&after_loop);
for (int i = 0; i < 42; i++) {
BytecodeLabel after_loop;
// Conditional jump to force the code after the JumpLoop to be live.
- builder.JumpIfNull(&after_loop).JumpLoop(&loop_header, 0).Bind(&after_loop);
+ builder.JumpIfNull(&after_loop)
+ .JumpLoop(&loop_header, 0, 0)
+ .Bind(&after_loop);
}
// Add padding to force wide backwards jumps.
@@ -719,7 +721,7 @@ TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
builder.Debugger();
}
- builder.JumpLoop(&loop_header, 0);
+ builder.JumpLoop(&loop_header, 0, 0);
builder.Bind(&end);
builder.Return();
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
index 23f0d08c1c..5772b802c0 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
@@ -53,10 +53,8 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -73,7 +71,7 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
.Return();
// Test iterator sees the expected output from the builder.
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
BytecodeArrayIterator iterator(builder.ToBytecodeArray(isolate()));
const int kPrefixByteSize = 1;
int offset = 0;
@@ -138,14 +136,6 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
iterator.Advance();
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- CHECK(!iterator.done());
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- iterator.Advance();
-
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
@@ -164,14 +154,6 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
kPrefixByteSize;
iterator.Advance();
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- CHECK(!iterator.done());
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- iterator.Advance();
-
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
index 9553058d8d..ecdf6757fb 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
@@ -49,10 +49,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, InvalidBeforeStart) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -66,7 +64,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, InvalidBeforeStart) {
.Debugger()
.Return();
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
@@ -103,10 +101,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, InvalidAfterEnd) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -120,7 +116,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, InvalidAfterEnd) {
.Debugger()
.Return();
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
@@ -157,10 +153,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, AccessesFirst) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -174,7 +168,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, AccessesFirst) {
.Debugger()
.Return();
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
@@ -216,10 +210,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, AccessesLast) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -233,7 +225,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, AccessesLast) {
.Debugger()
.Return();
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
@@ -242,7 +234,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, AccessesLast) {
int offset = bytecodeArray->length() -
Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
- EXPECT_EQ(iterator.current_index(), 22);
+ EXPECT_EQ(iterator.current_index(), 20);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
@@ -276,10 +268,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -294,13 +284,13 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
.Return();
// Test iterator sees the expected output from the builder.
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
zone());
const int kPrefixByteSize = 1;
int offset = 0;
- iterator.GoToIndex(13);
+ iterator.GoToIndex(11);
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
@@ -308,16 +298,14 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
kPrefixByteSize;
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
- EXPECT_EQ(iterator.current_index(), 13);
+ EXPECT_EQ(iterator.current_index(), 11);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -336,7 +324,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
heap_num_1);
ASSERT_TRUE(iterator.IsValid());
- iterator.GoToIndex(18);
+ iterator.GoToIndex(16);
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
@@ -344,11 +332,9 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
kPrefixByteSize;
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
@@ -358,7 +344,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
- EXPECT_EQ(iterator.current_index(), 18);
+ EXPECT_EQ(iterator.current_index(), 16);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
@@ -375,7 +361,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
- EXPECT_EQ(iterator.current_index(), 15);
+ EXPECT_EQ(iterator.current_index(), 13);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -388,14 +374,14 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 17);
+ EXPECT_EQ(iterator.current_index(), 15);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
ASSERT_TRUE(iterator.IsValid());
- iterator.GoToIndex(22);
+ iterator.GoToIndex(20);
offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
@@ -403,11 +389,9 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
kPrefixByteSize;
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
@@ -422,12 +406,12 @@ TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
- EXPECT_EQ(iterator.current_index(), 22);
+ EXPECT_EQ(iterator.current_index(), 20);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
- iterator.GoToIndex(24);
+ iterator.GoToIndex(22);
EXPECT_FALSE(iterator.IsValid());
iterator.GoToIndex(-5);
@@ -462,10 +446,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -480,7 +462,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
.Return();
// Test iterator sees the expected output from the builder.
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
zone());
const int kPrefixByteSize = 1;
@@ -553,17 +535,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
++iterator;
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_index(), 7);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- ASSERT_TRUE(iterator.IsValid());
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- ++iterator;
-
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 8);
+ EXPECT_EQ(iterator.current_index(), 7);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -573,7 +546,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
- EXPECT_EQ(iterator.current_index(), 9);
+ EXPECT_EQ(iterator.current_index(), 8);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
@@ -582,17 +555,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
kPrefixByteSize;
++iterator;
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_index(), 10);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- ASSERT_TRUE(iterator.IsValid());
- offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- ++iterator;
-
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 11);
+ EXPECT_EQ(iterator.current_index(), 9);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -602,7 +566,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
- EXPECT_EQ(iterator.current_index(), 12);
+ EXPECT_EQ(iterator.current_index(), 10);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -611,7 +575,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
- EXPECT_EQ(iterator.current_index(), 13);
+ EXPECT_EQ(iterator.current_index(), 11);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -621,7 +585,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 14);
+ EXPECT_EQ(iterator.current_index(), 12);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -631,7 +595,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
- EXPECT_EQ(iterator.current_index(), 15);
+ EXPECT_EQ(iterator.current_index(), 13);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -642,7 +606,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
- EXPECT_EQ(iterator.current_index(), 16);
+ EXPECT_EQ(iterator.current_index(), 14);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -652,7 +616,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 17);
+ EXPECT_EQ(iterator.current_index(), 15);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
@@ -662,7 +626,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
- EXPECT_EQ(iterator.current_index(), 18);
+ EXPECT_EQ(iterator.current_index(), 16);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
@@ -677,7 +641,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
- EXPECT_EQ(iterator.current_index(), 19);
+ EXPECT_EQ(iterator.current_index(), 17);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -688,7 +652,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
- EXPECT_EQ(iterator.current_index(), 20);
+ EXPECT_EQ(iterator.current_index(), 18);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
@@ -699,7 +663,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
- EXPECT_EQ(iterator.current_index(), 21);
+ EXPECT_EQ(iterator.current_index(), 19);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
@@ -707,7 +671,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
++iterator;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
- EXPECT_EQ(iterator.current_index(), 22);
+ EXPECT_EQ(iterator.current_index(), 20);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
@@ -743,10 +707,8 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
.LoadLiteral(zero)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_0)
- .StackCheck(0)
.StoreAccumulatorInRegister(reg_0)
.LoadLiteral(smi_1)
- .StackCheck(1)
.StoreAccumulatorInRegister(reg_1)
.LoadAccumulatorWithRegister(reg_0)
.BinaryOperation(Token::Value::ADD, reg_0, 2)
@@ -761,7 +723,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
.Return();
// Test iterator sees the expected output from the builder.
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
const int kPrefixByteSize = 1;
@@ -771,7 +733,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
- EXPECT_EQ(iterator.current_index(), 22);
+ EXPECT_EQ(iterator.current_index(), 20);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
@@ -779,7 +741,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
- EXPECT_EQ(iterator.current_index(), 21);
+ EXPECT_EQ(iterator.current_index(), 19);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
ASSERT_TRUE(iterator.IsValid());
@@ -787,7 +749,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
- EXPECT_EQ(iterator.current_index(), 20);
+ EXPECT_EQ(iterator.current_index(), 18);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
@@ -798,7 +760,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
- EXPECT_EQ(iterator.current_index(), 19);
+ EXPECT_EQ(iterator.current_index(), 17);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -810,7 +772,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -=
Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
- EXPECT_EQ(iterator.current_index(), 18);
+ EXPECT_EQ(iterator.current_index(), 16);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
@@ -824,7 +786,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 17);
+ EXPECT_EQ(iterator.current_index(), 15);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
@@ -834,7 +796,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
- EXPECT_EQ(iterator.current_index(), 16);
+ EXPECT_EQ(iterator.current_index(), 14);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -844,7 +806,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
- EXPECT_EQ(iterator.current_index(), 15);
+ EXPECT_EQ(iterator.current_index(), 13);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -855,7 +817,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 14);
+ EXPECT_EQ(iterator.current_index(), 12);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -865,7 +827,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
- EXPECT_EQ(iterator.current_index(), 13);
+ EXPECT_EQ(iterator.current_index(), 11);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -875,7 +837,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
- EXPECT_EQ(iterator.current_index(), 12);
+ EXPECT_EQ(iterator.current_index(), 10);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -884,7 +846,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 11);
+ EXPECT_EQ(iterator.current_index(), 9);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
@@ -892,19 +854,10 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
ASSERT_TRUE(iterator.IsValid());
--iterator;
- offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_index(), 10);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- ASSERT_TRUE(iterator.IsValid());
- --iterator;
-
offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
kPrefixByteSize;
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
- EXPECT_EQ(iterator.current_index(), 9);
+ EXPECT_EQ(iterator.current_index(), 8);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
@@ -913,7 +866,7 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
- EXPECT_EQ(iterator.current_index(), 8);
+ EXPECT_EQ(iterator.current_index(), 7);
EXPECT_EQ(iterator.current_offset(), offset);
EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
@@ -921,15 +874,6 @@ TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
ASSERT_TRUE(iterator.IsValid());
--iterator;
- offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
- EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
- EXPECT_EQ(iterator.current_index(), 7);
- EXPECT_EQ(iterator.current_offset(), offset);
- EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
- EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
- ASSERT_TRUE(iterator.IsValid());
- --iterator;
-
offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
EXPECT_EQ(iterator.current_index(), 6);
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
index 339fc33178..0bf431eaae 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
@@ -115,28 +115,24 @@ void BytecodeArrayWriterUnittest::WriteJumpLoop(Bytecode bytecode,
TEST_F(BytecodeArrayWriterUnittest, SimpleExample) {
CHECK_EQ(bytecodes()->size(), 0u);
- Write(Bytecode::kStackCheck, {10, false});
- CHECK_EQ(bytecodes()->size(), 1u);
-
Write(Bytecode::kLdaSmi, 127, {55, true});
- CHECK_EQ(bytecodes()->size(), 3u);
+ CHECK_EQ(bytecodes()->size(), 2u);
Write(Bytecode::kStar, Register(20).ToOperand());
- CHECK_EQ(bytecodes()->size(), 5u);
+ CHECK_EQ(bytecodes()->size(), 4u);
Write(Bytecode::kLdar, Register(200).ToOperand());
- CHECK_EQ(bytecodes()->size(), 9u);
+ CHECK_EQ(bytecodes()->size(), 8u);
Write(Bytecode::kReturn, {70, true});
- CHECK_EQ(bytecodes()->size(), 10u);
+ CHECK_EQ(bytecodes()->size(), 9u);
static const uint8_t expected_bytes[] = {
// clang-format off
- /* 0 10 E> */ B(StackCheck),
- /* 1 55 S> */ B(LdaSmi), U8(127),
- /* 3 */ B(Star), R8(20),
- /* 5 */ B(Wide), B(Ldar), R16(200),
- /* 9 70 S> */ B(Return),
+ /* 0 55 S> */ B(LdaSmi), U8(127),
+ /* 2 */ B(Star), R8(20),
+ /* 4 */ B(Wide), B(Ldar), R16(200),
+ /* 8 70 S> */ B(Return),
// clang-format on
};
CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes));
@@ -150,8 +146,7 @@ TEST_F(BytecodeArrayWriterUnittest, SimpleExample) {
*writer()->ToSourcePositionTable(isolate()));
CHECK_EQ(bytecodes()->size(), arraysize(expected_bytes));
- PositionTableEntry expected_positions[] = {
- {0, 10, false}, {1, 55, true}, {9, 70, true}};
+ PositionTableEntry expected_positions[] = {{0, 55, true}, {8, 70, true}};
SourcePositionTableIterator source_iterator(
bytecode_array->SourcePositionTable());
for (size_t i = 0; i < arraysize(expected_positions); ++i) {
@@ -168,40 +163,37 @@ TEST_F(BytecodeArrayWriterUnittest, SimpleExample) {
TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
static const uint8_t expected_bytes[] = {
// clang-format off
- /* 0 30 E> */ B(StackCheck),
- /* 1 42 S> */ B(LdaConstant), U8(0),
- /* 3 42 E> */ B(Add), R8(1), U8(1),
- /* 5 68 S> */ B(JumpIfUndefined), U8(39),
- /* 7 */ B(JumpIfNull), U8(37),
- /* 9 */ B(ToObject), R8(3),
- /* 11 */ B(ForInPrepare), R8(3), U8(4),
- /* 14 */ B(LdaZero),
- /* 15 */ B(Star), R8(7),
- /* 17 63 S> */ B(ForInContinue), R8(7), R8(6),
- /* 20 */ B(JumpIfFalse), U8(24),
- /* 22 */ B(ForInNext), R8(3), R8(7), R8(4), U8(1),
- /* 27 */ B(JumpIfUndefined), U8(10),
- /* 29 */ B(Star), R8(0),
- /* 31 54 E> */ B(StackCheck),
- /* 32 */ B(Ldar), R8(0),
- /* 34 */ B(Star), R8(2),
- /* 36 85 S> */ B(Return),
- /* 37 */ B(ForInStep), R8(7),
- /* 39 */ B(Star), R8(7),
- /* 41 */ B(JumpLoop), U8(24), U8(0),
- /* 44 */ B(LdaUndefined),
- /* 45 85 S> */ B(Return),
+ /* 0 42 S> */ B(LdaConstant), U8(0),
+ /* 2 42 E> */ B(Add), R8(1), U8(1),
+ /* 4 68 S> */ B(JumpIfUndefined), U8(38),
+ /* 6 */ B(JumpIfNull), U8(36),
+ /* 8 */ B(ToObject), R8(3),
+ /* 10 */ B(ForInPrepare), R8(3), U8(4),
+ /* 13 */ B(LdaZero),
+ /* 14 */ B(Star), R8(7),
+ /* 16 63 S> */ B(ForInContinue), R8(7), R8(6),
+ /* 19 */ B(JumpIfFalse), U8(23),
+ /* 21 */ B(ForInNext), R8(3), R8(7), R8(4), U8(1),
+ /* 26 */ B(JumpIfUndefined), U8(9),
+ /* 28 */ B(Star), R8(0),
+ /* 30 */ B(Ldar), R8(0),
+ /* 32 */ B(Star), R8(2),
+ /* 34 85 S> */ B(Return),
+ /* 35 */ B(ForInStep), R8(7),
+ /* 37 */ B(Star), R8(7),
+ /* 39 */ B(JumpLoop), U8(23), U8(0),
+ /* 42 */ B(LdaUndefined),
+ /* 43 85 S> */ B(Return),
// clang-format on
};
static const PositionTableEntry expected_positions[] = {
- {0, 30, false}, {1, 42, true}, {3, 42, false}, {6, 68, true},
- {18, 63, true}, {32, 54, false}, {37, 85, true}, {46, 85, true}};
+ {0, 42, true}, {2, 42, false}, {5, 68, true},
+ {17, 63, true}, {35, 85, true}, {44, 85, true}};
BytecodeLoopHeader loop_header;
BytecodeLabel jump_for_in, jump_end_1, jump_end_2, jump_end_3;
- Write(Bytecode::kStackCheck, {30, false});
Write(Bytecode::kLdaConstant, U8(0), {42, true});
Write(Bytecode::kAdd, R(1), U8(1), {42, false});
WriteJump(Bytecode::kJumpIfUndefined, &jump_end_1, {68, true});
@@ -216,7 +208,6 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
Write(Bytecode::kForInNext, R(3), R(7), R(4), U8(1));
WriteJump(Bytecode::kJumpIfUndefined, &jump_for_in);
Write(Bytecode::kStar, R(0));
- Write(Bytecode::kStackCheck, {54, false});
Write(Bytecode::kLdar, R(0));
Write(Bytecode::kStar, R(2));
Write(Bytecode::kReturn, {85, true});
@@ -258,23 +249,18 @@ TEST_F(BytecodeArrayWriterUnittest, ElideNoneffectfulBytecodes) {
static const uint8_t expected_bytes[] = {
// clang-format off
- /* 0 10 E> */ B(StackCheck),
- /* 1 55 S> */ B(Ldar), R8(20),
- /* 3 */ B(Star), R8(20),
- /* 5 */ B(CreateMappedArguments),
- /* 6 60 S> */ B(LdaSmi), U8(127),
- /* 8 70 S> */ B(Ldar), R8(20),
- /* 10 75 S> */ B(Return),
+ /* 0 55 S> */ B(Ldar), R8(20),
+ /* 2 */ B(Star), R8(20),
+ /* 4 */ B(CreateMappedArguments),
+ /* 5 60 S> */ B(LdaSmi), U8(127),
+ /* 7 70 S> */ B(Ldar), R8(20),
+ /* 9 75 S> */ B(Return),
// clang-format on
};
- static const PositionTableEntry expected_positions[] = {{0, 10, false},
- {1, 55, true},
- {6, 60, false},
- {8, 70, true},
- {10, 75, true}};
+ static const PositionTableEntry expected_positions[] = {
+ {0, 55, true}, {5, 60, false}, {7, 70, true}, {9, 75, true}};
- Write(Bytecode::kStackCheck, {10, false});
Write(Bytecode::kLdaSmi, 127, {55, true}); // Should be elided.
Write(Bytecode::kLdar, Register(20).ToOperand());
Write(Bytecode::kStar, Register(20).ToOperand());
@@ -310,27 +296,25 @@ TEST_F(BytecodeArrayWriterUnittest, ElideNoneffectfulBytecodes) {
TEST_F(BytecodeArrayWriterUnittest, DeadcodeElimination) {
static const uint8_t expected_bytes[] = {
// clang-format off
- /* 0 10 E> */ B(StackCheck),
- /* 1 55 S> */ B(LdaSmi), U8(127),
- /* 3 */ B(Jump), U8(2),
- /* 5 65 S> */ B(LdaSmi), U8(127),
- /* 7 */ B(JumpIfFalse), U8(3),
- /* 9 75 S> */ B(Return),
- /* 10 */ B(JumpIfFalse), U8(3),
- /* 12 */ B(Throw),
- /* 13 */ B(JumpIfFalse), U8(3),
- /* 15 */ B(ReThrow),
- /* 16 */ B(Return),
+ /* 0 55 S> */ B(LdaSmi), U8(127),
+ /* 2 */ B(Jump), U8(2),
+ /* 4 65 S> */ B(LdaSmi), U8(127),
+ /* 6 */ B(JumpIfFalse), U8(3),
+ /* 8 75 S> */ B(Return),
+ /* 9 */ B(JumpIfFalse), U8(3),
+ /* 11 */ B(Throw),
+ /* 12 */ B(JumpIfFalse), U8(3),
+ /* 14 */ B(ReThrow),
+ /* 15 */ B(Return),
// clang-format on
};
static const PositionTableEntry expected_positions[] = {
- {0, 10, false}, {1, 55, true}, {5, 65, true}, {9, 75, true}};
+ {0, 55, true}, {4, 65, true}, {8, 75, true}};
BytecodeLabel after_jump, after_conditional_jump, after_return, after_throw,
after_rethrow;
- Write(Bytecode::kStackCheck, {10, false});
Write(Bytecode::kLdaSmi, 127, {55, true});
WriteJump(Bytecode::kJump, &after_jump);
Write(Bytecode::kLdaSmi, 127); // Dead code.
diff --git a/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
index 680479754a..bfe83b03ca 100644
--- a/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
@@ -40,7 +40,7 @@ TEST_F(ConstantArrayBuilderTest, AllocateAllEntries) {
builder.Insert(i + 0.5);
}
CHECK_EQ(builder.size(), k16BitCapacity);
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
for (size_t i = 0; i < k16BitCapacity; i++) {
CHECK_EQ(
Handle<HeapNumber>::cast(builder.At(i, isolate()).ToHandleChecked())
@@ -90,7 +90,7 @@ TEST_F(ConstantArrayBuilderTest, ToLargeFixedArrayWithReservations) {
for (int i = 0; i < kNumberOfElements; i++) {
builder.CommitReservedEntry(builder.CreateReservedEntry(), Smi::FromInt(i));
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
ASSERT_EQ(kNumberOfElements, constant_array->length());
for (int i = 0; i < kNumberOfElements; i++) {
@@ -149,7 +149,7 @@ TEST_F(ConstantArrayBuilderTest, AllocateEntriesWithIdx8Reservations) {
builder.DiscardReservedEntry(OperandSize::kByte);
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
CHECK_EQ(constant_array->length(),
static_cast<int>(2 * k8BitCapacity + reserved));
@@ -203,7 +203,7 @@ TEST_F(ConstantArrayBuilderTest, AllocateEntriesWithWideReservations) {
CHECK_EQ(builder.size(), i + 1);
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
CHECK_EQ(constant_array->length(),
static_cast<int>(k8BitCapacity + reserved));
@@ -234,7 +234,7 @@ TEST_F(ConstantArrayBuilderTest, GapFilledWhenLowReservationCommitted) {
Smi::FromInt(static_cast<int>(i)));
CHECK_EQ(builder.size(), 2 * k8BitCapacity);
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
CHECK_EQ(constant_array->length(), static_cast<int>(2 * k8BitCapacity));
for (size_t i = 0; i < k8BitCapacity; i++) {
@@ -300,7 +300,7 @@ TEST_F(ConstantArrayBuilderTest, HolesWithUnusedReservations) {
builder.DiscardReservedEntry(OperandSize::kByte);
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
CHECK_EQ(constant_array->length(), k8BitCapacity + 1);
for (int i = kNumberOfHoles; i < k8BitCapacity; i++) {
@@ -343,7 +343,7 @@ TEST_F(ConstantArrayBuilderTest, ReservationsAtAllScales) {
builder.DiscardReservedEntry(OperandSize::kQuad);
}
- ast_factory.Internalize(isolate()->factory());
+ ast_factory.Internalize(isolate());
Handle<FixedArray> constant_array = builder.ToFixedArray(isolate());
CHECK_EQ(constant_array->length(), 65537);
int count = 1;
diff --git a/deps/v8/test/unittests/objects/value-serializer-unittest.cc b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
index fac266d3f9..59d9b4df78 100644
--- a/deps/v8/test/unittests/objects/value-serializer-unittest.cc
+++ b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
@@ -235,8 +235,7 @@ class ValueSerializerTest : public TestWithIsolate {
}
Local<String> StringFromUtf8(const char* source) {
- return String::NewFromUtf8(isolate(), source, NewStringType::kNormal)
- .ToLocalChecked();
+ return String::NewFromUtf8(isolate(), source).ToLocalChecked();
}
std::string Utf8Value(Local<Value> value) {
@@ -2500,10 +2499,8 @@ class ValueSerializerTestWithWasm : public ValueSerializerTest {
Maybe<uint32_t> GetWasmModuleTransferId(
Isolate* isolate, Local<WasmModuleObject> module) override {
isolate->ThrowException(Exception::Error(
- String::NewFromOneByte(
- isolate,
- reinterpret_cast<const uint8_t*>(kUnsupportedSerialization),
- NewStringType::kNormal)
+ String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(
+ kUnsupportedSerialization))
.ToLocalChecked()));
return Nothing<uint32_t>();
}
diff --git a/deps/v8/test/unittests/profiler/strings-storage-unittest.cc b/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
index 31225f46c2..087a7bf735 100644
--- a/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
+++ b/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
@@ -108,5 +108,54 @@ TEST_F(StringsStorageWithIsolate, FormatAndGetShareStorage) {
CHECK_EQ(stored_str, formatted_str);
}
+TEST_F(StringsStorageWithIsolate, Refcounting) {
+ StringsStorage storage;
+
+ const char* a = storage.GetCopy("12");
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+
+ const char* b = storage.GetCopy("12");
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+
+ // Ensure that we deduplicate the string.
+ CHECK_EQ(a, b);
+
+ CHECK(storage.Release(a));
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+ CHECK(storage.Release(b));
+ CHECK_EQ(storage.GetStringCountForTesting(), 0);
+#if !DEBUG
+ CHECK(!storage.Release("12"));
+#endif // !DEBUG
+
+ // Verify that other constructors refcount as intended.
+ const char* c = storage.GetFormatted("%d", 12);
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+
+ const char* d = storage.GetName(12);
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+
+ CHECK_EQ(c, d);
+
+ CHECK(storage.Release(c));
+ CHECK_EQ(storage.GetStringCountForTesting(), 1);
+ CHECK(storage.Release(d));
+ CHECK_EQ(storage.GetStringCountForTesting(), 0);
+#if !DEBUG
+ CHECK(!storage.Release("12"));
+#endif // !DEBUG
+}
+
+TEST_F(StringsStorageWithIsolate, InvalidRelease) {
+ StringsStorage storage;
+
+ // If a refcount becomes invalid, throw in debug builds.
+#ifdef DEBUG
+ ASSERT_DEATH_IF_SUPPORTED(storage.Release("12"), "check failed");
+#else
+ CHECK(!storage.Release("12"));
+#endif // DEBUG
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/test-utils.h b/deps/v8/test/unittests/test-utils.h
index 3746ee267e..c2ffbf1561 100644
--- a/deps/v8/test/unittests/test-utils.h
+++ b/deps/v8/test/unittests/test-utils.h
@@ -181,9 +181,8 @@ class WithContextMixin : public TMixin {
const Local<Context>& v8_context() const { return context_; }
Local<Value> RunJS(const char* source) {
- return RunJS(v8::String::NewFromUtf8(v8_isolate(), source,
- v8::NewStringType::kNormal)
- .ToLocalChecked());
+ return RunJS(
+ v8::String::NewFromUtf8(v8_isolate(), source).ToLocalChecked());
}
Local<Value> RunJS(v8::String::ExternalOneByteStringResource* source) {
@@ -192,9 +191,7 @@ class WithContextMixin : public TMixin {
}
v8::Local<v8::String> NewString(const char* string) {
- return v8::String::NewFromUtf8(v8_isolate(), string,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
+ return v8::String::NewFromUtf8(v8_isolate(), string).ToLocalChecked();
}
void SetGlobalProperty(const char* name, v8::Local<v8::Value> value) {
diff --git a/deps/v8/test/unittests/torque/torque-unittest.cc b/deps/v8/test/unittests/torque/torque-unittest.cc
index 5180e301cc..778efc7641 100644
--- a/deps/v8/test/unittests/torque/torque-unittest.cc
+++ b/deps/v8/test/unittests/torque/torque-unittest.cc
@@ -25,6 +25,9 @@ namespace torque_internal {
const object: HeapObject;
const offset: intptr;
}
+ type ConstReference<T : type> extends Reference<T>;
+ type MutableReference<T : type> extends ConstReference<T>;
+
type UninitializedHeapObject extends HeapObject;
}
@@ -42,6 +45,7 @@ extern class HeapObject extends StrongTagged {
}
type Map extends HeapObject generates 'TNode<Map>';
type Object = Smi | HeapObject;
+type Number = Smi|HeapNumber;
type JSReceiver extends HeapObject generates 'TNode<JSReceiver>';
type JSObject extends JSReceiver generates 'TNode<JSObject>';
type int32 generates 'TNode<Int32T>' constexpr 'int32_t';
@@ -70,12 +74,18 @@ type Code extends HeapObject generates 'TNode<Code>';
type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>';
type Context extends HeapObject generates 'TNode<Context>';
type NativeContext extends Context;
+type SmiTagged<T : type extends uint31> extends Smi;
+type String extends HeapObject;
+type HeapNumber extends HeapObject;
+type FixedArrayBase extends HeapObject;
struct float64_or_hole {
is_hole: bool;
value: float64;
}
+extern operator '+' macro IntPtrAdd(intptr, intptr): intptr;
+
intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
intrinsic %RawDownCast<To: type, From: type>(x: From): To;
intrinsic %RawConstexprCast<To: type, From: type>(f: From): To;
@@ -84,6 +94,7 @@ extern macro TaggedToSmi(Object): Smi
labels CastError;
extern macro TaggedToHeapObject(Object): HeapObject
labels CastError;
+extern macro Float64SilenceNaN(float64): float64;
extern macro IntPtrConstant(constexpr int31): intptr;
@@ -97,6 +108,9 @@ FromConstexpr<Smi, constexpr int31>(s: constexpr int31): Smi {
FromConstexpr<intptr, constexpr int31>(i: constexpr int31): intptr {
return IntPtrConstant(i);
}
+FromConstexpr<intptr, constexpr intptr>(i: constexpr intptr): intptr {
+ return %FromConstexpr<intptr>(i);
+}
macro Cast<A : type extends Object>(implicit context: Context)(o: Object): A
labels CastError {
@@ -613,6 +627,134 @@ TEST(Torque, EnumInTypeswitch) {
)");
}
+TEST(Torque, ConstClassFields) {
+ ExpectSuccessfulCompilation(R"(
+ class Foo extends HeapObject {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ const _x: int32 = o.x;
+ o.y = n;
+ }
+ )");
+
+ ExpectFailingCompilation(R"(
+ class Foo extends HeapObject {
+ const x: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ o.x = n;
+ }
+ )",
+ HasSubstr("cannot assign to const value"));
+
+ ExpectSuccessfulCompilation(R"(
+ class Foo extends HeapObject {
+ s: Bar;
+ }
+ struct Bar {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ const _x: int32 = o.s.x;
+ // Assigning a struct as a value is OK, even when the struct contains
+ // const fields.
+ o.s = Bar{x: n, y: n};
+ o.s.y = n;
+ }
+ )");
+
+ ExpectFailingCompilation(R"(
+ class Foo extends HeapObject {
+ const s: Bar;
+ }
+ struct Bar {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ o.s.y = n;
+ }
+ )",
+ HasSubstr("cannot assign to const value"));
+
+ ExpectFailingCompilation(R"(
+ class Foo extends HeapObject {
+ s: Bar;
+ }
+ struct Bar {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ o.s.x = n;
+ }
+ )",
+ HasSubstr("cannot assign to const value"));
+}
+
+TEST(Torque, References) {
+ ExpectSuccessfulCompilation(R"(
+ class Foo extends HeapObject {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ const constRefX: const &int32 = &o.x;
+ const refY: &int32 = &o.y;
+ const constRefY: const &int32 = refY;
+ const _x: int32 = *constRefX;
+ const _y1: int32 = *refY;
+ const _y2: int32 = *constRefY;
+ *refY = n;
+ let r: const &int32 = constRefX;
+ r = constRefY;
+ }
+ )");
+
+ ExpectFailingCompilation(R"(
+ class Foo extends HeapObject {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo) {
+ const _refX: &int32 = &o.x;
+ }
+ )",
+ HasSubstr("cannot use expression of type const "
+ "&int32 as a value of type &int32"));
+
+ ExpectFailingCompilation(R"(
+ class Foo extends HeapObject {
+ const x: int32;
+ y: int32;
+ }
+
+ @export
+ macro Test(implicit context: Context)(o: Foo, n: int32) {
+ const constRefX: const &int32 = &o.x;
+ *constRefX = n;
+ }
+ )",
+ HasSubstr("cannot assign to const value"));
+}
+
} // namespace torque
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
index de3f825335..e242132a14 100644
--- a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
+++ b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
@@ -109,7 +109,7 @@ class FunctionBodyDecoderTest : public TestWithZone {
// Prepends local variable declarations and renders nice error messages for
// verification failures.
template <typename Code = std::initializer_list<const byte>>
- void Validate(bool expected_success, FunctionSig* sig, Code&& raw_code,
+ void Validate(bool expected_success, const FunctionSig* sig, Code&& raw_code,
AppendEnd append_end = kAppendEnd,
const char* message = nullptr) {
Vector<const byte> code =
@@ -136,20 +136,20 @@ class FunctionBodyDecoderTest : public TestWithZone {
}
template <typename Code = std::initializer_list<const byte>>
- void ExpectValidates(FunctionSig* sig, Code&& raw_code,
+ void ExpectValidates(const FunctionSig* sig, Code&& raw_code,
AppendEnd append_end = kAppendEnd,
const char* message = nullptr) {
Validate(true, sig, std::forward<Code>(raw_code), append_end, message);
}
template <typename Code = std::initializer_list<const byte>>
- void ExpectFailure(FunctionSig* sig, Code&& raw_code,
+ void ExpectFailure(const FunctionSig* sig, Code&& raw_code,
AppendEnd append_end = kAppendEnd,
const char* message = nullptr) {
Validate(false, sig, std::forward<Code>(raw_code), append_end, message);
}
- void TestBinop(WasmOpcode opcode, FunctionSig* success) {
+ void TestBinop(WasmOpcode opcode, const FunctionSig* success) {
// op(local[0], local[1])
byte code[] = {WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
ExpectValidates(success, code);
@@ -171,7 +171,7 @@ class FunctionBodyDecoderTest : public TestWithZone {
}
}
- void TestUnop(WasmOpcode opcode, FunctionSig* success) {
+ void TestUnop(WasmOpcode opcode, const FunctionSig* success) {
TestUnop(opcode, success->GetReturn(), success->GetParam(0));
}
@@ -215,22 +215,23 @@ class TestModuleBuilder {
CHECK_LE(mod.globals.size(), kMaxByteSizedLeb128);
return static_cast<byte>(mod.globals.size() - 1);
}
- byte AddSignature(FunctionSig* sig) {
+ byte AddSignature(const FunctionSig* sig) {
mod.signatures.push_back(sig);
CHECK_LE(mod.signatures.size(), kMaxByteSizedLeb128);
return static_cast<byte>(mod.signatures.size() - 1);
}
- byte AddFunction(FunctionSig* sig) {
- mod.functions.push_back({sig, // sig
- 0, // func_index
- 0, // sig_index
- {0, 0}, // code
- false, // import
- false}); // export
+ byte AddFunction(const FunctionSig* sig, bool declared = true) {
+ mod.functions.push_back({sig, // sig
+ 0, // func_index
+ 0, // sig_index
+ {0, 0}, // code
+ false, // import
+ false, // export
+ declared}); // declared
CHECK_LE(mod.functions.size(), kMaxByteSizedLeb128);
return static_cast<byte>(mod.functions.size() - 1);
}
- byte AddImport(FunctionSig* sig) {
+ byte AddImport(const FunctionSig* sig) {
byte result = AddFunction(sig);
mod.functions[result].imported = true;
return result;
@@ -259,11 +260,16 @@ class TestModuleBuilder {
mod.maximum_pages = 100;
}
- void InitializeTable() { mod.tables.emplace_back(); }
+ byte InitializeTable(wasm::ValueType type) {
+ mod.tables.emplace_back();
+ mod.tables.back().type = type;
+ return static_cast<byte>(mod.tables.size() - 1);
+ }
- byte AddPassiveElementSegment() {
- mod.elem_segments.emplace_back();
+ byte AddPassiveElementSegment(wasm::ValueType type) {
+ mod.elem_segments.emplace_back(false);
auto& init = mod.elem_segments.back();
+ init.type = type;
// Add 5 empty elements.
for (uint32_t j = 0; j < 5; j++) {
init.entries.push_back(WasmElemSegment::kNullIndex);
@@ -271,6 +277,12 @@ class TestModuleBuilder {
return static_cast<byte>(mod.elem_segments.size() - 1);
}
+ byte AddDeclarativeElementSegment() {
+ mod.elem_segments.emplace_back(true);
+ mod.elem_segments.back().entries.push_back(WasmElemSegment::kNullIndex);
+ return static_cast<byte>(mod.elem_segments.size() - 1);
+ }
+
// Set the number of data segments as declared by the DataCount section.
void SetDataSegmentCount(uint32_t data_segment_count) {
// The Data section occurs after the Code section, so we don't need to
@@ -387,10 +399,8 @@ TEST_F(FunctionBodyDecoderTest, TooManyLocals) {
}
TEST_F(FunctionBodyDecoderTest, GetLocal0_param_n) {
- FunctionSig* array[] = {sigs.i_i(), sigs.i_ii(), sigs.i_iii()};
-
- for (size_t i = 0; i < arraysize(array); i++) {
- ExpectValidates(array[i], kCodeGetLocal0);
+ for (const FunctionSig* sig : {sigs.i_i(), sigs.i_ii(), sigs.i_iii()}) {
+ ExpectValidates(sig, kCodeGetLocal0);
}
}
@@ -1350,14 +1360,14 @@ TEST_F(FunctionBodyDecoderTest, MacrosInt64) {
TEST_F(FunctionBodyDecoderTest, AllSimpleExpressions) {
WASM_FEATURE_SCOPE(anyref);
// Test all simple expressions which are described by a signature.
-#define DECODE_TEST(name, opcode, sig) \
- { \
- FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \
- if (sig->parameter_count() == 1) { \
- TestUnop(kExpr##name, sig); \
- } else { \
- TestBinop(kExpr##name, sig); \
- } \
+#define DECODE_TEST(name, opcode, sig) \
+ { \
+ const FunctionSig* sig = WasmOpcodes::Signature(kExpr##name); \
+ if (sig->parameter_count() == 1) { \
+ TestUnop(kExpr##name, sig); \
+ } else { \
+ TestBinop(kExpr##name, sig); \
+ } \
}
FOREACH_SIMPLE_OPCODE(DECODE_TEST);
@@ -1475,7 +1485,7 @@ TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) {
MachineType mem_type = machineTypes[j];
byte code[] = {WASM_LOAD_MEM(mem_type, WASM_ZERO)};
FunctionSig sig(1, 0, &local_type);
- Validate(local_type == ValueTypes::ValueTypeFor(mem_type), &sig, code);
+ Validate(local_type == ValueType::For(mem_type), &sig, code);
}
}
}
@@ -1490,13 +1500,13 @@ TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) {
MachineType mem_type = machineTypes[j];
byte code[] = {WASM_STORE_MEM(mem_type, WASM_ZERO, WASM_GET_LOCAL(0))};
FunctionSig sig(0, 1, &local_type);
- Validate(local_type == ValueTypes::ValueTypeFor(mem_type), &sig, code);
+ Validate(local_type == ValueType::For(mem_type), &sig, code);
}
}
}
TEST_F(FunctionBodyDecoderTest, SimpleCalls) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1511,7 +1521,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleCalls) {
}
TEST_F(FunctionBodyDecoderTest, CallsWithTooFewArguments) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1525,7 +1535,7 @@ TEST_F(FunctionBodyDecoderTest, CallsWithTooFewArguments) {
}
TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs2) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1537,7 +1547,7 @@ TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs2) {
}
TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs3) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1557,7 +1567,7 @@ TEST_F(FunctionBodyDecoderTest, CallsWithMismatchedSigs3) {
TEST_F(FunctionBodyDecoderTest, SimpleReturnCalls) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1574,7 +1584,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleReturnCalls) {
TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1590,7 +1600,7 @@ TEST_F(FunctionBodyDecoderTest, ReturnCallsWithTooFewArguments) {
TEST_F(FunctionBodyDecoderTest, ReturnCallsWithMismatchedSigs) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1609,7 +1619,7 @@ TEST_F(FunctionBodyDecoderTest, ReturnCallsWithMismatchedSigs) {
TEST_F(FunctionBodyDecoderTest, SimpleIndirectReturnCalls) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.AddTable(kWasmFuncRef, 20, true, 30);
module = builder.module();
@@ -1628,7 +1638,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleIndirectReturnCalls) {
TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsOutOfBounds) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.AddTable(kWasmFuncRef, 20, false, 20);
module = builder.module();
@@ -1650,9 +1660,9 @@ TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsOutOfBounds) {
TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithMismatchedSigs3) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
byte sig0 = builder.AddSignature(sigs.i_f());
@@ -1681,7 +1691,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithMismatchedSigs3) {
TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithoutTableCrash) {
WASM_FEATURE_SCOPE(return_call);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1697,9 +1707,9 @@ TEST_F(FunctionBodyDecoderTest, IndirectReturnCallsWithoutTableCrash) {
}
TEST_F(FunctionBodyDecoderTest, IncompleteIndirectReturnCall) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
static byte code[] = {kExprReturnCallIndirect};
@@ -1739,8 +1749,8 @@ TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
ExpectValidates(&sig_cd_v, {WASM_CALL_FUNCTION0(0)});
- if (ValueTypes::IsSubType(kValueTypes[c], kValueTypes[a]) &&
- ValueTypes::IsSubType(kValueTypes[d], kValueTypes[b])) {
+ if (kValueTypes[c].IsSubTypeOf(kValueTypes[a]) &&
+ kValueTypes[d].IsSubTypeOf(kValueTypes[b])) {
ExpectValidates(&sig_ab_v, {WASM_CALL_FUNCTION0(0)});
} else {
ExpectFailure(&sig_ab_v, {WASM_CALL_FUNCTION0(0)});
@@ -1752,7 +1762,7 @@ TEST_F(FunctionBodyDecoderTest, MultiReturnType) {
}
TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.AddTable(kWasmFuncRef, 20, false, 20);
module = builder.module();
@@ -1768,7 +1778,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleIndirectCalls) {
}
TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.AddTable(kWasmFuncRef, 20, false, 20);
module = builder.module();
@@ -1785,9 +1795,9 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsOutOfBounds) {
}
TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
byte sig0 = builder.AddSignature(sigs.i_f());
@@ -1808,7 +1818,7 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsWithMismatchedSigs3) {
}
TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1823,9 +1833,9 @@ TEST_F(FunctionBodyDecoderTest, IndirectCallsWithoutTableCrash) {
}
TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
static byte code[] = {kExprCallIndirect};
@@ -1833,10 +1843,10 @@ TEST_F(FunctionBodyDecoderTest, IncompleteIndirectCall) {
}
TEST_F(FunctionBodyDecoderTest, IncompleteStore) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.InitializeMemory();
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
static byte code[] = {kExprI32StoreMem};
@@ -1845,10 +1855,10 @@ TEST_F(FunctionBodyDecoderTest, IncompleteStore) {
TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) {
WASM_FEATURE_SCOPE(simd);
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
builder.InitializeMemory();
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
static byte code[] = {kSimdPrefix,
@@ -1857,7 +1867,7 @@ TEST_F(FunctionBodyDecoderTest, IncompleteS8x16Shuffle) {
}
TEST_F(FunctionBodyDecoderTest, SimpleImportCalls) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1872,7 +1882,7 @@ TEST_F(FunctionBodyDecoderTest, SimpleImportCalls) {
}
TEST_F(FunctionBodyDecoderTest, ImportCallsWithMismatchedSigs3) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1892,7 +1902,7 @@ TEST_F(FunctionBodyDecoderTest, ImportCallsWithMismatchedSigs3) {
}
TEST_F(FunctionBodyDecoderTest, Int32Globals) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1904,7 +1914,7 @@ TEST_F(FunctionBodyDecoderTest, Int32Globals) {
}
TEST_F(FunctionBodyDecoderTest, ImmutableGlobal) {
- FunctionSig* sig = sigs.v_v();
+ const FunctionSig* sig = sigs.v_v();
TestModuleBuilder builder;
module = builder.module();
@@ -1916,7 +1926,7 @@ TEST_F(FunctionBodyDecoderTest, ImmutableGlobal) {
}
TEST_F(FunctionBodyDecoderTest, Int32Globals_fail) {
- FunctionSig* sig = sigs.i_i();
+ const FunctionSig* sig = sigs.i_i();
TestModuleBuilder builder;
module = builder.module();
@@ -1937,7 +1947,7 @@ TEST_F(FunctionBodyDecoderTest, Int32Globals_fail) {
}
TEST_F(FunctionBodyDecoderTest, Int64Globals) {
- FunctionSig* sig = sigs.l_l();
+ const FunctionSig* sig = sigs.l_l();
TestModuleBuilder builder;
module = builder.module();
@@ -1954,7 +1964,7 @@ TEST_F(FunctionBodyDecoderTest, Int64Globals) {
}
TEST_F(FunctionBodyDecoderTest, Float32Globals) {
- FunctionSig* sig = sigs.f_ff();
+ const FunctionSig* sig = sigs.f_ff();
TestModuleBuilder builder;
module = builder.module();
@@ -1966,7 +1976,7 @@ TEST_F(FunctionBodyDecoderTest, Float32Globals) {
}
TEST_F(FunctionBodyDecoderTest, Float64Globals) {
- FunctionSig* sig = sigs.d_dd();
+ const FunctionSig* sig = sigs.d_dd();
TestModuleBuilder builder;
module = builder.module();
@@ -1986,8 +1996,7 @@ TEST_F(FunctionBodyDecoderTest, AllGetGlobalCombinations) {
TestModuleBuilder builder;
module = builder.module();
builder.AddGlobal(global_type);
- Validate(ValueTypes::IsSubType(global_type, local_type), &sig,
- {WASM_GET_GLOBAL(0)});
+ Validate(global_type.IsSubTypeOf(local_type), &sig, {WASM_GET_GLOBAL(0)});
}
}
}
@@ -2001,7 +2010,7 @@ TEST_F(FunctionBodyDecoderTest, AllSetGlobalCombinations) {
TestModuleBuilder builder;
module = builder.module();
builder.AddGlobal(global_type);
- Validate(ValueTypes::IsSubType(local_type, global_type), &sig,
+ Validate(local_type.IsSubTypeOf(global_type), &sig,
{WASM_SET_GLOBAL(0, WASM_GET_LOCAL(0))});
}
}
@@ -2181,7 +2190,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
FunctionSig sig_d_id(1, 2, float64int32float64);
struct {
WasmOpcode op;
- FunctionSig* sig;
+ const FunctionSig* sig;
} AsmJsBinOps[] = {
{kExprF64Atan2, sigs.d_dd()},
{kExprF64Pow, sigs.d_dd()},
@@ -2225,7 +2234,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
FunctionSig sig_d_i(1, 1, float64int32);
struct {
WasmOpcode op;
- FunctionSig* sig;
+ const FunctionSig* sig;
} AsmJsUnOps[] = {{kExprF64Acos, sigs.d_d()},
{kExprF64Asin, sigs.d_d()},
{kExprF64Atan, sigs.d_d()},
@@ -2367,9 +2376,8 @@ TEST_F(FunctionBodyDecoderTest, BreakNesting_6_levels) {
}
TEST_F(FunctionBodyDecoderTest, Break_TypeCheck) {
- FunctionSig* sigarray[] = {sigs.i_i(), sigs.l_l(), sigs.f_ff(), sigs.d_dd()};
- for (size_t i = 0; i < arraysize(sigarray); i++) {
- FunctionSig* sig = sigarray[i];
+ for (const FunctionSig* sig :
+ {sigs.i_i(), sigs.l_l(), sigs.f_ff(), sigs.d_dd()}) {
// unify X and X => OK
byte code[] = {WASM_BLOCK_T(
sig->GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
@@ -2398,8 +2406,7 @@ TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll1) {
sig.GetReturn(), WASM_IF(WASM_ZERO, WASM_BRV(0, WASM_GET_LOCAL(0))),
WASM_GET_LOCAL(1))};
- Validate(ValueTypes::IsSubType(kValueTypes[j], kValueTypes[i]), &sig,
- code);
+ Validate(kValueTypes[j].IsSubTypeOf(kValueTypes[i]), &sig, code);
}
}
}
@@ -2413,8 +2420,7 @@ TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll2) {
WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)),
WASM_GET_LOCAL(1))};
- Validate(ValueTypes::IsSubType(kValueTypes[j], kValueTypes[i]), &sig,
- code);
+ Validate(kValueTypes[j].IsSubTypeOf(kValueTypes[i]), &sig, code);
}
}
}
@@ -2428,8 +2434,7 @@ TEST_F(FunctionBodyDecoderTest, Break_TypeCheckAll3) {
WASM_GET_LOCAL(1),
WASM_BRV_IF_ZERO(0, WASM_GET_LOCAL(0)))};
- Validate(ValueTypes::IsSubType(kValueTypes[j], kValueTypes[i]), &sig,
- code);
+ Validate(kValueTypes[j].IsSubTypeOf(kValueTypes[i]), &sig, code);
}
}
}
@@ -2473,8 +2478,7 @@ TEST_F(FunctionBodyDecoderTest, BreakIf_val_type) {
types[1], WASM_BRV_IF(0, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)),
WASM_DROP, WASM_GET_LOCAL(0))};
- Validate(ValueTypes::IsSubType(kValueTypes[j], kValueTypes[i]), &sig,
- code);
+ Validate(kValueTypes[j].IsSubTypeOf(kValueTypes[i]), &sig, code);
}
}
}
@@ -3203,8 +3207,8 @@ TEST_F(FunctionBodyDecoderTest, BulkMemoryOpsWithoutMemory) {
TEST_F(FunctionBodyDecoderTest, TableInit) {
TestModuleBuilder builder;
- builder.InitializeTable();
- builder.AddPassiveElementSegment();
+ builder.InitializeTable(wasm::kWasmFuncRef);
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
ExpectFailure(sigs.v_v(),
@@ -3216,10 +3220,22 @@ TEST_F(FunctionBodyDecoderTest, TableInit) {
{WASM_TABLE_INIT(0, 1, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
}
+TEST_F(FunctionBodyDecoderTest, TableInitWrongType) {
+ TestModuleBuilder builder;
+ uint32_t table_index = builder.InitializeTable(wasm::kWasmFuncRef);
+ uint32_t element_index = builder.AddPassiveElementSegment(wasm::kWasmAnyRef);
+ module = builder.module();
+
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ ExpectFailure(sigs.v_v(), {WASM_TABLE_INIT(table_index, element_index,
+ WASM_ZERO, WASM_ZERO, WASM_ZERO)});
+}
+
TEST_F(FunctionBodyDecoderTest, TableInitInvalid) {
TestModuleBuilder builder;
- builder.InitializeTable();
- builder.AddPassiveElementSegment();
+ builder.InitializeTable(wasm::kWasmFuncRef);
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
WASM_FEATURE_SCOPE(bulk_memory);
@@ -3232,8 +3248,8 @@ TEST_F(FunctionBodyDecoderTest, TableInitInvalid) {
TEST_F(FunctionBodyDecoderTest, ElemDrop) {
TestModuleBuilder builder;
- builder.InitializeTable();
- builder.AddPassiveElementSegment();
+ builder.InitializeTable(wasm::kWasmFuncRef);
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
@@ -3242,11 +3258,62 @@ TEST_F(FunctionBodyDecoderTest, ElemDrop) {
ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(1)});
}
+TEST_F(FunctionBodyDecoderTest, TableInitDeclarativeElem) {
+ TestModuleBuilder builder;
+ builder.InitializeTable(wasm::kWasmFuncRef);
+ builder.AddDeclarativeElementSegment();
+ module = builder.module();
+
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ byte code[] = {WASM_TABLE_INIT(0, 0, WASM_ZERO, WASM_ZERO, WASM_ZERO),
+ WASM_END};
+ for (size_t i = 0; i <= arraysize(code); ++i) {
+ Validate(i == arraysize(code), sigs.v_v(), VectorOf(code, i), kOmitEnd);
+ }
+}
+
+TEST_F(FunctionBodyDecoderTest, DeclarativeElemDrop) {
+ TestModuleBuilder builder;
+ builder.InitializeTable(wasm::kWasmFuncRef);
+ builder.AddDeclarativeElementSegment();
+ module = builder.module();
+
+ ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(0)});
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ ExpectValidates(sigs.v_v(), {WASM_ELEM_DROP(0)});
+ ExpectFailure(sigs.v_v(), {WASM_ELEM_DROP(1)});
+}
+
+TEST_F(FunctionBodyDecoderTest, RefFuncDeclared) {
+ TestModuleBuilder builder;
+ builder.InitializeTable(wasm::kWasmStmt);
+ byte function_index = builder.AddFunction(sigs.v_i());
+ module = builder.module();
+
+ ExpectFailure(sigs.a_v(), {WASM_REF_FUNC(function_index)});
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ ExpectValidates(sigs.a_v(), {WASM_REF_FUNC(function_index)});
+}
+
+TEST_F(FunctionBodyDecoderTest, RefFuncUndeclared) {
+ TestModuleBuilder builder;
+ builder.InitializeTable(wasm::kWasmStmt);
+ byte function_index = builder.AddFunction(sigs.v_i(), false);
+ module = builder.module();
+
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ ExpectFailure(sigs.a_v(), {WASM_REF_FUNC(function_index)});
+}
+
TEST_F(FunctionBodyDecoderTest, ElemSegmentIndexUnsigned) {
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmFuncRef);
for (int i = 0; i < 65; ++i) {
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
}
module = builder.module();
@@ -3260,7 +3327,7 @@ TEST_F(FunctionBodyDecoderTest, ElemSegmentIndexUnsigned) {
TEST_F(FunctionBodyDecoderTest, TableCopy) {
TestModuleBuilder builder;
- builder.InitializeTable();
+ builder.InitializeTable(wasm::kWasmStmt);
module = builder.module();
ExpectFailure(sigs.v_v(),
@@ -3270,6 +3337,18 @@ TEST_F(FunctionBodyDecoderTest, TableCopy) {
{WASM_TABLE_COPY(0, 0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
}
+TEST_F(FunctionBodyDecoderTest, TableCopyWrongType) {
+ TestModuleBuilder builder;
+ uint32_t dst_table_index = builder.InitializeTable(wasm::kWasmFuncRef);
+ uint32_t src_table_index = builder.InitializeTable(wasm::kWasmAnyRef);
+ module = builder.module();
+
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ ExpectFailure(sigs.v_v(), {WASM_TABLE_COPY(dst_table_index, src_table_index,
+ WASM_ZERO, WASM_ZERO, WASM_ZERO)});
+}
+
TEST_F(FunctionBodyDecoderTest, TableGrow) {
TestModuleBuilder builder;
byte tab_func = builder.AddTable(kWasmFuncRef, 10, true, 20);
@@ -3369,7 +3448,7 @@ TEST_F(FunctionBodyDecoderTest, TableOpsWithoutTable) {
}
{
WASM_FEATURE_SCOPE(bulk_memory);
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
ExpectFailure(sigs.v_v(),
{WASM_TABLE_INIT(0, 0, WASM_ZERO, WASM_ZERO, WASM_ZERO)});
ExpectFailure(sigs.v_v(),
@@ -3383,7 +3462,7 @@ TEST_F(FunctionBodyDecoderTest, TableCopyMultiTable) {
{
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
// We added one table, therefore table.copy on table 0 should work.
int table_src = 0;
@@ -3405,7 +3484,7 @@ TEST_F(FunctionBodyDecoderTest, TableCopyMultiTable) {
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
builder.AddTable(kWasmAnyRef, 10, true, 20);
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
// We added two tables, therefore table.copy on table 0 should work.
int table_src = 0;
@@ -3433,7 +3512,7 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
{
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
// We added one table, therefore table.init on table 0 should work.
int table_index = 0;
@@ -3448,7 +3527,7 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
TestModuleBuilder builder;
builder.AddTable(kWasmAnyRef, 10, true, 20);
builder.AddTable(kWasmAnyRef, 10, true, 20);
- builder.AddPassiveElementSegment();
+ builder.AddPassiveElementSegment(wasm::kWasmFuncRef);
module = builder.module();
// We added two tables, therefore table.init on table 0 should work.
int table_index = 0;
@@ -3727,8 +3806,7 @@ TEST_F(LocalDeclDecoderTest, OneLocal) {
WASM_FEATURE_SCOPE(anyref);
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
ValueType type = kValueTypes[i];
- const byte data[] = {1, 1,
- static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
+ const byte data[] = {1, 1, static_cast<byte>(type.value_type_code())};
BodyLocalDecls decls(zone());
bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
EXPECT_TRUE(result);
@@ -3743,8 +3821,7 @@ TEST_F(LocalDeclDecoderTest, FiveLocals) {
WASM_FEATURE_SCOPE(anyref);
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
ValueType type = kValueTypes[i];
- const byte data[] = {1, 5,
- static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
+ const byte data[] = {1, 5, static_cast<byte>(type.value_type_code())};
BodyLocalDecls decls(zone());
bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
EXPECT_TRUE(result);
@@ -3809,8 +3886,7 @@ TEST_F(LocalDeclDecoderTest, UseEncoder) {
TEST_F(LocalDeclDecoderTest, ExnRef) {
WASM_FEATURE_SCOPE(eh);
ValueType type = kWasmExnRef;
- const byte data[] = {1, 1,
- static_cast<byte>(ValueTypes::ValueTypeCodeFor(type))};
+ const byte data[] = {1, 1, static_cast<byte>(type.value_type_code())};
BodyLocalDecls decls(zone());
bool result = DecodeLocalDecls(&decls, data, data + sizeof(data));
EXPECT_TRUE(result);
diff --git a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc
index f88beef794..68a2bb6ff1 100644
--- a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc
+++ b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc
@@ -130,6 +130,13 @@ struct CheckLEB1 : std::integral_constant<size_t, num> {
#define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data))
+#define EXPECT_FAILURE_WITH_MSG(data, msg) \
+ do { \
+ ModuleResult result = DecodeModule(data, data + sizeof(data)); \
+ EXPECT_FALSE(result.ok()); \
+ EXPECT_THAT(result.error().message(), HasSubstr(msg)); \
+ } while (false)
+
#define EXPECT_OFF_END_FAILURE(data, min) \
do { \
STATIC_ASSERT(min < arraysize(data)); \
@@ -252,6 +259,7 @@ TEST_F(WasmModuleVerifyTest, OneGlobal) {
TEST_F(WasmModuleVerifyTest, AnyRefGlobal) {
WASM_FEATURE_SCOPE(anyref);
+ WASM_FEATURE_SCOPE(bulk_memory);
static const byte data[] = {
// sig#0 ---------------------------------------------------------------
SIGNATURES_SECTION_VOID_VOID,
@@ -265,6 +273,16 @@ TEST_F(WasmModuleVerifyTest, AnyRefGlobal) {
kLocalAnyRef, // local type
0, // immutable
WASM_INIT_EXPR_REF_FUNC(1)), // init
+ SECTION(Element, // section name
+ ENTRY_COUNT(2), // entry count
+ DECLARATIVE, // flags 0
+ kExternalFunction, // type
+ ENTRY_COUNT(1), // func entry count
+ FUNC_INDEX(0), // func index
+ DECLARATIVE_WITH_ELEMENTS, // flags 1
+ kLocalFuncRef, // local type
+ ENTRY_COUNT(1), // func ref count
+ REF_FUNC_ELEMENT(1)), // func ref
TWO_EMPTY_BODIES};
{
@@ -290,6 +308,7 @@ TEST_F(WasmModuleVerifyTest, AnyRefGlobal) {
TEST_F(WasmModuleVerifyTest, FuncRefGlobal) {
WASM_FEATURE_SCOPE(anyref);
+ WASM_FEATURE_SCOPE(bulk_memory);
static const byte data[] = {
// sig#0 ---------------------------------------------------------------
SIGNATURES_SECTION_VOID_VOID,
@@ -303,6 +322,16 @@ TEST_F(WasmModuleVerifyTest, FuncRefGlobal) {
kLocalFuncRef, // local type
0, // immutable
WASM_INIT_EXPR_REF_FUNC(1)), // init
+ SECTION(Element, // section name
+ ENTRY_COUNT(2), // entry count
+ DECLARATIVE, // flags 0
+ kExternalFunction, // type
+ ENTRY_COUNT(1), // func entry count
+ FUNC_INDEX(0), // func index
+ DECLARATIVE_WITH_ELEMENTS, // flags 1
+ kLocalFuncRef, // local type
+ ENTRY_COUNT(1), // func ref count
+ REF_FUNC_ELEMENT(1)), // func ref
TWO_EMPTY_BODIES};
{
// Should decode to two globals.
@@ -695,9 +724,9 @@ TEST_F(WasmModuleVerifyTest, Exception_invalid_attribute) {
}
TEST_F(WasmModuleVerifyTest, ExceptionSectionCorrectPlacement) {
- static const byte data[] = {SECTION(Import, ENTRY_COUNT(0)),
+ static const byte data[] = {SECTION(Memory, ENTRY_COUNT(0)),
SECTION(Exception, ENTRY_COUNT(0)),
- SECTION(Export, ENTRY_COUNT(0))};
+ SECTION(Global, ENTRY_COUNT(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
@@ -705,37 +734,37 @@ TEST_F(WasmModuleVerifyTest, ExceptionSectionCorrectPlacement) {
EXPECT_OK(result);
}
-TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterExport) {
- static const byte data[] = {SECTION(Export, ENTRY_COUNT(0)),
+TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterGlobal) {
+ static const byte data[] = {SECTION(Global, ENTRY_COUNT(0)),
SECTION(Exception, ENTRY_COUNT(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_NOT_OK(result,
- "The Exception section must appear before the Export section");
+ "The Exception section must appear before the Global section");
}
-TEST_F(WasmModuleVerifyTest, ExceptionSectionBeforeGlobal) {
+TEST_F(WasmModuleVerifyTest, ExceptionSectionBeforeMemory) {
static const byte data[] = {SECTION(Exception, ENTRY_COUNT(0)),
- SECTION(Global, ENTRY_COUNT(0))};
+ SECTION(Memory, ENTRY_COUNT(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
ModuleResult result = DecodeModule(data, data + sizeof(data));
- EXPECT_NOT_OK(result, "unexpected section <Global>");
+ EXPECT_NOT_OK(result, "unexpected section <Memory>");
}
-TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterMemoryBeforeGlobal) {
+TEST_F(WasmModuleVerifyTest, ExceptionSectionAfterTableBeforeMemory) {
STATIC_ASSERT(kMemorySectionCode + 1 == kGlobalSectionCode);
- static const byte data[] = {SECTION(Memory, ENTRY_COUNT(0)),
+ static const byte data[] = {SECTION(Table, ENTRY_COUNT(0)),
SECTION(Exception, ENTRY_COUNT(0)),
- SECTION(Global, ENTRY_COUNT(0))};
+ SECTION(Memory, ENTRY_COUNT(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);
WASM_FEATURE_SCOPE(eh);
ModuleResult result = DecodeModule(data, data + sizeof(data));
- EXPECT_NOT_OK(result, "unexpected section <Global>");
+ EXPECT_NOT_OK(result, "unexpected section <Memory>");
}
TEST_F(WasmModuleVerifyTest, ExceptionImport) {
@@ -1493,7 +1522,7 @@ class WasmSignatureDecodeTest : public TestWithZone {
public:
WasmFeatures enabled_features_ = WasmFeatures::None();
- FunctionSig* DecodeSig(const byte* start, const byte* end) {
+ const FunctionSig* DecodeSig(const byte* start, const byte* end) {
return DecodeWasmSignatureForTesting(enabled_features_, zone(), start, end);
}
};
@@ -1502,7 +1531,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_v_v) {
static const byte data[] = {SIG_ENTRY_v_v};
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(0u, sig->parameter_count());
@@ -1514,7 +1543,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_t_v) {
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
ValueTypePair ret_type = kValueTypes[i];
const byte data[] = {SIG_ENTRY_x(ret_type.code)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(0u, sig->parameter_count());
@@ -1528,7 +1557,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_v_t) {
for (size_t i = 0; i < arraysize(kValueTypes); i++) {
ValueTypePair param_type = kValueTypes[i];
const byte data[] = {SIG_ENTRY_v_x(param_type.code)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(1u, sig->parameter_count());
@@ -1544,7 +1573,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_t_t) {
for (size_t j = 0; j < arraysize(kValueTypes); j++) {
ValueTypePair param_type = kValueTypes[j];
const byte data[] = {SIG_ENTRY_x_x(ret_type.code, param_type.code)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(1u, sig->parameter_count());
@@ -1564,7 +1593,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_i_tt) {
ValueTypePair p1_type = kValueTypes[j];
const byte data[] = {
SIG_ENTRY_x_xx(kLocalI32, p0_type.code, p1_type.code)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(2u, sig->parameter_count());
@@ -1584,7 +1613,7 @@ TEST_F(WasmSignatureDecodeTest, Ok_tt_tt) {
ValueTypePair p1_type = kValueTypes[j];
const byte data[] = {SIG_ENTRY_xx_xx(p0_type.code, p1_type.code,
p0_type.code, p1_type.code)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_TRUE(sig != nullptr);
EXPECT_EQ(2u, sig->parameter_count());
@@ -1601,7 +1630,7 @@ TEST_F(WasmSignatureDecodeTest, TooManyParams) {
static const byte data[] = {kWasmFunctionTypeCode,
WASM_I32V_3(kV8MaxWasmFunctionParams + 1),
kLocalI32, 0};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_FALSE(sig != nullptr);
}
@@ -1613,7 +1642,7 @@ TEST_F(WasmSignatureDecodeTest, TooManyReturns) {
enable_mv ? kV8MaxWasmFunctionMultiReturns : kV8MaxWasmFunctionReturns);
byte data[] = {kWasmFunctionTypeCode, 0, WASM_I32V_3(max_return_count + 1),
kLocalI32};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
}
@@ -1626,7 +1655,7 @@ TEST_F(WasmSignatureDecodeTest, Fail_off_end) {
for (int i = 0; i < p + 1; i++) {
// Should fall off the end for all signatures.
- FunctionSig* sig = DecodeSig(data, data + i);
+ const FunctionSig* sig = DecodeSig(data, data + i);
EXPECT_EQ(nullptr, sig);
}
}
@@ -1641,7 +1670,7 @@ TEST_F(WasmSignatureDecodeTest, Fail_anyref_without_flag) {
byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)};
if (i >= arraysize(data)) break;
data[i] = invalid_type;
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
}
@@ -1653,26 +1682,26 @@ TEST_F(WasmSignatureDecodeTest, Fail_invalid_type) {
byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalI32)};
if (i >= arraysize(data)) break;
data[i] = kInvalidType;
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
}
TEST_F(WasmSignatureDecodeTest, Fail_invalid_ret_type1) {
static const byte data[] = {SIG_ENTRY_x_x(kLocalVoid, kLocalI32)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type1) {
static const byte data[] = {SIG_ENTRY_x_x(kLocalI32, kLocalVoid)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
TEST_F(WasmSignatureDecodeTest, Fail_invalid_param_type2) {
static const byte data[] = {SIG_ENTRY_x_xx(kLocalI32, kLocalI32, kLocalVoid)};
- FunctionSig* sig = DecodeSig(data, data + sizeof(data));
+ const FunctionSig* sig = DecodeSig(data, data + sizeof(data));
EXPECT_EQ(nullptr, sig);
}
@@ -1724,12 +1753,22 @@ TEST_F(WasmModuleVerifyTest, SectionWithoutNameLength) {
EXPECT_FAILURE(data);
}
+TEST_F(WasmModuleVerifyTest, EmptyCustomSectionIsInvalid) {
+ // An empty custom section is invalid, because at least one byte for the
+ // length of the custom section name is required.
+ const byte data[] = {
+ 0, // unknown section code.
+ 0 // section length.
+ };
+ EXPECT_FAILURE(data);
+}
+
TEST_F(WasmModuleVerifyTest, TheLoneliestOfValidModulesTheTrulyEmptyOne) {
const byte data[] = {
0, // unknown section code.
- 0, // Empty section name.
- // No section name, no content, nothing but sadness.
- 0, // No section content.
+ 1, // section length, only one byte for the name length.
+ 0, // string length of 0.
+ // Empty section name, no content, nothing but sadness.
};
EXPECT_VERIFIES(data);
}
@@ -2507,7 +2546,7 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegmentWithIndices) {
ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
// table declaration -----------------------------------------------------
SECTION(Table, ENTRY_COUNT(1), kLocalFuncRef, 0, 1),
- // element segments -----------------------------------------------------
+ // element segments ------------------------------------------------------
SECTION(Element, ENTRY_COUNT(1), PASSIVE, kExternalFunction,
ENTRY_COUNT(3), U32V_1(0), U32V_1(0), U32V_1(0)),
// code ------------------------------------------------------------------
@@ -2518,6 +2557,67 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegmentWithIndices) {
EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5);
}
+TEST_F(WasmModuleVerifyTest, DeclarativeElementSegmentFuncRef) {
+ static const byte data[] = {
+ // sig#0 -----------------------------------------------------------------
+ SIGNATURES_SECTION_VOID_VOID,
+ // funcs -----------------------------------------------------------------
+ ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
+ // element segments -----------------------------------------------------
+ SECTION(Element, // section name
+ ENTRY_COUNT(1), // entry count
+ DECLARATIVE_WITH_ELEMENTS, // flags
+ kLocalFuncRef, // local type
+ U32V_1(0)), // func ref count
+ // code ------------------------------------------------------------------
+ ONE_EMPTY_BODY};
+ EXPECT_FAILURE(data);
+ WASM_FEATURE_SCOPE(bulk_memory);
+ EXPECT_FAILURE(data);
+ WASM_FEATURE_SCOPE(anyref);
+ EXPECT_VERIFIES(data);
+}
+
+TEST_F(WasmModuleVerifyTest, DeclarativeElementSegmentWithInvalidIndex) {
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ static const byte data[] = {
+ // sig#0 -----------------------------------------------------------------
+ SIGNATURES_SECTION_VOID_VOID,
+ // funcs -----------------------------------------------------------------
+ ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
+ // element segments -----------------------------------------------------
+ SECTION(Element, // section name
+ ENTRY_COUNT(1), // entry count
+ DECLARATIVE, // flags
+ kExternalFunction, // type
+ ENTRY_COUNT(2), // func index count
+ U32V_1(0), // func index
+ U32V_1(1)), // func index
+ // code ------------------------------------------------------------------
+ ONE_EMPTY_BODY};
+ EXPECT_FAILURE_WITH_MSG(data, "element function index 1 out of bounds");
+}
+
+TEST_F(WasmModuleVerifyTest, DeclarativeElementSegmentMissingForGlobal) {
+ WASM_FEATURE_SCOPE(bulk_memory);
+ WASM_FEATURE_SCOPE(anyref);
+ static const byte data[] = {
+ // sig#0 -----------------------------------------------------------------
+ SIGNATURES_SECTION_VOID_VOID,
+ // funcs -----------------------------------------------------------------
+ ONE_EMPTY_FUNCTION(SIG_INDEX(0)),
+ // global definitions ----------------------------------------------------
+ SECTION(Global, // section name
+ ENTRY_COUNT(1), // entry count
+ kLocalAnyRef, // local type
+ 0, // immutable
+ WASM_INIT_EXPR_REF_FUNC(0)), // init
+ // code ------------------------------------------------------------------
+ ONE_EMPTY_BODY};
+ EXPECT_FAILURE_WITH_MSG(data, "undeclared reference to function");
+}
+
TEST_F(WasmModuleVerifyTest, DataCountSectionCorrectPlacement) {
static const byte data[] = {SECTION(Element, ENTRY_COUNT(0)),
SECTION(DataCount, ENTRY_COUNT(0)),
diff --git a/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc b/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
index 4b9f78dfdc..0b8cf6d11d 100644
--- a/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
+++ b/deps/v8/test/unittests/wasm/wasm-compiler-unittest.cc
@@ -21,9 +21,9 @@ TEST_F(WasmCallDescriptorTest, TestAnyRefIsGrouped) {
ValueType params[kMaxCount];
for (size_t i = 0; i < kMaxCount; i += 2) {
- params[i] = ValueType::kWasmAnyRef;
+ params[i] = kWasmAnyRef;
CHECK_LT(i + 1, kMaxCount);
- params[i + 1] = ValueType::kWasmI32;
+ params[i + 1] = kWasmI32;
}
for (size_t count = 1; count <= kMaxCount; ++count) {