OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "include/dart_debugger_api.h" | 5 #include "include/dart_debugger_api.h" |
6 #include "include/dart_mirrors_api.h" | 6 #include "include/dart_mirrors_api.h" |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
9 #include "vm/thread.h" | 9 #include "vm/thread.h" |
10 #include "vm/unit_test.h" | 10 #include "vm/unit_test.h" |
11 | 11 |
12 namespace dart { | 12 namespace dart { |
13 | 13 |
| 14 DECLARE_FLAG(int, optimization_counter_threshold); |
| 15 DECLARE_FLAG(bool, use_osr); |
| 16 |
14 static bool breakpoint_hit = false; | 17 static bool breakpoint_hit = false; |
15 static int breakpoint_hit_counter = 0; | 18 static int breakpoint_hit_counter = 0; |
16 static Dart_Handle script_lib = NULL; | 19 static Dart_Handle script_lib = NULL; |
17 | 20 |
18 static const bool verbose = true; | 21 static const bool verbose = true; |
19 | 22 |
20 static void LoadScript(const char* source) { | 23 static void LoadScript(const char* source) { |
21 script_lib = TestCase::LoadTestScript(source, NULL); | 24 script_lib = TestCase::LoadTestScript(source, NULL); |
22 EXPECT_VALID(script_lib); | 25 EXPECT_VALID(script_lib); |
23 } | 26 } |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 LoadScript(kScriptChars); | 328 LoadScript(kScriptChars); |
326 Dart_SetBreakpointHandler(&TestBreakpointHandler); | 329 Dart_SetBreakpointHandler(&TestBreakpointHandler); |
327 SetBreakpointAtEntry("A", "foo"); | 330 SetBreakpointAtEntry("A", "foo"); |
328 | 331 |
329 breakpoint_hit = false; | 332 breakpoint_hit = false; |
330 Dart_Handle retval = Invoke("main"); | 333 Dart_Handle retval = Invoke("main"); |
331 EXPECT_VALID(retval); | 334 EXPECT_VALID(retval); |
332 EXPECT(breakpoint_hit == true); | 335 EXPECT(breakpoint_hit == true); |
333 } | 336 } |
334 | 337 |
| 338 static const int stack_buffer_size = 1024; |
| 339 static char stack_buffer[stack_buffer_size]; |
| 340 |
| 341 static void SaveStackTrace(Dart_StackTrace trace) { |
| 342 Dart_ActivationFrame frame; |
| 343 Dart_Handle func_name; |
| 344 |
| 345 char* buffer = stack_buffer; |
| 346 int buffer_size = stack_buffer_size; |
| 347 |
| 348 intptr_t trace_len; |
| 349 EXPECT_VALID(Dart_StackTraceLength(trace, &trace_len)); |
| 350 |
| 351 for (intptr_t frame_index = 0; frame_index < trace_len; frame_index++) { |
| 352 EXPECT_VALID(Dart_GetActivationFrame(trace, frame_index, &frame)); |
| 353 EXPECT_VALID(Dart_ActivationFrameInfo(frame, &func_name, |
| 354 NULL, NULL, NULL)); |
| 355 int pos = OS::SNPrint(buffer, buffer_size, "[%" Pd "] %s { ", |
| 356 frame_index, ToCString(func_name)); |
| 357 buffer += pos; |
| 358 buffer_size -= pos; |
| 359 |
| 360 Dart_Handle locals = Dart_GetLocalVariables(frame); |
| 361 EXPECT_VALID(locals); |
| 362 intptr_t list_length = 0; |
| 363 EXPECT_VALID(Dart_ListLength(locals, &list_length)); |
| 364 |
| 365 for (intptr_t i = 0; i + 1 < list_length; i += 2) { |
| 366 Dart_Handle name = Dart_ListGetAt(locals, i); |
| 367 EXPECT_VALID(name); |
| 368 EXPECT(Dart_IsString(name)); |
| 369 |
| 370 Dart_Handle value = Dart_ListGetAt(locals, i + 1); |
| 371 EXPECT_VALID(value); |
| 372 Dart_Handle value_str = Dart_ToString(value); |
| 373 EXPECT_VALID(value_str); |
| 374 |
| 375 const char* name_cstr = NULL; |
| 376 const char* value_cstr = NULL; |
| 377 EXPECT_VALID(Dart_StringToCString(name, &name_cstr)); |
| 378 EXPECT_VALID(Dart_StringToCString(value_str, &value_cstr)); |
| 379 pos = OS::SNPrint(buffer, buffer_size, "%s = %s ", |
| 380 name_cstr, value_cstr); |
| 381 buffer += pos; |
| 382 buffer_size -= pos; |
| 383 } |
| 384 pos = OS::SNPrint(buffer, buffer_size, "}\n"); |
| 385 buffer += pos; |
| 386 buffer_size -= pos; |
| 387 } |
| 388 } |
| 389 |
| 390 |
| 391 static void InspectOptimizedStack_Breakpoint(Dart_IsolateId isolate_id, |
| 392 const Dart_CodeLocation& loc) { |
| 393 Dart_StackTrace trace; |
| 394 Dart_GetStackTrace(&trace); |
| 395 SaveStackTrace(trace); |
| 396 } |
| 397 |
| 398 |
| 399 static void InspectStackTest(bool optimize) { |
| 400 const char* kScriptChars = |
| 401 "void breakpointNow() {\n" |
| 402 "}\n" |
| 403 "void helper(int a, int b, bool stop) {\n" |
| 404 " if (b == 99 && stop) {\n" |
| 405 " breakpointNow();\n" |
| 406 " }\n" |
| 407 " int c = a*b;\n" |
| 408 " return c;\n" |
| 409 "}\n" |
| 410 "int anotherMiddleMan(int one, int two, bool stop) {\n" |
| 411 " return helper(one, two, stop);\n" |
| 412 "}\n" |
| 413 "int middleMan(int x, int limit, bool stop) {\n" |
| 414 " int value = 0;\n" |
| 415 " for (int i = 0; i < limit; i++) {\n" |
| 416 " value += anotherMiddleMan(x, i, stop);\n" |
| 417 " }\n" |
| 418 " return value;\n" |
| 419 "}\n" |
| 420 "int test(bool stop, int limit) {\n" |
| 421 " return middleMan(5, limit, stop);\n" |
| 422 "}\n"; |
| 423 |
| 424 LoadScript(kScriptChars); |
| 425 |
| 426 // Save/restore some compiler flags. |
| 427 Dart_Handle dart_args[2]; |
| 428 int saved_threshold = FLAG_optimization_counter_threshold; |
| 429 const int kLowThreshold = 100; |
| 430 const int kHighThreshold = 10000; |
| 431 bool saved_osr = FLAG_use_osr; |
| 432 FLAG_use_osr = false; |
| 433 |
| 434 // Set up the breakpoint. |
| 435 Dart_SetPausedEventHandler(InspectOptimizedStack_Breakpoint); |
| 436 SetBreakpointAtEntry("", "breakpointNow"); |
| 437 |
| 438 if (optimize) { |
| 439 // Warm up the code to make sure it gets optimized. We ignore any |
| 440 // breakpoints that get hit during warm-up. |
| 441 FLAG_optimization_counter_threshold = kLowThreshold; |
| 442 dart_args[0] = Dart_False(); |
| 443 dart_args[1] = Dart_NewInteger(kLowThreshold); |
| 444 EXPECT_VALID(Dart_Invoke(script_lib, NewString("test"), 2, dart_args)); |
| 445 } else { |
| 446 // Try to ensure that none of the test code gets optimized. |
| 447 FLAG_optimization_counter_threshold = kHighThreshold; |
| 448 } |
| 449 |
| 450 // Run the code and inspect the stack. |
| 451 stack_buffer[0] = '\0'; |
| 452 dart_args[0] = Dart_True(); |
| 453 dart_args[1] = Dart_NewInteger(kLowThreshold); |
| 454 EXPECT_VALID(Dart_Invoke(script_lib, NewString("test"), 2, dart_args)); |
| 455 if (optimize) { |
| 456 // Note that several variables have the value 'null' in the |
| 457 // optimized case. This is because these values were determined |
| 458 // to be dead by the optimizing compiler and their values were not |
| 459 // preserved by the deopt information. |
| 460 EXPECT_STREQ("[0] breakpointNow { }\n" |
| 461 "[1] helper { a = 5 b = 99 stop = null }\n" |
| 462 "[2] anotherMiddleMan { one = null two = null stop = null }\n" |
| 463 "[3] middleMan { x = 5 limit = 100 stop = true value = 24255" |
| 464 " i = 99 }\n" |
| 465 "[4] test { stop = true limit = 100 }\n", |
| 466 stack_buffer); |
| 467 } else { |
| 468 EXPECT_STREQ("[0] breakpointNow { }\n" |
| 469 "[1] helper { a = 5 b = 99 stop = true }\n" |
| 470 "[2] anotherMiddleMan { one = 5 two = 99 stop = true }\n" |
| 471 "[3] middleMan { x = 5 limit = 100 stop = true value = 24255" |
| 472 " i = 99 }\n" |
| 473 "[4] test { stop = true limit = 100 }\n", |
| 474 stack_buffer); |
| 475 } |
| 476 |
| 477 FLAG_optimization_counter_threshold = saved_threshold; |
| 478 FLAG_use_osr = saved_osr; |
| 479 } |
| 480 |
| 481 |
| 482 TEST_CASE(Debug_InspectStack_NotOptimized) { |
| 483 InspectStackTest(false); |
| 484 } |
| 485 |
| 486 |
| 487 TEST_CASE(Debug_InspectStack_Optimized) { |
| 488 InspectStackTest(true); |
| 489 } |
| 490 |
335 | 491 |
336 void TestStepOutHandler(Dart_IsolateId isolate_id, | 492 void TestStepOutHandler(Dart_IsolateId isolate_id, |
337 const Dart_CodeLocation& location) { | 493 const Dart_CodeLocation& location) { |
338 Dart_StackTrace trace; | 494 Dart_StackTrace trace; |
339 Dart_GetStackTrace(&trace); | 495 Dart_GetStackTrace(&trace); |
340 const char* expected_bpts[] = {"f1", "foo", "main"}; | 496 const char* expected_bpts[] = {"f1", "foo", "main"}; |
341 const intptr_t expected_bpts_length = ARRAY_SIZE(expected_bpts); | 497 const intptr_t expected_bpts_length = ARRAY_SIZE(expected_bpts); |
342 intptr_t trace_len; | 498 intptr_t trace_len; |
343 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); | 499 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); |
344 EXPECT_VALID(res); | 500 EXPECT_VALID(res); |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1765 | 1921 |
1766 Dart_Handle list_type = Dart_InstanceGetType(list_access_test_obj); | 1922 Dart_Handle list_type = Dart_InstanceGetType(list_access_test_obj); |
1767 Dart_Handle super_type = Dart_GetSupertype(list_type); | 1923 Dart_Handle super_type = Dart_GetSupertype(list_type); |
1768 EXPECT(!Dart_IsError(super_type)); | 1924 EXPECT(!Dart_IsError(super_type)); |
1769 super_type = Dart_GetSupertype(super_type); | 1925 super_type = Dart_GetSupertype(super_type); |
1770 EXPECT(!Dart_IsError(super_type)); | 1926 EXPECT(!Dart_IsError(super_type)); |
1771 EXPECT(super_type == Dart_Null()); | 1927 EXPECT(super_type == Dart_Null()); |
1772 } | 1928 } |
1773 | 1929 |
1774 } // namespace dart | 1930 } // namespace dart |
OLD | NEW |