Changeset 37891 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


Ignore:
Timestamp:
Oct 25, 2008, 12:59:47 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-25 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig, with Gavin Barraclough's help.


Fixed Sampling Tool:

  • Made CodeBlock sampling work with CTI
  • Improved accuracy by unifying most sampling data into a single 32bit word, which can be written / read atomically.
  • Split out three different #ifdefs for modularity: OPCODE_SAMPLING; CODEBLOCK_SAMPLING; OPCODE_STATS.
  • Improved reporting clarity
  • Refactored for code clarity
  • VM/CTI.cpp: (JSC::CTI::emitCTICall): (JSC::CTI::compileOpCall): (JSC::CTI::emitSlowScriptCheck): (JSC::CTI::compileBinaryArithOpSlowCase): (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases): (JSC::CTI::privateCompile):
  • VM/CTI.h: Updated CTI codegen to use the unified SamplingTool interface for encoding samples. (This required passing the current vPC to a lot more functions, since the unified interface samples the current vPC.) Added hooks for writing the current CodeBlock* on function entry and after a function call, for the sake of the CodeBlock sampler. Removed obsolete hook for clearing the current sample inside op_end. Also removed the custom enum used to differentiate flavors of op_call, since the OpcodeID enum works just as well. (This was important in an earlier version of the patch, but now it's just cleanup.)
  • VM/CodeBlock.cpp: (JSC::CodeBlock::lineNumberForVPC):
  • VM/CodeBlock.h: Upated for refactored #ifdefs. Changed lineNumberForVPC to be robust against vPCs not recorded for exception handling, since the Sampler may ask for an arbitrary vPC.
  • VM/Machine.cpp: (JSC::Machine::execute): (JSC::Machine::privateExecute): (JSC::Machine::cti_op_call_NotJSFunction): (JSC::Machine::cti_op_construct_NotJSConstruct):
  • VM/Machine.h: (JSC::Machine::setSampler): (JSC::Machine::sampler): (JSC::Machine::jitCodeBuffer): Upated for refactored #ifdefs. Changed Machine to use SamplingTool helper objects to record movement in and out of host code. This makes samples a bit more precise.


  • VM/Opcode.cpp: (JSC::OpcodeStats::~OpcodeStats):
  • VM/Opcode.h: Upated for refactored #ifdefs. Added a little more padding, to accomodate our more verbose opcode names.
  • VM/SamplingTool.cpp: (JSC::ScopeSampleRecord::sample): Only count a sample toward our total if we actually record it. This solves cases where a CodeBlock will claim to have been sampled many times, with reported samples that don't match.

(JSC::SamplingTool::run): Read the current sample into a Sample helper
object, to ensure that the data doesn't change while we're analyzing it,
and to help decode the data. Only access the CodeBlock sampling hash
table if CodeBlock sampling has been enabled, so non-CodeBlock sampling
runs can operate with even less overhead.

(JSC::SamplingTool::dump): I reorganized this code a lot to print the
most important info at the top, print as a table, annotate and document
the stuff I didn't understand when I started, etc.

  • VM/SamplingTool.h: New helper classes, described above.
  • kjs/Parser.h:
  • kjs/Shell.cpp: (runWithScripts):
  • kjs/nodes.cpp: (JSC::ScopeNode::ScopeNode): Updated for new sampling APIs.
  • wtf/Platform.h: Moved sampling #defines here, since our custom is to put ENABLE #defines into Platform.h. Made explicit the fact that CODEBLOCK_SAMPLING depends on OPCODE_SAMPLING.
File:
1 edited

Legend:

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

    r37845 r37891  
    924924        (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
    925925
    926     m_reentryDepth++;
     926    JSValue* result;
     927    {
     928        SamplingTool::CallRecord callRecord(m_sampler);
     929
     930        m_reentryDepth++;
    927931#if ENABLE(CTI)
    928     if (!codeBlock->ctiCode)
    929         CTI::compile(this, newCallFrame, codeBlock);
    930     JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
     932        if (!codeBlock->ctiCode)
     933            CTI::compile(this, newCallFrame, codeBlock);
     934        result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
    931935#else
    932     JSValue* result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     936        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
    933937#endif
    934     m_reentryDepth--;
    935 
    936     MACHINE_SAMPLING_privateExecuteReturned();
     938        m_reentryDepth--;
     939    }
    937940
    938941    if (*profiler)
     
    987990        (*profiler)->willExecute(newCallFrame, function);
    988991
    989     m_reentryDepth++;
     992    JSValue* result;
     993    {
     994        SamplingTool::CallRecord callRecord(m_sampler);
     995
     996        m_reentryDepth++;
    990997#if ENABLE(CTI)
    991     if (!codeBlock->ctiCode)
    992         CTI::compile(this, newCallFrame, codeBlock);
    993     JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
     998        if (!codeBlock->ctiCode)
     999            CTI::compile(this, newCallFrame, codeBlock);
     1000        result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
    9941001#else
    995     JSValue* result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     1002        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
    9961003#endif
    997     m_reentryDepth--;
     1004        m_reentryDepth--;
     1005    }
    9981006
    9991007    if (*profiler)
    10001008        (*profiler)->didExecute(newCallFrame, function);
    1001 
    1002     MACHINE_SAMPLING_privateExecuteReturned();
    10031009
    10041010    m_registerFile.shrink(oldEnd);
     
    10761082        (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
    10771083
    1078     m_reentryDepth++;
     1084    JSValue* result;
     1085    {
     1086        SamplingTool::CallRecord callRecord(m_sampler);
     1087
     1088        m_reentryDepth++;
    10791089#if ENABLE(CTI)
    1080     if (!codeBlock->ctiCode)
    1081         CTI::compile(this, newCallFrame, codeBlock);
    1082     JSValue* result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
     1090        if (!codeBlock->ctiCode)
     1091            CTI::compile(this, newCallFrame, codeBlock);
     1092        result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
    10831093#else
    1084     JSValue* result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
     1094        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
    10851095#endif
    1086     m_reentryDepth--;
    1087 
    1088     MACHINE_SAMPLING_privateExecuteReturned();
     1096        m_reentryDepth--;
     1097    }
    10891098
    10901099    if (*profiler)
     
    14731482    } while (0)
    14741483
    1475 #if DUMP_OPCODE_STATS
     1484#if ENABLE(OPCODE_STATS)
    14761485    OpcodeStats::resetLastInstruction();
    14771486#endif
     
    14831492        tickCount = m_ticksUntilNextTimeoutCheck; \
    14841493    }
     1494   
     1495#if ENABLE(OPCODE_SAMPLING)
     1496    #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
     1497    #define CTI_SAMPLER ARG_globalData->machine->sampler()
     1498#else
     1499    #define SAMPLE(codeBlock, vPC)
     1500    #define CTI_SAMPLER
     1501#endif
    14851502
    14861503#if HAVE(COMPUTED_GOTO)
    1487     #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
    1488 #if DUMP_OPCODE_STATS
     1504    #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
     1505#if ENABLE(OPCODE_STATS)
    14891506    #define BEGIN_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
    14901507#else
     
    14931510    NEXT_OPCODE;
    14941511#else
    1495     #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto interpreterLoopStart
    1496 #if DUMP_OPCODE_STATS
     1512    #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto interpreterLoopStart
     1513#if ENABLE(OPCODE_STATS)
    14971514    #define BEGIN_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);
    14981515#else
     
    29592976           the JS timeout is reached.
    29602977         */
    2961 #if DUMP_OPCODE_STATS
     2978#if ENABLE(OPCODE_STATS)
    29622979        OpcodeStats::resetLastInstruction();
    29632980#endif
     
    29732990           instruction.
    29742991        */
    2975 #if DUMP_OPCODE_STATS
     2992#if ENABLE(OPCODE_STATS)
    29762993        OpcodeStats::resetLastInstruction();
    29772994#endif
     
    33543371            vPC = newCodeBlock->instructions.begin();
    33553372
    3356 #if DUMP_OPCODE_STATS
     3373#if ENABLE(OPCODE_STATS)
    33573374            OpcodeStats::resetLastInstruction();
    33583375#endif
     
    33693386            newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
    33703387
    3371             MACHINE_SAMPLING_callingHostFunction();
    3372 
    3373             JSValue* returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
     3388            JSValue* returnValue;
     3389            {
     3390                SamplingTool::HostCallRecord callRecord(m_sampler);
     3391                returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
     3392            }
    33743393            VM_CHECK_EXCEPTION();
    33753394
     
    35993618            vPC = newCodeBlock->instructions.begin();
    36003619
    3601 #if DUMP_OPCODE_STATS
     3620#if ENABLE(OPCODE_STATS)
    36023621            OpcodeStats::resetLastInstruction();
    36033622#endif
     
    36133632            newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
    36143633
    3615             MACHINE_SAMPLING_callingHostFunction();
    3616 
    3617             JSValue* returnValue = constructData.native.function(newCallFrame, asObject(v), args);
    3618 
     3634            JSValue* returnValue;
     3635            {
     3636                SamplingTool::HostCallRecord callRecord(m_sampler);
     3637                returnValue = constructData.native.function(newCallFrame, asObject(v), args);
     3638            }
    36193639            VM_CHECK_EXCEPTION();
    36203640            callFrame[dst] = returnValue;
     
    47954815        ArgList argList(argv + 1, argCount - 1);
    47964816
    4797         CTI_MACHINE_SAMPLING_callingHostFunction();
    4798 
    4799         JSValue* returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList);
     4817        JSValue* returnValue;
     4818        {
     4819            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
     4820            returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList);
     4821        }
    48004822        ARG_setCallFrame(previousCallFrame);
    48014823        VM_CHECK_EXCEPTION();
     
    50005022        ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1);
    50015023
    5002         CTI_MACHINE_SAMPLING_callingHostFunction();
    5003 
    5004         JSValue* returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
     5024        JSValue* returnValue;
     5025        {
     5026            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
     5027            returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
     5028        }
    50055029        VM_CHECK_EXCEPTION();
    50065030
Note: See TracChangeset for help on using the changeset viewer.