Changeset 35454 in webkit for trunk/JavaScriptCore/VM/SamplingTool.cpp
- Timestamp:
- Jul 30, 2008, 10:38:35 AM (17 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/SamplingTool.cpp
r35450 r35454 1 1 /* 2 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Cameron Zwarich <[email protected]>4 3 * 5 4 * Redistribution and use in source and binary forms, with or without … … 29 28 30 29 #include "config.h" 31 #include "Opcode.h" 32 33 #include <stdlib.h> 30 #include "SamplingTool.h" 31 34 32 #include "CodeBlock.h" 35 33 #include "Machine.h" 36 37 using namespace std; 34 #include "Opcode.h" 38 35 39 36 namespace KJS { 40 41 #if SAMPLING_TOOL_ENABLED || DUMP_OPCODE_STATS42 43 static const char* opcodeNames[] = {44 "load ",45 "new_object ",46 "new_array ",47 "new_regexp ",48 "mov ",49 50 "not ",51 "eq ",52 "neq ",53 "stricteq ",54 "nstricteq ",55 "less ",56 "lesseq ",57 58 "pre_inc ",59 "pre_dec ",60 "post_inc ",61 "post_dec ",62 "to_jsnumber ",63 "negate ",64 "add ",65 "mul ",66 "div ",67 "mod ",68 "sub ",69 70 "lshift ",71 "rshift ",72 "urshift ",73 "bitand ",74 "bitxor ",75 "bitor ",76 "bitnot ",77 78 "instanceof ",79 "typeof ",80 "in ",81 82 "resolve ",83 "resolve_skip ",84 "get_scoped_var ",85 "put_scoped_var ",86 "resolve_base ",87 "resolve_with_base",88 "resolve_func ",89 "get_by_id ",90 "put_by_id ",91 "del_by_id ",92 "get_by_val ",93 "put_by_val ",94 "del_by_val ",95 "put_by_index ",96 "put_getter ",97 "put_setter ",98 99 "jmp ",100 "jtrue ",101 "jfalse ",102 "jless ",103 "jnless ",104 "jmp_scopes ",105 "loop ",106 "loop_if_true ",107 "loop_if_less ",108 "switch_imm ",109 "switch_char ",110 "switch_string ",111 112 "new_func ",113 "new_func_exp ",114 "call ",115 "call_eval ",116 "ret ",117 118 "construct ",119 120 "get_pnames ",121 "next_pname ",122 123 "push_scope ",124 "pop_scope ",125 126 "catch ",127 "throw ",128 "new_error ",129 130 "jsr ",131 "sret ",132 133 "debug ",134 135 "end "136 };137 138 #endif139 140 #if SAMPLING_TOOL_ENABLED141 37 142 38 void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC) … … 156 52 } 157 53 54 #if PLATFORM(WIN) 55 56 static void sleepForMicroseconds(unsigned us) 57 { 58 unsigned ms = us/1000; 59 if (us && !ms) 60 ms = 1; 61 Sleep(ms); 62 } 63 64 #else 65 66 static void sleepForMicroseconds(unsigned us) 67 { 68 usleep(us); 69 } 70 71 #endif 72 158 73 static inline unsigned hertz2us(unsigned hertz) 159 74 { … … 164 79 { 165 80 while (m_running) { 166 usleep(hertz2us(m_hertz));81 sleepForMicroseconds(hertz2us(m_hertz)); 167 82 168 83 m_totalSamples++; … … 172 87 173 88 if (codeBlock && vPC) { 174 ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode); 175 if (record) 89 if (ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode)) 176 90 record->sample(codeBlock, vPC); 177 91 } … … 195 109 m_running = true; 196 110 m_hertz = hertz; 197 pthread_create(&m_samplingThread, 0, threadStartFunc, this); 111 112 m_samplingThread = createThread(threadStartFunc, this, "JavaScriptCore::Sampler"); 198 113 } 199 114 … … 202 117 ASSERT(m_running); 203 118 m_running = false; 204 pthread_join(m_samplingThread, 0); 205 } 119 waitForThreadCompletion(m_samplingThread, 0); 120 } 121 122 #if ENABLE(SAMPLING_TOOL) 206 123 207 124 struct OpcodeSampleInfo … … 219 136 static int compareLineCountInfoSampling(const void* left, const void* right) 220 137 { 221 const LineCountInfo *leftLineCount = reinterpret_cast<const LineCountInfo*>(left);222 const LineCountInfo *rightLineCount = reinterpret_cast<const LineCountInfo*>(right);138 const LineCountInfo* leftLineCount = reinterpret_cast<const LineCountInfo*>(left); 139 const LineCountInfo* rightLineCount = reinterpret_cast<const LineCountInfo*>(right); 223 140 224 141 return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0; … … 227 144 static int compareOpcodeIndicesSampling(const void* left, const void* right) 228 145 { 229 const OpcodeSampleInfo *leftSampleInfo = reinterpret_cast<const OpcodeSampleInfo*>(left);230 const OpcodeSampleInfo *rightSampleInfo = reinterpret_cast<const OpcodeSampleInfo*>(right);146 const OpcodeSampleInfo* leftSampleInfo = reinterpret_cast<const OpcodeSampleInfo*>(left); 147 const OpcodeSampleInfo* rightSampleInfo = reinterpret_cast<const OpcodeSampleInfo*>(right); 231 148 232 149 return (leftSampleInfo->count < rightSampleInfo->count) ? 1 : (leftSampleInfo->count > rightSampleInfo->count) ? -1 : 0; … … 251 168 int scopeCount = m_scopeSampleMap->size(); 252 169 long long totalCodeBlockSamples = 0; 253 ScopeSampleRecord* codeBlockSamples[scopeCount];170 Vector<ScopeSampleRecord*> codeBlockSamples(scopeCount); 254 171 ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); 255 172 for (int i=0; i < scopeCount; ++i, ++iter) { … … 257 174 totalCodeBlockSamples += codeBlockSamples[i]->m_totalCount; 258 175 } 259 mergesort(codeBlockSamples, scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); 176 #if HAVE(MERGESORT) 177 mergesort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); 178 #else 179 qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScopeSampleRecord*), compareScopeSampleRecords); 180 #endif 260 181 261 182 // (2) Print data from 'codeBlockSamples' array, calculate 'totalOpcodeSamples', populate 'opcodeSampleCounts' array. … … 290 211 printf("\n"); 291 212 int linesCount = lineCounts.size(); 292 LineCountInfo lineCountInfo[linesCount];213 Vector<LineCountInfo> lineCountInfo(linesCount); 293 214 int lineno = 0; 294 215 for (HashMap<unsigned,unsigned>::iterator iter = lineCounts.begin(); iter != lineCounts.end(); ++iter, ++lineno) { … … 296 217 lineCountInfo[lineno].count = iter->second; 297 218 } 298 mergesort(lineCountInfo, linesCount, sizeof(LineCountInfo), compareLineCountInfoSampling); 219 #if HAVE(MERGESORT) 220 mergesort(lineCountInfo.begin(), linesCount, sizeof(LineCountInfo), compareLineCountInfoSampling); 221 #else 222 qsort(lineCountInfo.begin(), linesCount, sizeof(LineCountInfo), compareLineCountInfoSampling); 223 #endif 299 224 for (lineno = 0; lineno < linesCount; ++lineno) { 300 225 printf(" Line #%d has sample count %d.\n", lineCountInfo[lineno].line, lineCountInfo[lineno].count); … … 324 249 opcodeSampleInfo[i].count = opcodeSampleCounts[i]; 325 250 } 251 #if HAVE(MERGESORT) 326 252 mergesort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling); 253 #else 254 qsort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling); 255 #endif 327 256 328 257 // (4) Print Opcode sampling results. … … 334 263 for (int i = 0; i < numOpcodeIDs; ++i) { 335 264 long long count = opcodeSampleCounts[i]; 336 fprintf(stdout, "%s: \t%6lld\t%.3f%%\t(%.3f%%)\n", opcodeNames[i], count, ((double)count * 100)/totalOpcodeSamples, ((double)count * 100)/m_totalSamples);265 fprintf(stdout, "%s:%s%6lld\t%.3f%%\t(%.3f%%)\n", opcodeNames[i], padOpcodeName((OpcodeID)i, 20), count, ((double)count * 100)/totalOpcodeSamples, ((double)count * 100)/m_totalSamples); 337 266 } 338 267 fprintf(stdout, "\n"); … … 341 270 OpcodeID opcode = opcodeSampleInfo[i].opcode; 342 271 long long count = opcodeSampleInfo[i].count; 343 fprintf(stdout, "%s: \t%6lld\t%.3f%%\t(%.3f%%)\n", opcodeNames[opcode], count, ((double)count * 100)/totalOpcodeSamples, ((double)count * 100)/m_totalSamples);272 fprintf(stdout, "%s:%s%6lld\t%.3f%%\t(%.3f%%)\n", opcodeNames[opcode], padOpcodeName(opcode, 20), count, ((double)count * 100)/totalOpcodeSamples, ((double)count * 100)/m_totalSamples); 344 273 } 345 274 fprintf(stdout, "\n"); 346 275 } 347 276 348 #endif 349 350 351 #if DUMP_OPCODE_STATS 352 353 long long OpcodeStats::opcodeCounts[numOpcodeIDs]; 354 long long OpcodeStats::opcodePairCounts[numOpcodeIDs][numOpcodeIDs]; 355 int OpcodeStats::lastOpcode = -1; 356 357 static OpcodeStats logger; 358 359 OpcodeStats::OpcodeStats() 360 { 361 for (int i = 0; i < numOpcodeIDs; ++i) 362 opcodeCounts[i] = 0; 363 364 for (int i = 0; i < numOpcodeIDs; ++i) 365 for (int j = 0; j < numOpcodeIDs; ++j) 366 opcodePairCounts[i][j] = 0; 367 } 368 369 static int compareOpcodeIndices(const void* left, const void* right) 370 { 371 long long leftValue = OpcodeStats::opcodeCounts[*(int*) left]; 372 long long rightValue = OpcodeStats::opcodeCounts[*(int*) right]; 373 374 if (leftValue < rightValue) 375 return 1; 376 else if (leftValue > rightValue) 377 return -1; 378 else 379 return 0; 380 } 381 382 static int compareOpcodePairIndices(const void* left, const void* right) 383 { 384 pair<int, int> leftPair = *(pair<int, int>*) left; 385 long long leftValue = OpcodeStats::opcodePairCounts[leftPair.first][leftPair.second]; 386 pair<int, int> rightPair = *(pair<int, int>*) right; 387 long long rightValue = OpcodeStats::opcodePairCounts[rightPair.first][rightPair.second]; 388 389 if (leftValue < rightValue) 390 return 1; 391 else if (leftValue > rightValue) 392 return -1; 393 else 394 return 0; 395 } 396 397 OpcodeStats::~OpcodeStats() 398 { 399 long long totalInstructions = 0; 400 for (int i = 0; i < numOpcodeIDs; ++i) 401 totalInstructions += opcodeCounts[i]; 402 403 long long totalInstructionPairs = 0; 404 for (int i = 0; i < numOpcodeIDs; ++i) 405 for (int j = 0; j < numOpcodeIDs; ++j) 406 totalInstructionPairs += opcodePairCounts[i][j]; 407 408 int sortedIndices[numOpcodeIDs]; 409 for (int i = 0; i < numOpcodeIDs; ++i) 410 sortedIndices[i] = i; 411 mergesort(sortedIndices, numOpcodeIDs, sizeof(int), compareOpcodeIndices); 412 413 pair<int, int> sortedPairIndices[numOpcodeIDs * numOpcodeIDs]; 414 pair<int, int>* currentPairIndex = sortedPairIndices; 415 for (int i = 0; i < numOpcodeIDs; ++i) 416 for (int j = 0; j < numOpcodeIDs; ++j) 417 *(currentPairIndex++) = make_pair(i, j); 418 mergesort(sortedPairIndices, numOpcodeIDs * numOpcodeIDs, sizeof(pair<int, int>), compareOpcodePairIndices); 419 420 printf("\nExecuted opcode statistics\n"); 421 422 printf("Total instructions executed: %lld\n\n", totalInstructions); 423 424 printf("All opcodes by frequency:\n\n"); 425 426 for (int i = 0; i < numOpcodeIDs; ++i) { 427 int index = sortedIndices[i]; 428 printf("%s: %lld - %.2f%%\n", opcodeNames[index], opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0); 429 } 430 431 printf("\n"); 432 printf("2-opcode sequences by frequency: %lld\n\n", totalInstructions); 433 434 for (int i = 0; i < numOpcodeIDs * numOpcodeIDs; ++i) { 435 pair<int, int> indexPair = sortedPairIndices[i]; 436 long long count = opcodePairCounts[indexPair.first][indexPair.second]; 437 438 if (!count) 439 break; 440 441 printf("%s %s: %lld %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], count, ((double) count) / ((double) totalInstructionPairs) * 100.0); 442 } 443 444 printf("\n"); 445 printf("Most common opcodes and sequences:\n"); 446 447 for (int i = 0; i < numOpcodeIDs; ++i) { 448 int index = sortedIndices[i]; 449 long long opcodeCount = opcodeCounts[index]; 450 double opcodeProportion = ((double) opcodeCount) / ((double) totalInstructions); 451 if (opcodeProportion < 0.0001) 452 break; 453 printf("\n%s: %lld - %.2f%%\n", opcodeNames[index], opcodeCount, opcodeProportion * 100.0); 454 455 for (int j = 0; j < numOpcodeIDs * numOpcodeIDs; ++j) { 456 pair<int, int> indexPair = sortedPairIndices[j]; 457 long long pairCount = opcodePairCounts[indexPair.first][indexPair.second]; 458 double pairProportion = ((double) pairCount) / ((double) totalInstructionPairs); 459 460 if (!pairCount || pairProportion < 0.0001 || pairProportion < opcodeProportion / 100) 461 break; 462 463 if (indexPair.first != index && indexPair.second != index) 464 continue; 465 466 printf(" %s %s: %lld - %.2f%%\n", opcodeNames[indexPair.first], opcodeNames[indexPair.second], pairCount, pairProportion * 100.0); 467 } 468 469 } 470 printf("\n"); 471 } 472 473 void OpcodeStats::recordInstruction(int opcode) 474 { 475 opcodeCounts[opcode]++; 476 477 if (lastOpcode != -1) 478 opcodePairCounts[lastOpcode][opcode]++; 479 480 lastOpcode = opcode; 481 } 482 483 void OpcodeStats::resetLastInstruction() 484 { 485 lastOpcode = -1; 486 } 487 488 #endif 489 490 } // namespace WTF 277 #else 278 279 void SamplingTool::dump(ExecState*) 280 { 281 } 282 283 #endif 284 285 } // namespace KJS
Note:
See TracChangeset
for help on using the changeset viewer.