1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jsapi-tests/testFuncCallback.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,141 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "jsapi-tests/tests.h" 1.9 + 1.10 +#ifdef MOZ_TRACE_JSCALLS 1.11 + 1.12 +static int depth = 0; 1.13 +static int enters = 0; 1.14 +static int leaves = 0; 1.15 +static int interpreted = 0; 1.16 + 1.17 +static void 1.18 +funcTransition(const JSFunction *, 1.19 + const JSScript *, 1.20 + const JSContext *cx, 1.21 + int entering) 1.22 +{ 1.23 + if (entering > 0) { 1.24 + ++depth; 1.25 + ++enters; 1.26 + ++interpreted; 1.27 + } else { 1.28 + --depth; 1.29 + ++leaves; 1.30 + } 1.31 +} 1.32 + 1.33 +static bool called2 = false; 1.34 + 1.35 +static void 1.36 +funcTransition2(const JSFunction *, const JSScript*, const JSContext*, int) 1.37 +{ 1.38 + called2 = true; 1.39 +} 1.40 + 1.41 +static int overlays = 0; 1.42 +static JSFunctionCallback innerCallback = nullptr; 1.43 +static void 1.44 +funcTransitionOverlay(const JSFunction *fun, 1.45 + const JSScript *script, 1.46 + const JSContext *cx, 1.47 + int entering) 1.48 +{ 1.49 + (*innerCallback)(fun, script, cx, entering); 1.50 + overlays++; 1.51 +} 1.52 +#endif 1.53 + 1.54 +BEGIN_TEST(testFuncCallback_bug507012) 1.55 +{ 1.56 +#ifdef MOZ_TRACE_JSCALLS 1.57 + // Call funcTransition() whenever a Javascript method is invoked 1.58 + JS_SetFunctionCallback(cx, funcTransition); 1.59 + 1.60 + EXEC("x = 0; function f (n) { if (n > 1) { f(n - 1); } }"); 1.61 + interpreted = enters = leaves = depth = 0; 1.62 + 1.63 + // Check whether JS_Execute() tracking works 1.64 + EXEC("42"); 1.65 + CHECK_EQUAL(enters, 1); 1.66 + CHECK_EQUAL(leaves, 1); 1.67 + CHECK_EQUAL(depth, 0); 1.68 + interpreted = enters = leaves = depth = 0; 1.69 + 1.70 + // Check whether the basic function tracking works 1.71 + EXEC("f(1)"); 1.72 + CHECK_EQUAL(enters, 1+1); 1.73 + CHECK_EQUAL(leaves, 1+1); 1.74 + CHECK_EQUAL(depth, 0); 1.75 + 1.76 + // Can we switch to a different callback? 1.77 + enters = 777; 1.78 + JS_SetFunctionCallback(cx, funcTransition2); 1.79 + EXEC("f(1)"); 1.80 + CHECK(called2); 1.81 + CHECK_EQUAL(enters, 777); 1.82 + 1.83 + // Check whether we can turn off function tracing 1.84 + JS_SetFunctionCallback(cx, nullptr); 1.85 + EXEC("f(1)"); 1.86 + CHECK_EQUAL(enters, 777); 1.87 + interpreted = enters = leaves = depth = 0; 1.88 + 1.89 + // Check nested invocations 1.90 + JS_SetFunctionCallback(cx, funcTransition); 1.91 + enters = leaves = depth = 0; 1.92 + EXEC("f(3)"); 1.93 + CHECK_EQUAL(enters, 1+3); 1.94 + CHECK_EQUAL(leaves, 1+3); 1.95 + CHECK_EQUAL(depth, 0); 1.96 + interpreted = enters = leaves = depth = 0; 1.97 + 1.98 + // Check calls invoked while running on trace -- or now, perhaps on 1.99 + // IonMonkey's equivalent, if it ever starts to exist? 1.100 + EXEC("function g () { ++x; }"); 1.101 + interpreted = enters = leaves = depth = 0; 1.102 + EXEC("for (i = 0; i < 5000; ++i) { g(); }"); 1.103 + CHECK_EQUAL(enters, 1+5000); 1.104 + CHECK_EQUAL(leaves, 1+5000); 1.105 + CHECK_EQUAL(depth, 0); 1.106 + 1.107 + // Test nesting callbacks via JS_GetFunctionCallback() 1.108 + JS_SetFunctionCallback(cx, funcTransition); 1.109 + innerCallback = JS_GetFunctionCallback(cx); 1.110 + JS_SetFunctionCallback(cx, funcTransitionOverlay); 1.111 + 1.112 + EXEC("x = 0; function f (n) { if (n > 1) { f(n - 1); } }"); 1.113 + interpreted = enters = leaves = depth = overlays = 0; 1.114 + 1.115 + EXEC("42.5"); 1.116 + CHECK_EQUAL(enters, 1); 1.117 + CHECK_EQUAL(leaves, 1); 1.118 + CHECK_EQUAL(depth, 0); 1.119 + CHECK_EQUAL(overlays, enters + leaves); 1.120 + interpreted = enters = leaves = depth = overlays = 0; 1.121 +#endif 1.122 + 1.123 + // Uncomment this to validate whether you're hitting all runmodes (interp, 1.124 + // mjit, ...?) Unfortunately, that still doesn't cover all 1.125 + // transitions between the various runmodes, but it's a start. 1.126 + //JS_DumpAllProfiles(cx); 1.127 + 1.128 + return true; 1.129 +} 1.130 + 1.131 +// Make sure that the method jit is enabled. 1.132 +// We'll probably want to test in all modes. 1.133 +virtual 1.134 +JSContext *createContext() 1.135 +{ 1.136 + JSContext *cx = JSAPITest::createContext(); 1.137 + if (!cx) 1.138 + return nullptr; 1.139 + JS::RuntimeOptionsRef(cx).setBaseline(true) 1.140 + .setIon(true); 1.141 + return cx; 1.142 +} 1.143 + 1.144 +END_TEST(testFuncCallback_bug507012)