Line data Source code
1 0 : /* 2 : 3 : OOJSEngineTimeManagement.h 4 : 5 : Functionality related to time limiting and profiling of JavaScript code. 6 : 7 : 8 : Copyright (C) 2010-2013 Jens Ayton 9 : 10 : Permission is hereby granted, free of charge, to any person obtaining a copy 11 : of this software and associated documentation files (the "Software"), to deal 12 : in the Software without restriction, including without limitation the rights 13 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 : copies of the Software, and to permit persons to whom the Software is 15 : furnished to do so, subject to the following conditions: 16 : 17 : The above copyright notice and this permission notice shall be included in all 18 : copies or substantial portions of the Software. 19 : 20 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 : SOFTWARE. 27 : 28 : */ 29 : 30 : 31 : #import "OOJavaScriptEngine.h" 32 : 33 : 34 : /* Time Limiter 35 : 36 : The time limiter stops scripts from running an arbitrarily long time. 37 : 38 : The time limiter must be started before calling into JavaScript code. 39 : Calls to OOJSStartTimeLimiter() and OOJSStopTimeLimiter() must be balanced, 40 : and may be nested. 41 : OOJSStartTimeLimiterWithTimeLimit() is like OOJSStartTimeLimiter(), but 42 : specifies a custom time limit. This limit is only used if the limiter is 43 : actually stopped. 44 : 45 : The time limiter can be paused and resumed for native operations that are 46 : known to be slow. OOJSPauseTimeLimiter() and OOJSResumeTimeLimiter() must 47 : be balanced and can be nested, but the nest count may be negative - it is 48 : valid to call OOJSResumeTimeLimiter() followed by OOJSPauseTimeLimiter(). 49 : */ 50 0 : #define OOJSStartTimeLimiter() OOJSStartTimeLimiterWithTimeLimit(0.0) 51 : 52 : #ifndef NDEBUG 53 0 : #define OOJSStartTimeLimiterWithTimeLimit(limit) OOJSStartTimeLimiterWithTimeLimit_(limit, OOLOG_FILE_NAME, __LINE__) 54 0 : #define OOJSStopTimeLimiter() OOJSStopTimeLimiter_(OOLOG_FILE_NAME, __LINE__) 55 0 : void OOJSStartTimeLimiterWithTimeLimit_(OOTimeDelta limit, const char *file, unsigned line); 56 0 : void OOJSStopTimeLimiter_(const char *file, unsigned line); 57 : #else 58 : void OOJSStartTimeLimiterWithTimeLimit(OOTimeDelta limit); 59 : void OOJSStopTimeLimiter(void); 60 : #endif 61 : 62 : 63 0 : #define kOOJSLongTimeLimit (5.0) 64 : 65 : 66 : #if OOJS_PROFILE 67 : #import "OOProfilingStopwatch.h" 68 : 69 : /* 70 : Profiling support. 71 : 72 : OOJSBeginProfiling(trace), OOJSEndProfiling(), OOJSIsProfiling() 73 : Start, stop, and query profiling mode. It is a hard error to start 74 : profiling while already profiling. 75 : 76 : If trace is set, all profileable functions will be logged. The actual 77 : profile will be of little use in this case because of logging overhead. 78 : 79 : OOJSCopyTimeLimiterNominalStartTime() 80 : Copy the nominal start time for the time limiter. This is the actual time 81 : with any time extensions (paused periods) added in. 82 : 83 : OOJSResetTimeLimiter() 84 : Set the time limiter start time to now. 85 : 86 : OOJSGetTimeLimiterLimit() 87 : OOJSSetTimeLimiterLimit() 88 : Manipulate the timeout. 89 : */ 90 : 91 : 92 : @class OOTimeProfile, OOTimeProfileEntry; 93 : 94 : 95 0 : void OOJSBeginProfiling(BOOL trace); 96 0 : OOTimeProfile *OOJSEndProfiling(void); 97 0 : BOOL OOJSIsProfiling(void); 98 : 99 0 : OOHighResTimeValue OOJSCopyTimeLimiterNominalStartTime(void); 100 : 101 0 : void OOJSResetTimeLimiter(void); 102 0 : OOTimeDelta OOJSGetTimeLimiterLimit(void); 103 0 : void OOJSSetTimeLimiterLimit(OOTimeDelta limit); 104 : 105 : 106 : /* 107 : NOTE: the profiler declarations that need to be visible to functions that 108 : are profiled are found in OOJSEngineNativeWrappers.h. 109 : */ 110 : 111 : 112 0 : @interface OOTimeProfile: NSObject 113 : { 114 : @private 115 0 : double _totalTime; 116 0 : double _nativeTime; 117 0 : double _extensionTime; 118 : #ifdef MOZ_TRACE_JSCALLS 119 : double _javaScriptTime; 120 : #endif 121 : 122 0 : double _profilerOverhead; 123 : 124 0 : NSArray *_profileEntries; 125 : } 126 : 127 0 : - (double) totalTime; 128 0 : - (double) javaScriptTime; 129 0 : - (double) nativeTime; 130 0 : - (double) extensionTime; 131 0 : - (double) nonExtensionTime; 132 0 : - (double) profilerOverhead; 133 : 134 0 : - (NSArray *) profileEntries; // Array of OOTimeProfileEntry 135 : 136 : @end 137 : 138 : 139 0 : @interface OOTimeProfileEntry: NSObject 140 : { 141 : @private 142 0 : NSString *_function; 143 0 : unsigned long _hitCount; 144 0 : double _totalTimeSum; 145 0 : double _selfTimeSum; 146 0 : double _totalTimeMax; 147 0 : double _selfTimeMax; 148 : #ifdef MOZ_TRACE_JSCALLS 149 : JSFunction *_jsFunction; 150 : #endif 151 : } 152 : 153 0 : - (NSString *) description; 154 : 155 0 : - (NSString *) function; 156 0 : - (NSUInteger) hitCount; 157 0 : - (double) totalTimeSum; 158 0 : - (double) selfTimeSum; 159 0 : - (double) totalTimeAverage; 160 0 : - (double) selfTimeAverage; 161 0 : - (double) totalTimeMax; 162 0 : - (double) selfTimeMax; 163 0 : - (BOOL) isJavaScriptFrame; 164 : 165 0 : - (NSComparisonResult) compareByTotalTime:(OOTimeProfileEntry *)other; 166 0 : - (NSComparisonResult) compareByTotalTimeReverse:(OOTimeProfileEntry *)other; 167 0 : - (NSComparisonResult) compareBySelfTime:(OOTimeProfileEntry *)other; 168 0 : - (NSComparisonResult) compareBySelfTimeReverse:(OOTimeProfileEntry *)other; 169 : 170 : @end 171 : 172 : #endif 173 : 174 : 175 : @class OOJavaScriptEngine; 176 : 177 0 : void OOJSTimeManagementInit(OOJavaScriptEngine *engine, JSRuntime *runtime);