| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| // VMOptions=--optimization_counter_threshold=10 --no-background-compilation | |
| // This test tries to verify that we produce the correct stack trace when | |
| // throwing exceptions even when functions are inlined. | |
| // The test invokes a bunch of functions and then does a throw. There is a | |
| // catch at the outer function which uses the stack trace produced to return | |
| // a string. The test then verifies that the stack trace contains each | |
| // method in the invocation chain. The test is run during warmup to ensure | |
| // unoptimized code produces the correct result and is then run | |
| // in a loop to ensure optimization kicks in and some inlining is done. | |
| // Note: it appears that functions which have a throw are not inlined (func4) | |
| // and functions that have try/catch in them are not optimized (func1). | |
| // func2 is not inlined as func1 has not been optimized. | |
| import "package:expect/variations.dart"; | |
| class Test { | |
| @pragma("vm:entry-point") | |
| String func1(k) { | |
| try { | |
| for (var i = 0; i <= 50; i++) { | |
| func2(i * k); | |
| } | |
| return ""; | |
| } catch (e, stacktrace) { | |
| var result = e.toString() + "\n" + stacktrace.toString(); | |
| return result; | |
| } | |
| } | |
| @pragma("vm:entry-point") | |
| int func2(i) { | |
| var result = 0; | |
| for (var k = 0; k <= 10; k++) { | |
| result += func3(i + k); | |
| } | |
| return result; | |
| } | |
| @pragma("vm:entry-point") | |
| int func3(i) { | |
| var result = 0; | |
| for (var l = 0; l <= 1; l++) { | |
| result += func4(i + l); | |
| } | |
| return result; | |
| } | |
| @pragma("vm:entry-point") | |
| int func4(i) { | |
| var result = 0; | |
| for (var j = 0; j <= 10; j++) { | |
| result += func5(i + j); | |
| } | |
| return result; | |
| } | |
| @pragma("vm:entry-point") | |
| int func5(i) { | |
| if (i >= 520) throw "show me inlined functions"; | |
| return i; | |
| } | |
| } | |
| expectHasSubstring(String string, String substring) { | |
| if (!string.contains(substring)) { | |
| var sb = new StringBuffer(); | |
| sb.writeln("Expect string:"); | |
| sb.writeln(string); | |
| sb.writeln("To have substring:"); | |
| sb.writeln(substring); | |
| throw new Exception(sb.toString()); | |
| } | |
| } | |
| main() { | |
| var x = new Test(); | |
| var result = x.func1(100000); | |
| expectHasSubstring(result, "show me inlined functions"); | |
| if (symbolicUnminifiedStackTraces) { | |
| expectHasSubstring(result, "Test.func1"); | |
| expectHasSubstring(result, "Test.func2"); | |
| expectHasSubstring(result, "Test.func3"); | |
| expectHasSubstring(result, "Test.func4"); | |
| expectHasSubstring(result, "Test.func5"); | |
| } | |
| for (var i = 0; i <= 10; i++) { | |
| result = x.func1(i); | |
| } | |
| expectHasSubstring(result, "show me inlined functions"); | |
| if (symbolicUnminifiedStackTraces) { | |
| expectHasSubstring(result, "Test.func1"); | |
| expectHasSubstring(result, "Test.func2"); | |
| expectHasSubstring(result, "Test.func3"); | |
| expectHasSubstring(result, "Test.func4"); | |
| expectHasSubstring(result, "Test.func5"); | |
| } | |
| } |