OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/dart_api_impl.h" | 5 #include "vm/dart_api_impl.h" |
6 #include "vm/dart_api_message.h" | 6 #include "vm/dart_api_message.h" |
7 #include "vm/debugger.h" | 7 #include "vm/debugger.h" |
8 #include "vm/message.h" | 8 #include "vm/message.h" |
9 #include "vm/unit_test.h" | 9 #include "vm/unit_test.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 #ifndef PRODUCT | 13 #ifndef PRODUCT |
14 | 14 |
| 15 DECLARE_FLAG(bool, background_compilation); |
| 16 DECLARE_FLAG(bool, enable_inlining_annotations); |
| 17 DECLARE_FLAG(bool, prune_dead_locals); |
15 DECLARE_FLAG(bool, remove_script_timestamps_for_test); | 18 DECLARE_FLAG(bool, remove_script_timestamps_for_test); |
16 DECLARE_FLAG(bool, trace_rewind); | 19 DECLARE_FLAG(bool, trace_rewind); |
| 20 DECLARE_FLAG(int, optimization_counter_threshold); |
17 | 21 |
18 // Search for the formatted string in buffer. | 22 // Search for the formatted string in buffer. |
19 // | 23 // |
20 // TODO(turnidge): This function obscures the line number of failing | 24 // TODO(turnidge): This function obscures the line number of failing |
21 // EXPECTs. Rework this. | 25 // EXPECTs. Rework this. |
22 static void ExpectSubstringF(const char* buff, const char* fmt, ...) { | 26 static void ExpectSubstringF(const char* buff, const char* fmt, ...) { |
23 va_list args; | 27 va_list args; |
24 va_start(args, fmt); | 28 va_start(args, fmt); |
25 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); | 29 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
26 va_end(args); | 30 va_end(args); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 // at some point. | 263 // at some point. |
260 I->set_is_runnable(true); | 264 I->set_is_runnable(true); |
261 SendResumeMessage(I); | 265 SendResumeMessage(I); |
262 I->PauseEventHandler(); | 266 I->PauseEventHandler(); |
263 } | 267 } |
264 } | 268 } |
265 | 269 |
266 | 270 |
267 TEST_CASE(Debugger_RewindOneFrame_Unoptimized) { | 271 TEST_CASE(Debugger_RewindOneFrame_Unoptimized) { |
268 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); | 272 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); |
| 273 |
| 274 // These variables are global state used by RewindOnce. |
269 saw_paused_event = false; | 275 saw_paused_event = false; |
270 rewind_frame_index = "1"; | 276 rewind_frame_index = "1"; |
271 | 277 |
272 const char* kScriptChars = | 278 const char* kScriptChars = |
273 "import 'dart:developer';\n" | 279 "import 'dart:developer';\n" |
274 "\n" | 280 "\n" |
275 "var msg = new StringBuffer();\n" | 281 "var msg = new StringBuffer();\n" |
276 "\n" | 282 "\n" |
277 "foo() {\n" | 283 "foo() {\n" |
278 " msg.write('enter(foo) ');\n" | 284 " msg.write('enter(foo) ');\n" |
(...skipping 17 matching lines...) Expand all Loading... |
296 EXPECT(Dart_IsString(result)); | 302 EXPECT(Dart_IsString(result)); |
297 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); | 303 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); |
298 EXPECT_STREQ("enter(main) enter(foo) enter(foo) exit(foo) exit(main) ", | 304 EXPECT_STREQ("enter(main) enter(foo) enter(foo) exit(foo) exit(main) ", |
299 result_cstr); | 305 result_cstr); |
300 EXPECT(saw_paused_event); | 306 EXPECT(saw_paused_event); |
301 } | 307 } |
302 | 308 |
303 | 309 |
304 TEST_CASE(Debugger_RewindTwoFrames_Unoptimized) { | 310 TEST_CASE(Debugger_RewindTwoFrames_Unoptimized) { |
305 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); | 311 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); |
| 312 |
| 313 // These variables are global state used by RewindOnce. |
306 saw_paused_event = false; | 314 saw_paused_event = false; |
307 rewind_frame_index = "2"; | 315 rewind_frame_index = "2"; |
308 | 316 |
309 const char* kScriptChars = | 317 const char* kScriptChars = |
310 "import 'dart:developer';\n" | 318 "import 'dart:developer';\n" |
311 "\n" | 319 "\n" |
312 "var msg = new StringBuffer();\n" | 320 "var msg = new StringBuffer();\n" |
313 "\n" | 321 "\n" |
314 "foo() {\n" | 322 "foo() {\n" |
315 " msg.write('enter(foo) ');\n" | 323 " msg.write('enter(foo) ');\n" |
(...skipping 22 matching lines...) Expand all Loading... |
338 EXPECT_VALID(result); | 346 EXPECT_VALID(result); |
339 EXPECT(Dart_IsString(result)); | 347 EXPECT(Dart_IsString(result)); |
340 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); | 348 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); |
341 EXPECT_STREQ( | 349 EXPECT_STREQ( |
342 "enter(main) enter(bar) enter(foo) enter(bar) enter(foo) " | 350 "enter(main) enter(bar) enter(foo) enter(bar) enter(foo) " |
343 "exit(foo) exit(bar) exit(main) ", | 351 "exit(foo) exit(bar) exit(main) ", |
344 result_cstr); | 352 result_cstr); |
345 EXPECT(saw_paused_event); | 353 EXPECT(saw_paused_event); |
346 } | 354 } |
347 | 355 |
| 356 |
| 357 TEST_CASE(Debugger_Rewind_Optimized) { |
| 358 SetFlagScope<bool> sfs1(&FLAG_trace_rewind, true); |
| 359 SetFlagScope<bool> sfs2(&FLAG_prune_dead_locals, false); |
| 360 SetFlagScope<bool> sfs3(&FLAG_enable_inlining_annotations, true); |
| 361 SetFlagScope<bool> sfs4(&FLAG_background_compilation, false); |
| 362 SetFlagScope<int> sfs5(&FLAG_optimization_counter_threshold, 10); |
| 363 |
| 364 // These variables are global state used by RewindOnce. |
| 365 saw_paused_event = false; |
| 366 rewind_frame_index = "2"; |
| 367 |
| 368 const char* kScriptChars = |
| 369 "import 'dart:developer';\n" |
| 370 "\n" |
| 371 "const alwaysInline = \"AlwaysInline\";\n" |
| 372 "const noInline = \"NeverInline\";\n" |
| 373 "\n" |
| 374 "var msg = new StringBuffer();\n" |
| 375 "int i;\n" |
| 376 "\n" |
| 377 "@noInline\n" |
| 378 "foo() {\n" |
| 379 " msg.write('enter(foo) ');\n" |
| 380 " if (i > 15) {\n" |
| 381 " debugger();\n" |
| 382 " msg.write('exit(foo) ');\n" |
| 383 " return true;\n" |
| 384 " } else {\n" |
| 385 " msg.write('exit(foo) ');\n" |
| 386 " return false;\n" |
| 387 " }\n" |
| 388 "}\n" |
| 389 "\n" |
| 390 "@alwaysInline\n" |
| 391 "bar3() {\n" |
| 392 " msg.write('enter(bar3) ');\n" |
| 393 " var result = foo();\n" |
| 394 " msg.write('exit(bar3) ');\n" |
| 395 " return result;\n" |
| 396 "}\n" |
| 397 "\n" |
| 398 "@alwaysInline\n" |
| 399 "bar2() {\n" |
| 400 " msg.write('enter(bar2) ');\n" |
| 401 " var result = bar3();\n" |
| 402 " msg.write('exit(bar2) ');\n" |
| 403 " return result;\n" |
| 404 "}\n" |
| 405 "\n" |
| 406 "@alwaysInline\n" |
| 407 "bar1() {\n" |
| 408 " msg.write('enter(bar1) ');\n" |
| 409 " var result = bar2();\n" |
| 410 " msg.write('exit(bar1) ');\n" |
| 411 " return result;\n" |
| 412 "}\n" |
| 413 "\n" |
| 414 "main() {\n" |
| 415 " for (i = 0; i < 20; i++) {\n" |
| 416 " msg.clear();\n" |
| 417 " if (bar1()) break;\n;" |
| 418 " }\n" |
| 419 " return msg.toString();\n" |
| 420 "}\n"; |
| 421 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 422 EXPECT_VALID(lib); |
| 423 |
| 424 Dart_SetPausedEventHandler(RewindOnce); |
| 425 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 426 const char* result_cstr; |
| 427 EXPECT_VALID(result); |
| 428 EXPECT(Dart_IsString(result)); |
| 429 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); |
| 430 EXPECT_STREQ( |
| 431 "enter(bar1) enter(bar2) enter(bar3) enter(foo) " |
| 432 "enter(bar3) enter(foo) " |
| 433 "exit(foo) exit(bar3) exit(bar2) exit(bar1) ", |
| 434 result_cstr); |
| 435 EXPECT(saw_paused_event); |
| 436 } |
| 437 |
348 #endif // !PRODUCT | 438 #endif // !PRODUCT |
349 | 439 |
350 } // namespace dart | 440 } // namespace dart |
OLD | NEW |