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 (int 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, "[%d] %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 (int i = 0; i + 1 < list_length; i += 2) { | |
srdjan
2013/10/08 18:41:25
s/int/intptr_t/
turnidge
2013/10/09 17:57:21
Done.
| |
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 |