| 184 | | typedef WTF::HashMap<ScopeNode*, ScopeSampleRecord*> ScopeSampleRecordMap; |
|---|
| 185 | | |
|---|
| 186 | | class SamplingTool |
|---|
| 187 | | { |
|---|
| 188 | | public: |
|---|
| 189 | | SamplingTool() |
|---|
| 190 | | : m_running(false) |
|---|
| 191 | | , m_recordedCodeBlock(0) |
|---|
| 192 | | , m_recordedVPC(0) |
|---|
| 193 | | , m_totalSamples(0) |
|---|
| 194 | | , m_scopeSampleMap(new ScopeSampleRecordMap()) |
|---|
| 195 | | { |
|---|
| 196 | | } |
|---|
| 197 | | |
|---|
| 198 | | ~SamplingTool() |
|---|
| 199 | | { |
|---|
| 200 | | for (ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); iter != m_scopeSampleMap->end(); ++iter) |
|---|
| 201 | | delete iter->second; |
|---|
| 202 | | delete m_scopeSampleMap; |
|---|
| 203 | | } |
|---|
| 204 | | |
|---|
| 205 | | void start(unsigned hertz=1000); |
|---|
| 206 | | void stop(); |
|---|
| 207 | | void dump(ExecState*); |
|---|
| 208 | | |
|---|
| 209 | | void notifyOfScope(ScopeNode* scope); |
|---|
| 210 | | |
|---|
| 211 | | void sample(CodeBlock* recordedCodeBlock, Instruction* recordedVPC) |
|---|
| 212 | | { |
|---|
| 213 | | m_recordedCodeBlock = recordedCodeBlock; |
|---|
| 214 | | m_recordedVPC = recordedVPC; |
|---|
| 215 | | } |
|---|
| 216 | | |
|---|
| 217 | | void privateExecuteReturned() |
|---|
| 218 | | { |
|---|
| 219 | | m_recordedCodeBlock = 0; |
|---|
| 220 | | m_recordedVPC = 0; |
|---|
| 221 | | } |
|---|
| 222 | | |
|---|
| 223 | | void callingNativeFunction() |
|---|
| 224 | | { |
|---|
| 225 | | m_recordedCodeBlock = 0; |
|---|
| 226 | | m_recordedVPC = 0; |
|---|
| 227 | | } |
|---|
| 228 | | |
|---|
| 229 | | private: |
|---|
| 230 | | static void* threadStartFunc(void*); |
|---|
| 231 | | void run(); |
|---|
| 232 | | |
|---|
| 233 | | // Sampling thread state. |
|---|
| 234 | | bool m_running; |
|---|
| 235 | | unsigned m_hertz; |
|---|
| 236 | | pthread_t m_samplingThread; |
|---|
| 237 | | |
|---|
| 238 | | // State tracked by the main thread, used by the sampling thread. |
|---|
| 239 | | CodeBlock* m_recordedCodeBlock; |
|---|
| 240 | | Instruction* m_recordedVPC; |
|---|
| 241 | | |
|---|
| 242 | | // Gathered sample data. |
|---|
| 243 | | long long m_totalSamples; |
|---|
| 244 | | ScopeSampleRecordMap* m_scopeSampleMap; |
|---|
| 245 | | }; |
|---|
| | 166 | #undef PADDING_STRING_LENGTH |
|---|
| | 167 | #undef PADDING_STRING |
|---|
| 248 | | |
|---|
| 249 | | // SCOPENODE_ / MACHINE_ macros for use from within member methods on ScopeNode / Machine respectively. |
|---|
| 250 | | #if SAMPLING_TOOL_ENABLED |
|---|
| 251 | | #define SCOPENODE_SAMPLING_notifyOfScope(sampler) sampler->notifyOfScope(this) |
|---|
| 252 | | #define MACHINE_SAMPLING_sample(codeBlock, vPC) m_sampler->sample(codeBlock, vPC) |
|---|
| 253 | | #define MACHINE_SAMPLING_privateExecuteReturned() m_sampler->privateExecuteReturned() |
|---|
| 254 | | #define MACHINE_SAMPLING_callingNativeFunction() m_sampler->callingNativeFunction() |
|---|
| 255 | | #else |
|---|
| 256 | | #define SCOPENODE_SAMPLING_notifyOfScope(sampler) |
|---|
| 257 | | #define MACHINE_SAMPLING_sample(codeBlock, vPC) |
|---|
| 258 | | #define MACHINE_SAMPLING_privateExecuteReturned() |
|---|
| 259 | | #define MACHINE_SAMPLING_callingNativeFunction() |
|---|
| 260 | | #endif |
|---|
| 261 | | |
|---|