Changeset 120974 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Jun 21, 2012, 3:55:42 PM (13 years ago)
Author:
[email protected]
Message:

DFG should inline 'new Array()'
https://bugs.webkit.org/show_bug.cgi?id=89632

Reviewed by Geoffrey Garen.

This adds support for treating InternalFunction like intrinsics. The code
to do so is actually quite clean, so I don't feel bad about perpetuating
the InternalFunction vs. JSFunction-with-NativeExecutable dichotomy.

Currently this newfound power is only used to inline 'new Array()'.

  • dfg/DFGByteCodeParser.cpp:

(ByteCodeParser):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(DFG):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::isInternalFunctionConstant):
(JSC::DFG::Graph::valueOfInternalFunctionConstant):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r120970 r120974  
     12012-06-20  Filip Pizlo  <[email protected]>
     2
     3        DFG should inline 'new Array()'
     4        https://bugs.webkit.org/show_bug.cgi?id=89632
     5
     6        Reviewed by Geoffrey Garen.
     7       
     8        This adds support for treating InternalFunction like intrinsics. The code
     9        to do so is actually quite clean, so I don't feel bad about perpetuating
     10        the InternalFunction vs. JSFunction-with-NativeExecutable dichotomy.
     11       
     12        Currently this newfound power is only used to inline 'new Array()'.
     13       
     14        * dfg/DFGByteCodeParser.cpp:
     15        (ByteCodeParser):
     16        (JSC::DFG::ByteCodeParser::handleCall):
     17        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
     18        (DFG):
     19        * dfg/DFGGraph.h:
     20        (JSC::DFG::Graph::isInternalFunctionConstant):
     21        (JSC::DFG::Graph::valueOfInternalFunctionConstant):
     22
    1232012-06-21  Mark Hahnenberg  <[email protected]>
    224
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r120897 r120974  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "ArrayConstructor.h"
    3132#include "CallLinkStatus.h"
    3233#include "CodeBlock.h"
     
    9697    // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
    9798    bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
     99    bool handleConstantInternalFunction(bool usesResult, int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind);
    98100    void handleGetByOffset(
    99101        int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
     
    11291131   
    11301132    NodeIndex callTarget = get(currentInstruction[1].u.operand);
    1131     enum { ConstantFunction, LinkedFunction, UnknownFunction } callType;
     1133    enum {
     1134        ConstantFunction,
     1135        ConstantInternalFunction,
     1136        LinkedFunction,
     1137        UnknownFunction
     1138    } callType;
    11321139           
    11331140    CallLinkStatus callLinkStatus = CallLinkStatus::computeFor(
     
    11511158                m_graph.valueOfFunctionConstant(callTarget),
    11521159                m_graph.valueOfFunctionConstant(callTarget)->executable());
     1160#endif
     1161    } else if (m_graph.isInternalFunctionConstant(callTarget)) {
     1162        callType = ConstantInternalFunction;
     1163#if DFG_ENABLE(DEBUG_VERBOSE)
     1164        dataLog("Call at [@%lu, bc#%u] has an internal function constant: %p.\n",
     1165                m_graph.size(), m_currentIndex,
     1166                m_graph.valueOfInternalFunctionConstant(callTarget));
    11531167#endif
    11541168    } else if (callLinkStatus.isSet() && !callLinkStatus.couldTakeSlowPath()
     
    11841198            nextOffset += OPCODE_LENGTH(op_call_put_result);
    11851199        }
     1200
     1201        if (callType == ConstantInternalFunction) {
     1202            if (handleConstantInternalFunction(usesResult, resultOperand, m_graph.valueOfInternalFunctionConstant(callTarget), registerOffset, argumentCountIncludingThis, prediction, kind))
     1203                return;
     1204           
     1205            // Can only handle this using the generic call handler.
     1206            addCall(interpreter, currentInstruction, op);
     1207            return;
     1208        }
     1209       
    11861210        JSFunction* expectedFunction;
    11871211        Intrinsic intrinsic;
     
    12151239            return;
    12161240    }
    1217            
     1241   
    12181242    addCall(interpreter, currentInstruction, op);
    12191243}
     
    15701594        return false;
    15711595    }
     1596}
     1597
     1598bool ByteCodeParser::handleConstantInternalFunction(
     1599    bool usesResult, int resultOperand, InternalFunction* function, int registerOffset,
     1600    int argumentCountIncludingThis, SpeculatedType prediction, CodeSpecializationKind kind)
     1601{
     1602    // If we ever find that we have a lot of internal functions that we specialize for,
     1603    // then we should probably have some sort of hashtable dispatch, or maybe even
     1604    // dispatch straight through the MethodTable of the InternalFunction. But for now,
     1605    // it seems that this case is hit infrequently enough, and the number of functions
     1606    // we know about is small enough, that having just a linear cascade of if statements
     1607    // is good enough.
     1608   
     1609    UNUSED_PARAM(registerOffset); // Remove this once we do more things to the arguments.
     1610    UNUSED_PARAM(prediction); // Remove this once we do more things.
     1611    UNUSED_PARAM(kind); // Remove this once we do more things.
     1612   
     1613    if (function->classInfo() == &ArrayConstructor::s_info) {
     1614        // We could handle this but don't for now.
     1615        if (argumentCountIncludingThis != 1)
     1616            return false;
     1617       
     1618        setIntrinsicResult(
     1619            usesResult, resultOperand,
     1620            addToGraph(Node::VarArg, NewArray, OpInfo(0), OpInfo(0)));
     1621        return true;
     1622    }
     1623   
     1624    return false;
    15721625}
    15731626
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r120834 r120974  
    278278        return true;
    279279    }
     280    bool isInternalFunctionConstant(NodeIndex nodeIndex)
     281    {
     282        if (!isJSConstant(nodeIndex))
     283            return false;
     284        JSValue value = valueOfJSConstant(nodeIndex);
     285        if (!value.isCell() || !value)
     286            return false;
     287        JSCell* cell = value.asCell();
     288        if (!cell->inherits(&InternalFunction::s_info))
     289            return false;
     290        return true;
     291    }
    280292    // Helper methods get constant values from nodes.
    281293    JSValue valueOfJSConstant(NodeIndex nodeIndex)
     
    300312        ASSERT(function);
    301313        return jsCast<JSFunction*>(function);
     314    }
     315    InternalFunction* valueOfInternalFunctionConstant(NodeIndex nodeIndex)
     316    {
     317        return jsCast<InternalFunction*>(valueOfJSConstant(nodeIndex).asCell());
    302318    }
    303319
Note: See TracChangeset for help on using the changeset viewer.