Ignore:
Timestamp:
Aug 14, 2014, 4:59:44 PM (11 years ago)
Author:
[email protected]
Message:

Allow high fidelity type profiling to be enabled and disabled.
https://bugs.webkit.org/show_bug.cgi?id=135423

Patch by Saam Barati <[email protected]> on 2014-08-14
Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

  • Merged op_put_to_scope_with_profile and op_get_from_scope_with_profile into op_profile_types_with_high_fidelity by adding extra arguments to the opcode.
  • Altered SymbolTable to use less memory by adding a rare data structure for type profiling.
  • Created an interface to turn on and off type profiling from the Web Inspector.
  • Refactored how entries are written to HighFidelityLog to make it easier to inline when generating machine code.
  • Implemented op_profile_types_with_high_fidelity in the baseline JIT by inlining the process of writing to the log and doing a small amount of type inference optimizations.
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::scopeDependentProfile): Deleted.

  • bytecode/CodeBlock.h:
  • bytecode/TypeLocation.h:

(JSC::TypeLocation::TypeLocation):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::emitMove):
(JSC::BytecodeGenerator::emitProfileTypesWithHighFidelity):
(JSC::BytecodeGenerator::emitGetFromScopeWithProfile): Deleted.
(JSC::BytecodeGenerator::emitPutToScopeWithProfile): Deleted.

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ThisNode::emitBytecode):
(JSC::ResolveNode::emitBytecode):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::PostfixNode::emitBracket):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitResolve):
(JSC::PrefixNode::emitBracket):
(JSC::PrefixNode::emitDot):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::AssignDotNode::emitBytecode):
(JSC::ReadModifyDotNode::emitBytecode):
(JSC::AssignBracketNode::emitBytecode):
(JSC::ReadModifyBracketNode::emitBytecode):
(JSC::ReturnNode::emitBytecode):
(JSC::FunctionBodyNode::emitBytecode):

  • inspector/agents/InspectorRuntimeAgent.cpp:

(Inspector::InspectorRuntimeAgent::InspectorRuntimeAgent):
(Inspector::InspectorRuntimeAgent::getRuntimeTypesForVariablesAtOffsets):
(Inspector::TypeRecompiler::operator()):
(Inspector::recompileAllJSFunctionsForTypeProfiling):
(Inspector::InspectorRuntimeAgent::willDestroyFrontendAndBackend):
(Inspector::InspectorRuntimeAgent::enableHighFidelityTypeProfiling):
(Inspector::InspectorRuntimeAgent::disableHighFidelityTypeProfiling):
(Inspector::InspectorRuntimeAgent::setHighFidelityTypeProfilingEnabledState):

  • inspector/agents/InspectorRuntimeAgent.h:
  • inspector/agents/JSGlobalObjectRuntimeAgent.cpp:

(Inspector::JSGlobalObjectRuntimeAgent::willDestroyFrontendAndBackend):

  • inspector/protocol/Runtime.json:
  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompile):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_profile_types_with_high_fidelity):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_profile_types_with_high_fidelity):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::getFromScopeCommon): Deleted.
(JSC::LLInt::putToScopeCommon): Deleted.

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • runtime/CodeCache.cpp:

(JSC::CodeCache::getGlobalCodeBlock):

  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:
  • runtime/HighFidelityLog.cpp:

(JSC::HighFidelityLog::initializeHighFidelityLog):
(JSC::HighFidelityLog::~HighFidelityLog):
(JSC::HighFidelityLog::processHighFidelityLog):

  • runtime/HighFidelityLog.h:

(JSC::HighFidelityLog::LogEntry::structureIDOffset):
(JSC::HighFidelityLog::LogEntry::valueOffset):
(JSC::HighFidelityLog::LogEntry::locationOffset):
(JSC::HighFidelityLog::recordTypeInformationForLocation):
(JSC::HighFidelityLog::logEndPtr):
(JSC::HighFidelityLog::logStartOffset):
(JSC::HighFidelityLog::currentLogEntryOffset):

  • runtime/HighFidelityTypeProfiler.cpp:

(JSC::HighFidelityTypeProfiler::logTypesForTypeLocation):
(JSC::descriptorMatchesTypeLocation):

  • runtime/HighFidelityTypeProfiler.h:
  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::cloneCapturedNames):
(JSC::SymbolTable::prepareForHighFidelityTypeProfiling):
(JSC::SymbolTable::uniqueIDForVariable):
(JSC::SymbolTable::uniqueIDForRegister):
(JSC::SymbolTable::globalTypeSetForRegister):
(JSC::SymbolTable::globalTypeSetForVariable):

  • runtime/SymbolTable.h:

(JSC::SymbolTable::add):
(JSC::SymbolTable::set):

  • runtime/TypeLocationCache.cpp:

(JSC::TypeLocationCache::getTypeLocation):

  • runtime/TypeSet.cpp:

(JSC::TypeSet::getRuntimeTypeForValue):
(JSC::TypeSet::addTypeInformation):
(JSC::TypeSet::allPrimitiveTypeNames):
(JSC::TypeSet::addTypeForValue): Deleted.

  • runtime/TypeSet.h:
  • runtime/VM.cpp:

(JSC::VM::VM):
(JSC::VM::nextTypeLocation):
(JSC::VM::enableHighFidelityTypeProfiling):
(JSC::VM::disableHighFidelityTypeProfiling):
(JSC::VM::dumpHighFidelityProfilingTypes):

  • runtime/VM.h:

(JSC::VM::nextLocation): Deleted.

Source/WebCore:

PageRuntimeAgent and WorkerRuntimeAgent now call their super
class's (InspectorRuntimeAgent) implementation of willDestroyFrontendAndBackend
to give InspectorRuntimeAgent a chance to recompile all JavaScript
functions, if necessary, for type profiling.

  • inspector/PageRuntimeAgent.cpp:

(WebCore::PageRuntimeAgent::willDestroyFrontendAndBackend):

  • inspector/WorkerRuntimeAgent.cpp:

(WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r172176 r172614  
    539539        LLINT_THROW(createSyntaxError(exec, "Invalid flag supplied to RegExp constructor."));
    540540    LLINT_RETURN(RegExpObject::create(vm, exec->lexicalGlobalObject()->regExpStructure(), regExp));
    541 }
    542 
    543 LLINT_SLOW_PATH_DECL(slow_path_profile_types_with_high_fidelity)
    544 {
    545     LLINT_BEGIN();
    546     TypeLocation* location = pc[2].u.location;
    547     JSValue val = LLINT_OP_C(1).jsValue();
    548     vm.highFidelityLog()->recordTypeInformationForLocation(val, location);
    549     LLINT_END_IMPL();
    550541}
    551542
     
    13761367}
    13771368
    1378 static JSValue getFromScopeCommon(ExecState* exec, Instruction* pc, VM& vm)
    1379 {
     1369LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
     1370{
     1371    LLINT_BEGIN();
     1372
    13801373    const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
    13811374    JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
     
    13851378    if (!scope->getPropertySlot(exec, ident, slot)) {
    13861379        if (modeAndType.mode() == ThrowIfNotFound)
    1387             return exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
    1388         return jsUndefined();
     1380            LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
     1381        LLINT_RETURN(jsUndefined());
    13891382    }
    13901383
     
    14031396    }
    14041397
    1405     return slot.getValue(exec, ident);
    1406 }
    1407 
    1408 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
    1409 {
    1410     LLINT_BEGIN();
    1411     JSValue value = getFromScopeCommon(exec, pc, vm);
    1412     LLINT_RETURN(value);
    1413 }
    1414 
    1415 LLINT_SLOW_PATH_DECL(slow_path_get_from_scope_with_profile)
    1416 {
    1417     LLINT_BEGIN();
    1418     JSValue value = getFromScopeCommon(exec, pc, vm);
    1419     TypeLocation* location = pc[8].u.location;
    1420     vm.highFidelityLog()->recordTypeInformationForLocation(value, location);
    1421     LLINT_RETURN(value);
    1422 }
    1423 
    1424 static JSObject* putToScopeCommon(ExecState* exec, Instruction* pc)
    1425 {
     1398    LLINT_RETURN(slot.getValue(exec, ident));
     1399}
     1400
     1401LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
     1402{
     1403    LLINT_BEGIN();
     1404
    14261405    CodeBlock* codeBlock = exec->codeBlock();
    14271406    const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
     
    14311410
    14321411    if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident))
    1433         return createUndefinedVariableError(exec, ident);
     1412        LLINT_THROW(createUndefinedVariableError(exec, ident));
    14341413
    14351414    PutPropertySlot slot(scope, codeBlock->isStrictMode());
     
    14381417    CommonSlowPaths::tryCachePutToScopeGlobal(exec, codeBlock, pc, scope, modeAndType, slot);
    14391418
    1440     return nullptr;
    1441 }
    1442 
    1443 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope)
    1444 {
    1445     LLINT_BEGIN();
    1446     JSObject* error = putToScopeCommon(exec, pc);
    1447     if (error)
    1448         LLINT_THROW(error);
    1449     LLINT_END();
    1450 }
    1451 
    1452 LLINT_SLOW_PATH_DECL(slow_path_put_to_scope_with_profile)
    1453 {
    1454     // The format of this instruction is the same as put_to_scope with a TypeLocation appended: put_to_scope_with_profile scope, id, value, ResolveModeAndType, Structure, Operand, TypeLocation*
    1455     LLINT_BEGIN();
    1456     JSObject* error = putToScopeCommon(exec, pc);
    1457     if (error)
    1458         LLINT_THROW(error);
    1459     TypeLocation* location = pc[7].u.location;
    1460     JSValue val = LLINT_OP_C(3).jsValue();
    1461     vm.highFidelityLog()->recordTypeInformationForLocation(val, location);
    14621419    LLINT_END();
    14631420}
Note: See TracChangeset for help on using the changeset viewer.