Ignore:
Timestamp:
Jul 30, 2008, 10:38:35 AM (17 years ago)
Author:
[email protected]
Message:

2008-07-30 Gavin Barraclough <[email protected]>

Reviewed by Geoff Garen.

Fixes for Windows and non-AllInOne file build with SamplingTool, plus review fixes.

  • GNUmakefile.am: Adding SamplingTool.cpp to build.
  • JavaScriptCore.exp: Export hooks to init & control SamplingTool.
  • JavaScriptCore.pri: Adding SamplingTool.cpp to build.
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Adding SamplingTool.cpp to build.
  • JavaScriptCore.xcodeproj/project.pbxproj: Adding SamplingTool.cpp to build.
  • JavaScriptCoreSources.bkl: Adding SamplingTool.cpp to build.
  • VM/Machine.cpp: MACHINE_SAMPLING_callingNativeFunction renamed MACHINE_SAMPLING_callingHostFunction
  • VM/Machine.h:
  • VM/Opcode.cpp: SamplingTool moved to SamplingTool.cpp/.h, opcodeNames generated from FOR_EACH_OPCODE_ID.
  • VM/Opcode.h:
  • VM/SamplingTool.cpp: Added .cpp/.h for SamplingTool.
  • VM/SamplingTool.h:
  • kjs/Shell.cpp: Switched SAMPLING_TOOL_ENABLED to ENABLE_SAMPLING_TOOL.
  • wtf/Platform.h: Added ENABLE_SAMPLING_TOOL config option.
  • kjs/nodes.cpp: Header include to fix non-AllInOne builds.
File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/SamplingTool.cpp

    r35450 r35454  
    11/*
    22 * Copyright (C) 2008 Apple Inc. All rights reserved.
    3  * Copyright (C) 2008 Cameron Zwarich <[email protected]>
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    2928
    3029#include "config.h"
    31 #include "Opcode.h"
    32 
    33 #include <stdlib.h>
     30#include "SamplingTool.h"
     31
    3432#include "CodeBlock.h"
    3533#include "Machine.h"
    36 
    37 using namespace std;
     34#include "Opcode.h"
    3835
    3936namespace KJS {
    40 
    41 #if SAMPLING_TOOL_ENABLED || DUMP_OPCODE_STATS
    42 
    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 #endif
    139 
    140 #if SAMPLING_TOOL_ENABLED
    14137
    14238void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
     
    15652}
    15753
     54#if PLATFORM(WIN)
     55
     56static 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
     66static void sleepForMicroseconds(unsigned us)
     67{
     68    usleep(us);
     69}
     70
     71#endif
     72
    15873static inline unsigned hertz2us(unsigned hertz)
    15974{
     
    16479{
    16580    while (m_running) {
    166         usleep(hertz2us(m_hertz));
     81        sleepForMicroseconds(hertz2us(m_hertz));
    16782
    16883        m_totalSamples++;
     
    17287
    17388        if (codeBlock && vPC) {
    174             ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode);
    175             if (record)
     89            if (ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode))
    17690                record->sample(codeBlock, vPC);
    17791        }
     
    195109    m_running = true;
    196110    m_hertz = hertz;
    197     pthread_create(&m_samplingThread, 0, threadStartFunc, this);
     111
     112    m_samplingThread = createThread(threadStartFunc, this, "JavaScriptCore::Sampler");
    198113}
    199114
     
    202117    ASSERT(m_running);
    203118    m_running = false;
    204     pthread_join(m_samplingThread, 0);
    205 }
     119    waitForThreadCompletion(m_samplingThread, 0);
     120}
     121
     122#if ENABLE(SAMPLING_TOOL)
    206123
    207124struct OpcodeSampleInfo
     
    219136static int compareLineCountInfoSampling(const void* left, const void* right)
    220137{
    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);
    223140
    224141    return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0;
     
    227144static int compareOpcodeIndicesSampling(const void* left, const void* right)
    228145{
    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);
    231148
    232149    return (leftSampleInfo->count < rightSampleInfo->count) ? 1 : (leftSampleInfo->count > rightSampleInfo->count) ? -1 : 0;
     
    251168    int scopeCount = m_scopeSampleMap->size();
    252169    long long totalCodeBlockSamples = 0;
    253     ScopeSampleRecord* codeBlockSamples[scopeCount];
     170    Vector<ScopeSampleRecord*> codeBlockSamples(scopeCount);
    254171    ScopeSampleRecordMap::iterator iter = m_scopeSampleMap->begin();
    255172    for (int i=0; i < scopeCount; ++i, ++iter) {
     
    257174        totalCodeBlockSamples += codeBlockSamples[i]->m_totalCount;
    258175    }
    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
    260181
    261182    // (2) Print data from 'codeBlockSamples' array, calculate 'totalOpcodeSamples', populate 'opcodeSampleCounts' array.
     
    290211                printf("\n");
    291212                int linesCount = lineCounts.size();
    292                 LineCountInfo lineCountInfo[linesCount];
     213                Vector<LineCountInfo> lineCountInfo(linesCount);
    293214                int lineno = 0;
    294215                for (HashMap<unsigned,unsigned>::iterator iter = lineCounts.begin(); iter != lineCounts.end(); ++iter, ++lineno) {
     
    296217                    lineCountInfo[lineno].count = iter->second;
    297218                }
    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
    299224                for (lineno = 0; lineno < linesCount; ++lineno) {
    300225                    printf("    Line #%d has sample count %d.\n", lineCountInfo[lineno].line, lineCountInfo[lineno].count);
     
    324249        opcodeSampleInfo[i].count = opcodeSampleCounts[i];
    325250    }
     251#if HAVE(MERGESORT)
    326252    mergesort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling);
     253#else
     254    qsort(opcodeSampleInfo, numOpcodeIDs, sizeof(OpcodeSampleInfo), compareOpcodeIndicesSampling);
     255#endif
    327256
    328257    // (4) Print Opcode sampling results.
     
    334263    for (int i = 0; i < numOpcodeIDs; ++i) {
    335264        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);   
    337266    }
    338267    fprintf(stdout, "\n");
     
    341270        OpcodeID opcode = opcodeSampleInfo[i].opcode;
    342271        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);   
    344273    }
    345274    fprintf(stdout, "\n");
    346275}
    347276
    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
     279void SamplingTool::dump(ExecState*)
     280{
     281}
     282
     283#endif
     284
     285} // namespace KJS
Note: See TracChangeset for help on using the changeset viewer.