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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.