diff options
Diffstat (limited to 'deps/v8/test/cctest/test-debug.cc')
-rw-r--r-- | deps/v8/test/cctest/test-debug.cc | 220 |
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" |