aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-debug.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/test-debug.cc')
-rw-r--r--deps/v8/test/cctest/test-debug.cc220
1 files changed, 168 insertions, 52 deletions
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 34b2e0fef4..82ebc8ca46 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -27,18 +27,18 @@
#include <stdlib.h>
-#include "src/v8.h"
+#include "src/init/v8.h"
-#include "src/api-inl.h"
-#include "src/compilation-cache.h"
+#include "src/api/api-inl.h"
+#include "src/codegen/compilation-cache.h"
#include "src/debug/debug-interface.h"
#include "src/debug/debug.h"
-#include "src/deoptimizer.h"
-#include "src/frames.h"
-#include "src/objects-inl.h"
+#include "src/deoptimizer/deoptimizer.h"
+#include "src/execution/frames.h"
+#include "src/objects/objects-inl.h"
#include "src/snapshot/natives.h"
#include "src/snapshot/snapshot.h"
-#include "src/utils.h"
+#include "src/utils/utils.h"
#include "test/cctest/cctest.h"
using ::v8::internal::Handle;
@@ -84,7 +84,7 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun,
const char* condition = nullptr) {
i::Handle<i::JSFunction> function =
i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun));
- position += function->shared()->StartPosition();
+ position += function->shared().StartPosition();
static int break_point_index = 0;
i::Isolate* isolate = function->GetIsolate();
i::Handle<i::String> condition_string =
@@ -94,7 +94,8 @@ static i::Handle<i::BreakPoint> SetBreakPoint(v8::Local<v8::Function> fun,
i::Handle<i::BreakPoint> break_point =
isolate->factory()->NewBreakPoint(++break_point_index, condition_string);
- debug->SetBreakPoint(function, break_point, &position);
+ debug->SetBreakpoint(handle(function->shared(), isolate), break_point,
+ &position);
return break_point;
}
@@ -167,7 +168,7 @@ void CheckDebuggerUnloaded() {
HeapIterator iterator(CcTest::heap());
for (HeapObject obj = iterator.next(); !obj.is_null();
obj = iterator.next()) {
- CHECK(!obj->IsDebugInfo());
+ CHECK(!obj.IsDebugInfo());
}
}
@@ -568,6 +569,110 @@ TEST(BreakPointBuiltin) {
CheckDebuggerUnloaded();
}
+TEST(BreakPointApiIntrinsics) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ DebugEventCounter delegate;
+ v8::debug::SetDebugDelegate(env->GetIsolate(), &delegate);
+
+ v8::Local<v8::Function> builtin;
+
+ // === Test that using API-exposed functions won't trigger breakpoints ===
+ {
+ v8::Local<v8::Function> weakmap_get =
+ CompileRun("WeakMap.prototype.get").As<v8::Function>();
+ SetBreakPoint(weakmap_get, 0);
+ v8::Local<v8::Function> weakmap_set =
+ CompileRun("WeakMap.prototype.set").As<v8::Function>();
+ SetBreakPoint(weakmap_set, 0);
+
+ // Run with breakpoint.
+ break_point_hit_count = 0;
+ CompileRun("var w = new WeakMap(); w.set(w, 1); w.get(w);");
+ CHECK_EQ(2, break_point_hit_count);
+
+ break_point_hit_count = 0;
+ v8::Local<v8::debug::WeakMap> weakmap =
+ v8::debug::WeakMap::New(env->GetIsolate());
+ CHECK(!weakmap->Set(env.local(), weakmap, v8_num(1)).IsEmpty());
+ CHECK(!weakmap->Get(env.local(), weakmap).IsEmpty());
+ CHECK_EQ(0, break_point_hit_count);
+ }
+
+ {
+ v8::Local<v8::Function> object_to_string =
+ CompileRun("Object.prototype.toString").As<v8::Function>();
+ SetBreakPoint(object_to_string, 0);
+
+ // Run with breakpoint.
+ break_point_hit_count = 0;
+ CompileRun("var o = {}; o.toString();");
+ CHECK_EQ(1, break_point_hit_count);
+
+ break_point_hit_count = 0;
+ v8::Local<v8::Object> object = v8::Object::New(env->GetIsolate());
+ CHECK(!object->ObjectProtoToString(env.local()).IsEmpty());
+ CHECK_EQ(0, break_point_hit_count);
+ }
+
+ {
+ v8::Local<v8::Function> map_set =
+ CompileRun("Map.prototype.set").As<v8::Function>();
+ v8::Local<v8::Function> map_get =
+ CompileRun("Map.prototype.get").As<v8::Function>();
+ v8::Local<v8::Function> map_has =
+ CompileRun("Map.prototype.has").As<v8::Function>();
+ v8::Local<v8::Function> map_delete =
+ CompileRun("Map.prototype.delete").As<v8::Function>();
+ SetBreakPoint(map_set, 0);
+ SetBreakPoint(map_get, 0);
+ SetBreakPoint(map_has, 0);
+ SetBreakPoint(map_delete, 0);
+
+ // Run with breakpoint.
+ break_point_hit_count = 0;
+ CompileRun(
+ "var m = new Map(); m.set(m, 1); m.get(m); m.has(m); m.delete(m);");
+ CHECK_EQ(4, break_point_hit_count);
+
+ break_point_hit_count = 0;
+ v8::Local<v8::Map> map = v8::Map::New(env->GetIsolate());
+ CHECK(!map->Set(env.local(), map, v8_num(1)).IsEmpty());
+ CHECK(!map->Get(env.local(), map).IsEmpty());
+ CHECK(map->Has(env.local(), map).FromJust());
+ CHECK(map->Delete(env.local(), map).FromJust());
+ CHECK_EQ(0, break_point_hit_count);
+ }
+
+ {
+ v8::Local<v8::Function> set_add =
+ CompileRun("Set.prototype.add").As<v8::Function>();
+ v8::Local<v8::Function> set_get =
+ CompileRun("Set.prototype.has").As<v8::Function>();
+ v8::Local<v8::Function> set_delete =
+ CompileRun("Set.prototype.delete").As<v8::Function>();
+ SetBreakPoint(set_add, 0);
+ SetBreakPoint(set_get, 0);
+ SetBreakPoint(set_delete, 0);
+
+ // Run with breakpoint.
+ break_point_hit_count = 0;
+ CompileRun("var s = new Set(); s.add(s); s.has(s); s.delete(s);");
+ CHECK_EQ(3, break_point_hit_count);
+
+ break_point_hit_count = 0;
+ v8::Local<v8::Set> set = v8::Set::New(env->GetIsolate());
+ CHECK(!set->Add(env.local(), set).IsEmpty());
+ CHECK(set->Has(env.local(), set).FromJust());
+ CHECK(set->Delete(env.local(), set).FromJust());
+ CHECK_EQ(0, break_point_hit_count);
+ }
+
+ v8::debug::SetDebugDelegate(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded();
+}
+
TEST(BreakPointJSBuiltin) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -710,6 +815,7 @@ TEST(BreakPointInlinedBuiltin) {
builtin = CompileRun("Math.sin").As<v8::Function>();
CompileRun("function test(x) { return 1 + Math.sin(x) }");
CompileRun(
+ "%PrepareFunctionForOptimization(test);"
"test(0.5); test(0.6);"
"%OptimizeFunctionOnNextCall(test); test(0.7);");
CHECK_EQ(0, break_point_hit_count);
@@ -722,7 +828,9 @@ TEST(BreakPointInlinedBuiltin) {
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
- CompileRun("%OptimizeFunctionOnNextCall(test);");
+ CompileRun(
+ "%PrepareFunctionForOptimization(test);"
+ "%OptimizeFunctionOnNextCall(test);");
ExpectBoolean("test(0.3) < 2", true);
CHECK_EQ(3, break_point_hit_count);
@@ -755,6 +863,7 @@ TEST(BreakPointInlineBoundBuiltin) {
.As<v8::Function>();
CompileRun("function test(x) { return 'a' + boundrepeat(x) }");
CompileRun(
+ "%PrepareFunctionForOptimization(test);"
"test(4); test(5);"
"%OptimizeFunctionOnNextCall(test); test(6);");
CHECK_EQ(0, break_point_hit_count);
@@ -767,7 +876,9 @@ TEST(BreakPointInlineBoundBuiltin) {
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
- CompileRun("%OptimizeFunctionOnNextCall(test);");
+ CompileRun(
+ "%PrepareFunctionForOptimization(f);"
+ "%OptimizeFunctionOnNextCall(test);");
CompileRun("test(8);");
CHECK_EQ(3, break_point_hit_count);
@@ -797,6 +908,7 @@ TEST(BreakPointInlinedConstructorBuiltin) {
builtin = CompileRun("Promise").As<v8::Function>();
CompileRun("function test(x) { return new Promise(()=>x); }");
CompileRun(
+ "%PrepareFunctionForOptimization(test);"
"test(4); test(5);"
"%OptimizeFunctionOnNextCall(test); test(6);");
CHECK_EQ(0, break_point_hit_count);
@@ -809,7 +921,9 @@ TEST(BreakPointInlinedConstructorBuiltin) {
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
- CompileRun("%OptimizeFunctionOnNextCall(test);");
+ CompileRun(
+ "%PrepareFunctionForOptimization(f);"
+ "%OptimizeFunctionOnNextCall(test);");
CompileRun("test(8);");
CHECK_EQ(3, break_point_hit_count);
@@ -840,6 +954,7 @@ TEST(BreakPointBuiltinConcurrentOpt) {
CompileRun("function test(x) { return 1 + Math.sin(x) }");
// Trigger concurrent compile job. It is suspended until unblock.
CompileRun(
+ "%PrepareFunctionForOptimization(test);"
"test(0.5); test(0.6);"
"%OptimizeFunctionOnNextCall(test, 'concurrent'); test(0.7);");
CHECK_EQ(0, break_point_hit_count);
@@ -878,6 +993,7 @@ TEST(BreakPointBuiltinTFOperator) {
builtin = CompileRun("String.prototype.indexOf").As<v8::Function>();
CompileRun("function test(x) { return 1 + 'foo'.indexOf(x) }");
CompileRun(
+ "%PrepareFunctionForOptimization(f);"
"test('a'); test('b');"
"%OptimizeFunctionOnNextCall(test); test('c');");
CHECK_EQ(0, break_point_hit_count);
@@ -890,7 +1006,9 @@ TEST(BreakPointBuiltinTFOperator) {
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
- CompileRun("%OptimizeFunctionOnNextCall(test);");
+ CompileRun(
+ "%PrepareFunctionForOptimization(f);"
+ "%OptimizeFunctionOnNextCall(test);");
CompileRun("test('e');");
CHECK_EQ(3, break_point_hit_count);
@@ -1210,7 +1328,9 @@ TEST(BreakPointInlineApiFunction) {
function_template->GetFunction(env.local()).ToLocalChecked();
env->Global()->Set(env.local(), v8_str("f"), function).ToChecked();
- CompileRun("function g() { return 1 + f(); }");
+ CompileRun(
+ "function g() { return 1 + f(); };"
+ "%PrepareFunctionForOptimization(g);");
// === Test simple builtin ===
break_point_hit_count = 0;
@@ -1381,6 +1501,7 @@ TEST(BreakPointInlining) {
CompileRun("function f(x) { return x*2; } f").As<v8::Function>();
CompileRun("function test(x) { return 1 + f(x) }");
CompileRun(
+ "%PrepareFunctionForOptimization(test);"
"test(0.5); test(0.6);"
"%OptimizeFunctionOnNextCall(test); test(0.7);");
CHECK_EQ(0, break_point_hit_count);
@@ -1393,7 +1514,9 @@ TEST(BreakPointInlining) {
CHECK_EQ(2, break_point_hit_count);
// Re-optimize.
- CompileRun("%OptimizeFunctionOnNextCall(test);");
+ CompileRun(
+ "%PrepareFunctionForOptimization(test);"
+ "%OptimizeFunctionOnNextCall(test);");
CompileRun("test(0.3);");
CHECK_EQ(3, break_point_hit_count);
@@ -2690,7 +2813,7 @@ TEST(PauseInScript) {
// Set breakpoint in the script.
i::Handle<i::Script> i_script(
- i::Script::cast(v8::Utils::OpenHandle(*script)->shared()->script()),
+ i::Script::cast(v8::Utils::OpenHandle(*script)->shared().script()),
isolate);
i::Handle<i::String> condition = isolate->factory()->empty_string();
int position = 0;
@@ -3036,7 +3159,7 @@ class EmptyExternalStringResource : public v8::String::ExternalStringResource {
EmptyExternalStringResource() { empty_[0] = 0; }
~EmptyExternalStringResource() override = default;
size_t length() const override { return empty_.length(); }
- const uint16_t* data() const override { return empty_.start(); }
+ const uint16_t* data() const override { return empty_.begin(); }
private:
::v8::internal::EmbeddedVector<uint16_t, 1> empty_;
@@ -3072,11 +3195,11 @@ TEST(DebugScriptLineEndsAreAscending) {
v8::internal::Script::InitLineEnds(script);
v8::internal::FixedArray ends =
v8::internal::FixedArray::cast(script->line_ends());
- CHECK_GT(ends->length(), 0);
+ CHECK_GT(ends.length(), 0);
int prev_end = -1;
- for (int j = 0; j < ends->length(); j++) {
- const int curr_end = v8::internal::Smi::ToInt(ends->get(j));
+ for (int j = 0; j < ends.length(); j++) {
+ const int curr_end = v8::internal::Smi::ToInt(ends.get(j));
CHECK_GT(curr_end, prev_end);
prev_end = curr_end;
}
@@ -3449,7 +3572,7 @@ static void TestDebugBreakInLoop(const char* loop_head,
SNPrintF(buffer, "function f() {%s%s%s}", loop_head, loop_bodies[i],
loop_tail);
- i::PrintF("%s\n", buffer.start());
+ i::PrintF("%s\n", buffer.begin());
for (int j = 0; j < 3; j++) {
break_point_hit_count_deoptimize = j;
@@ -3462,7 +3585,7 @@ static void TestDebugBreakInLoop(const char* loop_head,
terminate_after_max_break_point_hit = true;
// Function with infinite loop.
- CompileRun(buffer.start());
+ CompileRun(buffer.begin());
// Set the debug break to enter the debugger as soon as possible.
v8::debug::SetBreakOnNextFunctionCall(CcTest::isolate());
@@ -3575,7 +3698,7 @@ class DebugBreakInlineListener : public v8::debug::DebugDelegate {
const std::vector<v8::debug::BreakpointId>&
inspector_break_points_hit) override {
int expected_frame_count = 4;
- int expected_line_number[] = {1, 4, 7, 12};
+ int expected_line_number[] = {1, 4, 7, 13};
int frame_count = 0;
auto iterator = v8::debug::StackTraceIterator::Create(CcTest::isolate());
@@ -3593,18 +3716,19 @@ TEST(DebugBreakInline) {
v8::HandleScope scope(env->GetIsolate());
v8::Local<v8::Context> context = env.local();
const char* source =
- "function debug(b) { \n"
- " if (b) debugger; \n"
- "} \n"
- "function f(b) { \n"
- " debug(b) \n"
- "}; \n"
- "function g(b) { \n"
- " f(b); \n"
- "}; \n"
- "g(false); \n"
- "g(false); \n"
- "%OptimizeFunctionOnNextCall(g); \n"
+ "function debug(b) { \n"
+ " if (b) debugger; \n"
+ "} \n"
+ "function f(b) { \n"
+ " debug(b) \n"
+ "}; \n"
+ "function g(b) { \n"
+ " f(b); \n"
+ "}; \n"
+ "%PrepareFunctionForOptimization(g); \n"
+ "g(false); \n"
+ "g(false); \n"
+ "%OptimizeFunctionOnNextCall(g); \n"
"g(true);";
DebugBreakInlineListener delegate;
v8::debug::SetDebugDelegate(env->GetIsolate(), &delegate);
@@ -4047,8 +4171,6 @@ UNINITIALIZED_TEST(DebugSetOutOfMemoryListener) {
}
TEST(DebugCoverage) {
- // Coverage needs feedback vectors.
- if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -4103,8 +4225,6 @@ v8::debug::Coverage::ScriptData GetScriptDataAndDeleteCoverage(
} // namespace
TEST(DebugCoverageWithCoverageOutOfScope) {
- // Coverage needs feedback vectors.
- if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -4175,8 +4295,6 @@ v8::debug::Coverage::FunctionData GetFunctionDataAndDeleteCoverage(
} // namespace
TEST(DebugCoverageWithScriptDataOutOfScope) {
- // Coverage needs feedback vectors.
- if (i::FLAG_lite_mode) return;
i::FLAG_always_opt = false;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -4207,8 +4325,8 @@ TEST(BuiltinsExceptionPrediction) {
bool fail = false;
for (int i = 0; i < i::Builtins::builtin_count; i++) {
i::Code builtin = builtins->builtin(i);
- if (builtin->kind() != i::Code::BUILTIN) continue;
- auto prediction = builtin->GetBuiltinCatchPrediction();
+ if (builtin.kind() != i::Code::BUILTIN) continue;
+ auto prediction = builtin.GetBuiltinCatchPrediction();
USE(prediction);
}
CHECK(!fail);
@@ -4253,7 +4371,7 @@ TEST(DebugEvaluateNoSideEffect) {
i::HeapIterator iterator(isolate->heap());
for (i::HeapObject obj = iterator.next(); !obj.is_null();
obj = iterator.next()) {
- if (!obj->IsJSFunction()) continue;
+ if (!obj.IsJSFunction()) continue;
i::JSFunction fun = i::JSFunction::cast(obj);
all_functions.emplace_back(fun, isolate);
}
@@ -4279,7 +4397,7 @@ i::MaybeHandle<i::Script> FindScript(
Handle<i::String> i_name =
isolate->factory()->NewStringFromAsciiChecked(name);
for (const auto& script : scripts) {
- if (!script->name()->IsString()) continue;
+ if (!script->name().IsString()) continue;
if (i_name->Equals(i::String::cast(script->name()))) return script;
}
return i::MaybeHandle<i::Script>();
@@ -4307,11 +4425,11 @@ UNINITIALIZED_TEST(LoadedAtStartupScripts) {
i::Script::Iterator iterator(i_isolate);
for (i::Script script = iterator.Next(); !script.is_null();
script = iterator.Next()) {
- if (script->type() == i::Script::TYPE_NATIVE &&
- script->name()->IsUndefined(i_isolate)) {
+ if (script.type() == i::Script::TYPE_NATIVE &&
+ script.name().IsUndefined(i_isolate)) {
continue;
}
- ++count_by_type[script->type()];
+ ++count_by_type[script.type()];
scripts.emplace_back(script, i_isolate);
}
}
@@ -4368,7 +4486,7 @@ TEST(SourceInfo) {
v8::Local<v8::Script> v8_script =
v8::Script::Compile(env.local(), v8_str(source)).ToLocalChecked();
i::Handle<i::Script> i_script(
- i::Script::cast(v8::Utils::OpenHandle(*v8_script)->shared()->script()),
+ i::Script::cast(v8::Utils::OpenHandle(*v8_script)->shared().script()),
CcTest::i_isolate());
v8::Local<v8::debug::Script> script =
v8::ToApiHandle<v8::debug::Script>(i_script);
@@ -4527,8 +4645,6 @@ TEST(GetPrivateFields) {
v8::internal::Isolate* isolate = CcTest::i_isolate();
v8::HandleScope scope(v8_isolate);
v8::Local<v8::Context> context = env.local();
- v8::internal::FLAG_harmony_class_fields = true;
- v8::internal::FLAG_harmony_private_fields = true;
v8::Local<v8::String> source = v8_str(
"var X = class {\n"
" #foo = 1;\n"