Changeset 95666 in webkit


Ignore:
Timestamp:
Sep 21, 2011 12:59:39 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Replace jsFunctionVPtr compares with a type check on the Structure.
https://bugs.webkit.org/show_bug.cgi?id=68557

Reviewed by Oliver Hunt.

This will permit calls to still optimize to subclasses of JSFunction
that have the correct type (but a different C++ vptr).

This patch stops passing the globalData into numerous functions.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::isFunctionConstant):
(JSC::DFG::Graph::valueOfFunctionConstant):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::isFunctionConstant):
(JSC::DFG::JITCompiler::valueOfFunctionConstant):

  • dfg/DFGOperations.cpp:
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

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

(JSC::JIT::compileOpCallVarargs):
(JSC::JIT::compileOpCallSlowCase):

  • jit/JITCall32_64.cpp:

(JSC::JIT::compileOpCallVarargs):
(JSC::JIT::compileOpCallSlowCase):

  • jit/JITInlineMethods.h:

(JSC::JIT::emitJumpIfNotType):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/Executable.h:

(JSC::isHostFunction):

  • runtime/JSFunction.h:

(JSC::JSFunction::createStructure):

  • runtime/JSObject.cpp:

(JSC::JSObject::put):
(JSC::JSObject::putWithAttributes):

  • runtime/JSObject.h:

(JSC::getJSFunction):
(JSC::JSObject::putDirect):
(JSC::JSObject::putDirectWithoutTransition):

  • runtime/JSType.h:
Location:
trunk/Source/JavaScriptCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r95663 r95666  
     12011-09-21  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Replace jsFunctionVPtr compares with a type check on the Structure.
     4        https://bugs.webkit.org/show_bug.cgi?id=68557
     5
     6        Reviewed by Oliver Hunt.
     7
     8        This will permit calls to still optimize to subclasses of JSFunction
     9        that have the correct type (but a different C++ vptr).
     10
     11        This patch stops passing the globalData into numerous functions.
     12
     13        * dfg/DFGByteCodeParser.cpp:
     14        (JSC::DFG::ByteCodeParser::parseBlock):
     15        * dfg/DFGGraph.h:
     16        (JSC::DFG::Graph::isFunctionConstant):
     17        (JSC::DFG::Graph::valueOfFunctionConstant):
     18        * dfg/DFGJITCompiler.h:
     19        (JSC::DFG::JITCompiler::isFunctionConstant):
     20        (JSC::DFG::JITCompiler::valueOfFunctionConstant):
     21        * dfg/DFGOperations.cpp:
     22        * interpreter/Interpreter.cpp:
     23        (JSC::Interpreter::privateExecute):
     24        * jit/JIT.h:
     25        * jit/JITCall.cpp:
     26        (JSC::JIT::compileOpCallVarargs):
     27        (JSC::JIT::compileOpCallSlowCase):
     28        * jit/JITCall32_64.cpp:
     29        (JSC::JIT::compileOpCallVarargs):
     30        (JSC::JIT::compileOpCallSlowCase):
     31        * jit/JITInlineMethods.h:
     32        (JSC::JIT::emitJumpIfNotType):
     33        * jit/JITStubs.cpp:
     34        (JSC::DEFINE_STUB_FUNCTION):
     35        * runtime/Executable.h:
     36        (JSC::isHostFunction):
     37        * runtime/JSFunction.h:
     38        (JSC::JSFunction::createStructure):
     39        * runtime/JSObject.cpp:
     40        (JSC::JSObject::put):
     41        (JSC::JSObject::putWithAttributes):
     42        * runtime/JSObject.h:
     43        (JSC::getJSFunction):
     44        (JSC::JSObject::putDirect):
     45        (JSC::JSObject::putDirectWithoutTransition):
     46        * runtime/JSType.h:
     47
    1482011-09-21  Geoffrey Garen  <ggaren@apple.com>
    249
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r95594 r95666  
    13061306        case op_call: {
    13071307            NodeIndex callTarget = get(currentInstruction[1].u.operand);
    1308             if (m_graph.isFunctionConstant(m_codeBlock, *m_globalData, callTarget)) {
     1308            if (m_graph.isFunctionConstant(m_codeBlock, callTarget)) {
    13091309                int argCount = currentInstruction[2].u.operand;
    13101310                int registerOffset = currentInstruction[3].u.operand;
     
    13211321                }
    13221322               
    1323                 DFG::Intrinsic intrinsic = m_graph.valueOfFunctionConstant(m_codeBlock, *m_globalData, callTarget)->executable()->intrinsic();
     1323                DFG::Intrinsic intrinsic = m_graph.valueOfFunctionConstant(m_codeBlock, callTarget)->executable()->intrinsic();
    13241324               
    13251325                if (handleIntrinsic(usesResult, resultOperand, intrinsic, firstArg, lastArg)) {
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r95523 r95666  
    272272        return at(nodeIndex).isBooleanConstant(codeBlock);
    273273    }
    274     bool isFunctionConstant(CodeBlock* codeBlock, JSGlobalData& globalData, NodeIndex nodeIndex)
     274    bool isFunctionConstant(CodeBlock* codeBlock, NodeIndex nodeIndex)
    275275    {
    276276        if (!isJSConstant(nodeIndex))
    277277            return false;
    278         if (!getJSFunction(globalData, valueOfJSConstant(codeBlock, nodeIndex)))
     278        if (!getJSFunction(valueOfJSConstant(codeBlock, nodeIndex)))
    279279            return false;
    280280        return true;
     
    299299        return valueOfJSConstantNode(codeBlock, nodeIndex).getBoolean();
    300300    }
    301     JSFunction* valueOfFunctionConstant(CodeBlock* codeBlock, JSGlobalData& globalData, NodeIndex nodeIndex)
    302     {
    303         JSCell* function = getJSFunction(globalData, valueOfJSConstant(codeBlock, nodeIndex));
     301    JSFunction* valueOfFunctionConstant(CodeBlock* codeBlock, NodeIndex nodeIndex)
     302    {
     303        JSCell* function = getJSFunction(valueOfJSConstant(codeBlock, nodeIndex));
    304304        ASSERT(function);
    305305        return asFunction(function);
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r95326 r95666  
    252252    bool isNumberConstant(NodeIndex nodeIndex) { return graph().isNumberConstant(codeBlock(), nodeIndex); }
    253253    bool isBooleanConstant(NodeIndex nodeIndex) { return graph().isBooleanConstant(codeBlock(), nodeIndex); }
    254     bool isFunctionConstant(NodeIndex nodeIndex) { return graph().isFunctionConstant(codeBlock(), *globalData(), nodeIndex); }
     254    bool isFunctionConstant(NodeIndex nodeIndex) { return graph().isFunctionConstant(codeBlock(), nodeIndex); }
    255255    // Helper methods get constant values from nodes.
    256256    JSValue valueOfJSConstant(NodeIndex nodeIndex) { return graph().valueOfJSConstant(codeBlock(), nodeIndex); }
     
    258258    double valueOfNumberConstant(NodeIndex nodeIndex) { return graph().valueOfNumberConstant(codeBlock(), nodeIndex); }
    259259    bool valueOfBooleanConstant(NodeIndex nodeIndex) { return graph().valueOfBooleanConstant(codeBlock(), nodeIndex); }
    260     JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return graph().valueOfFunctionConstant(codeBlock(), *globalData(), nodeIndex); }
     260    JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return graph().valueOfFunctionConstant(codeBlock(), nodeIndex); }
    261261
    262262    // These methods JIT generate dynamic, debug-only checks - akin to ASSERTs.
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r95340 r95666  
    520520    JSGlobalData* globalData = &exec->globalData();
    521521    JSValue calleeAsValue = execCallee->calleeAsValue();
    522     JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     522    JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
    523523    if (!calleeAsFunctionCell)
    524524        return handleHostCall(execCallee, calleeAsValue, kind);
     
    569569{
    570570    ExecState* exec = execCallee->callerFrame();
    571     JSGlobalData* globalData = &exec->globalData();
    572571    JSValue calleeAsValue = execCallee->calleeAsValue();
    573     JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     572    JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
    574573    if (UNLIKELY(!calleeAsFunctionCell))
    575574        return handleHostCall(execCallee, calleeAsValue, kind);
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r95139 r95666  
    41704170        JSValue funcVal = callFrame->r(func).jsValue();
    41714171
    4172         if (isHostFunction(callFrame->globalData(), funcVal, globalFuncEval)) {
     4172        if (isHostFunction(funcVal, globalFuncEval)) {
    41734173            Register* newCallFrame = callFrame->registers() + registerOffset;
    41744174            Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r95484 r95666  
    313313        void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
    314314        Jump emitJumpIfNotObject(RegisterID structureReg);
     315        Jump emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType);
    315316
    316317        void testPrototype(JSValue, JumpList& failureCases);
  • trunk/Source/JavaScriptCore/jit/JITCall.cpp

    r93466 r95666  
    7676    // Check for JSFunctions.
    7777    emitJumpSlowCaseIfNotJSCell(regT0);
    78     addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
     78    addSlowCase(emitJumpIfNotType(regT0, regT3, JSFunctionType));
    7979
    8080    // Speculatively roll the callframe, assuming argCount will match the arity.
     
    172172    // Fast check for JS function.
    173173    Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT0);
    174     Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr));
     174    Jump callLinkFailNotJSFunction = emitJumpIfNotType(regT0, regT3, JSFunctionType);
    175175
    176176    // Speculatively roll the callframe, assuming argCount will match the arity.
  • trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp

    r94688 r95666  
    7373
    7474    emitJumpSlowCaseIfNotJSCell(callee, regT1);
    75     addSlowCase(branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr)));
     75    addSlowCase(emitJumpIfNotType(regT0, regT1, JSFunctionType));
    7676
    7777    // Speculatively roll the callframe, assuming argCount will match the arity.
     
    257257    // Fast check for JS function.
    258258    Jump callLinkFailNotObject = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
    259     Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), TrustedImmPtr(m_globalData->jsFunctionVPtr));
     259    Jump callLinkFailNotJSFunction = emitJumpIfNotType(regT0, regT1, JSFunctionType);
    260260
    261261    // Speculatively roll the callframe, assuming argCount will match the arity.
  • trunk/Source/JavaScriptCore/jit/JITInlineMethods.h

    r95559 r95666  
    327327}
    328328
     329ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType type)
     330{
     331    loadPtr(Address(baseReg, JSCell::structureOffset()), scratchReg);
     332    return branch8(NotEqual, Address(scratchReg, Structure::typeInfoTypeOffset()), TrustedImm32(type));
     333}
     334
    329335#if ENABLE(SAMPLING_FLAGS)
    330336ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r95399 r95666  
    33903390    int argCount = stackFrame.args[2].int32();
    33913391
    3392     if (!isHostFunction(callFrame->globalData(), funcVal, globalFuncEval))
     3392    if (!isHostFunction(funcVal, globalFuncEval))
    33933393        return JSValue::encode(JSValue());
    33943394
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r95313 r95666  
    621621    }
    622622
    623     inline bool isHostFunction(JSGlobalData& globalData, JSValue value, NativeFunction nativeFunction)
     623    inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
    624624    {
    625         JSFunction* function = static_cast<JSFunction*>(getJSFunction(globalData, value));
     625        JSFunction* function = static_cast<JSFunction*>(getJSFunction(value));
    626626        if (!function || !function->isHostFunction())
    627627            return false;
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r95205 r95666  
    120120        {
    121121            ASSERT(globalObject);
    122             return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
     122            return Structure::create(globalData, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), &s_info);
    123123        }
    124124
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r95503 r95666  
    129129        prototype = obj->prototype();
    130130        if (prototype.isNull()) {
    131             if (!putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(globalData, value)) && slot.isStrictMode())
     131            if (!putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(value)) && slot.isStrictMode())
    132132                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    133133            return;
     
    172172    }
    173173   
    174     if (!putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(globalData, value)) && slot.isStrictMode())
     174    if (!putDirectInternal(globalData, propertyName, value, 0, true, slot, getJSFunction(value)) && slot.isStrictMode())
    175175        throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    176176    return;
     
    185185void JSObject::putWithAttributes(JSGlobalData* globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
    186186{
    187     putDirectInternal(*globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(*globalData, value));
     187    putDirectInternal(*globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(value));
    188188}
    189189
     
    191191{
    192192    PutPropertySlot slot;
    193     putDirectInternal(*globalData, propertyName, value, attributes, true, slot, getJSFunction(*globalData, value));
     193    putDirectInternal(*globalData, propertyName, value, attributes, true, slot, getJSFunction(value));
    194194}
    195195
     
    202202{
    203203    JSGlobalData& globalData = exec->globalData();
    204     putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
     204    putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(value));
    205205}
    206206
     
    209209    PutPropertySlot slot;
    210210    JSGlobalData& globalData = exec->globalData();
    211     putDirectInternal(globalData, propertyName, value, attributes, true, slot, getJSFunction(globalData, value));
     211    putDirectInternal(globalData, propertyName, value, attributes, true, slot, getJSFunction(value));
    212212}
    213213
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r95516 r95666  
    4040namespace JSC {
    4141
    42     inline JSCell* getJSFunction(JSGlobalData& globalData, JSValue value)
     42    inline JSCell* getJSFunction(JSValue value)
    4343    {
    44         if (value.isCell() && (value.asCell()->vptr() == globalData.jsFunctionVPtr))
     44        if (value.isCell() && (value.asCell()->structure()->typeInfo().type() == JSFunctionType))
    4545            return value.asCell();
    4646        return 0;
     
    703703    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
    704704
    705     return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
     705    return putDirectInternal(globalData, propertyName, value, attributes, checkReadOnly, slot, getJSFunction(value));
    706706}
    707707
     
    709709{
    710710    PutPropertySlot slot;
    711     putDirectInternal(globalData, propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
     711    putDirectInternal(globalData, propertyName, value, attributes, false, slot, getJSFunction(value));
    712712}
    713713
    714714inline bool JSObject::putDirect(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
    715715{
    716     return putDirectInternal(globalData, propertyName, value, 0, false, slot, getJSFunction(globalData, value));
     716    return putDirectInternal(globalData, propertyName, value, 0, false, slot, getJSFunction(value));
    717717}
    718718
     
    720720{
    721721    size_t currentCapacity = structure()->propertyStorageCapacity();
    722     size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(globalData, value));
     722    size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value));
    723723    if (currentCapacity != structure()->propertyStorageCapacity())
    724724        allocatePropertyStorage(globalData, currentCapacity, structure()->propertyStorageCapacity());
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r95358 r95666  
    4141    ObjectType          = 10,
    4242    FinalObjectType     = 11,
     43    JSFunctionType      = 12,
    4344};
    4445
Note: See TracChangeset for help on using the changeset viewer.