Changeset 90423 in webkit


Ignore:
Timestamp:
Jul 5, 2011 5:56:49 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-07-05 Filip Pizlo <fpizlo@apple.com>

DFG JIT does not implement op_call.
https://bugs.webkit.org/show_bug.cgi?id=63858

Reviewed by Gavin Barraclough.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::unlinkCalls):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::setNumberOfCallLinkInfos): (JSC::CodeBlock::numberOfCallLinkInfos):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitCall): (JSC::BytecodeGenerator::emitConstruct):
  • dfg/DFGAliasTracker.h: (JSC::DFG::AliasTracker::lookupGetByVal): (JSC::DFG::AliasTracker::recordCall): (JSC::DFG::AliasTracker::equalIgnoringLaterNumericConversion):
  • dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::ByteCodeParser): (JSC::DFG::ByteCodeParser::getLocal): (JSC::DFG::ByteCodeParser::getArgument): (JSC::DFG::ByteCodeParser::toInt32): (JSC::DFG::ByteCodeParser::addToGraph): (JSC::DFG::ByteCodeParser::addVarArgChild): (JSC::DFG::ByteCodeParser::predictInt32): (JSC::DFG::ByteCodeParser::parseBlock): (JSC::DFG::ByteCodeParser::processPhiStack): (JSC::DFG::ByteCodeParser::allocateVirtualRegisters):
  • dfg/DFGGraph.cpp: (JSC::DFG::Graph::opName): (JSC::DFG::Graph::dump): (JSC::DFG::Graph::refChildren):
  • dfg/DFGGraph.h:
  • dfg/DFGJITCodeGenerator.cpp: (JSC::DFG::JITCodeGenerator::useChildren): (JSC::DFG::JITCodeGenerator::emitCall):
  • dfg/DFGJITCodeGenerator.h: (JSC::DFG::JITCodeGenerator::addressOfCallData):
  • dfg/DFGJITCompiler.cpp: (JSC::DFG::JITCompiler::compileFunction):
  • dfg/DFGJITCompiler.h: (JSC::DFG::CallRecord::CallRecord): (JSC::DFG::JITCompiler::notifyCall): (JSC::DFG::JITCompiler::appendCallWithFastExceptionCheck): (JSC::DFG::JITCompiler::addJSCall): (JSC::DFG::JITCompiler::PropertyAccessRecord::PropertyAccessRecord): (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
  • dfg/DFGNode.h: (JSC::DFG::Node::Node): (JSC::DFG::Node::child1): (JSC::DFG::Node::child2): (JSC::DFG::Node::child3): (JSC::DFG::Node::firstChild): (JSC::DFG::Node::numChildren):
  • dfg/DFGNonSpeculativeJIT.cpp: (JSC::DFG::NonSpeculativeJIT::basicArithOp): (JSC::DFG::NonSpeculativeJIT::compare): (JSC::DFG::NonSpeculativeJIT::compile):
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGRepatch.cpp: (JSC::DFG::dfgLinkCall):
  • dfg/DFGRepatch.h:
  • dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch): (JSC::DFG::SpeculativeJIT::compilePeepHoleCall): (JSC::DFG::SpeculativeJIT::compile):
  • dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
  • interpreter/CallFrame.h: (JSC::ExecState::calleeAsValue):
  • jit/JIT.cpp: (JSC::JIT::JIT): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::privateCompile): (JSC::JIT::linkCall): (JSC::JIT::linkConstruct):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCall):
  • jit/JITCode.h: (JSC::JITCode::JITCode): (JSC::JITCode::jitType): (JSC::JITCode::HostFunction):
  • runtime/JSFunction.h:
  • runtime/JSGlobalData.h:
Location:
trunk/Source/JavaScriptCore
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r90421 r90423  
     12011-07-05  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG JIT does not implement op_call.
     4        https://bugs.webkit.org/show_bug.cgi?id=63858
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        * bytecode/CodeBlock.cpp:
     9        (JSC::CodeBlock::unlinkCalls):
     10        * bytecode/CodeBlock.h:
     11        (JSC::CodeBlock::setNumberOfCallLinkInfos):
     12        (JSC::CodeBlock::numberOfCallLinkInfos):
     13        * bytecompiler/BytecodeGenerator.cpp:
     14        (JSC::BytecodeGenerator::emitCall):
     15        (JSC::BytecodeGenerator::emitConstruct):
     16        * dfg/DFGAliasTracker.h:
     17        (JSC::DFG::AliasTracker::lookupGetByVal):
     18        (JSC::DFG::AliasTracker::recordCall):
     19        (JSC::DFG::AliasTracker::equalIgnoringLaterNumericConversion):
     20        * dfg/DFGByteCodeParser.cpp:
     21        (JSC::DFG::ByteCodeParser::ByteCodeParser):
     22        (JSC::DFG::ByteCodeParser::getLocal):
     23        (JSC::DFG::ByteCodeParser::getArgument):
     24        (JSC::DFG::ByteCodeParser::toInt32):
     25        (JSC::DFG::ByteCodeParser::addToGraph):
     26        (JSC::DFG::ByteCodeParser::addVarArgChild):
     27        (JSC::DFG::ByteCodeParser::predictInt32):
     28        (JSC::DFG::ByteCodeParser::parseBlock):
     29        (JSC::DFG::ByteCodeParser::processPhiStack):
     30        (JSC::DFG::ByteCodeParser::allocateVirtualRegisters):
     31        * dfg/DFGGraph.cpp:
     32        (JSC::DFG::Graph::opName):
     33        (JSC::DFG::Graph::dump):
     34        (JSC::DFG::Graph::refChildren):
     35        * dfg/DFGGraph.h:
     36        * dfg/DFGJITCodeGenerator.cpp:
     37        (JSC::DFG::JITCodeGenerator::useChildren):
     38        (JSC::DFG::JITCodeGenerator::emitCall):
     39        * dfg/DFGJITCodeGenerator.h:
     40        (JSC::DFG::JITCodeGenerator::addressOfCallData):
     41        * dfg/DFGJITCompiler.cpp:
     42        (JSC::DFG::JITCompiler::compileFunction):
     43        * dfg/DFGJITCompiler.h:
     44        (JSC::DFG::CallRecord::CallRecord):
     45        (JSC::DFG::JITCompiler::notifyCall):
     46        (JSC::DFG::JITCompiler::appendCallWithFastExceptionCheck):
     47        (JSC::DFG::JITCompiler::addJSCall):
     48        (JSC::DFG::JITCompiler::PropertyAccessRecord::PropertyAccessRecord):
     49        (JSC::DFG::JITCompiler::JSCallRecord::JSCallRecord):
     50        * dfg/DFGNode.h:
     51        (JSC::DFG::Node::Node):
     52        (JSC::DFG::Node::child1):
     53        (JSC::DFG::Node::child2):
     54        (JSC::DFG::Node::child3):
     55        (JSC::DFG::Node::firstChild):
     56        (JSC::DFG::Node::numChildren):
     57        * dfg/DFGNonSpeculativeJIT.cpp:
     58        (JSC::DFG::NonSpeculativeJIT::basicArithOp):
     59        (JSC::DFG::NonSpeculativeJIT::compare):
     60        (JSC::DFG::NonSpeculativeJIT::compile):
     61        * dfg/DFGOperations.cpp:
     62        * dfg/DFGOperations.h:
     63        * dfg/DFGRepatch.cpp:
     64        (JSC::DFG::dfgLinkCall):
     65        * dfg/DFGRepatch.h:
     66        * dfg/DFGSpeculativeJIT.cpp:
     67        (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
     68        (JSC::DFG::SpeculativeJIT::compilePeepHoleCall):
     69        (JSC::DFG::SpeculativeJIT::compile):
     70        * dfg/DFGSpeculativeJIT.h:
     71        (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
     72        * interpreter/CallFrame.h:
     73        (JSC::ExecState::calleeAsValue):
     74        * jit/JIT.cpp:
     75        (JSC::JIT::JIT):
     76        (JSC::JIT::privateCompileMainPass):
     77        (JSC::JIT::privateCompileSlowCases):
     78        (JSC::JIT::privateCompile):
     79        (JSC::JIT::linkCall):
     80        (JSC::JIT::linkConstruct):
     81        * jit/JITCall.cpp:
     82        (JSC::JIT::compileOpCall):
     83        * jit/JITCode.h:
     84        (JSC::JITCode::JITCode):
     85        (JSC::JITCode::jitType):
     86        (JSC::JITCode::HostFunction):
     87        * runtime/JSFunction.h:
     88        * runtime/JSGlobalData.h:
     89
    1902011-07-05  Oliver Hunt  <oliver@apple.com>
    291
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r90415 r90423  
    4444#include <wtf/StringExtras.h>
    4545
     46#if ENABLE(DFG_JIT)
     47#include "DFGOperations.h"
     48#endif
     49
    4650#define DUMP_CODE_BLOCK_STATISTICS 0
    4751
    4852namespace JSC {
     53
     54#if ENABLE(DFG_JIT)
     55using namespace DFG;
     56#endif
    4957
    5058#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
     
    17401748        if (!m_callLinkInfos[i].isLinked())
    17411749            continue;
    1742         repatchBuffer.relink(m_callLinkInfos[i].callReturnLocation, m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink());
     1750        if (getJITCode().jitType() == JITCode::DFGJIT) {
     1751#if ENABLE(DFG_JIT)
     1752            repatchBuffer.relink(CodeLocationCall(m_callLinkInfos[i].callReturnLocation), operationLinkCall);
     1753#else
     1754            ASSERT_NOT_REACHED();
     1755#endif
     1756        } else
     1757            repatchBuffer.relink(CodeLocationNearCall(m_callLinkInfos[i].callReturnLocation), m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink());
    17431758        m_callLinkInfos[i].unlink();
    17441759    }
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r89954 r90423  
    103103        }
    104104
    105         CodeLocationNearCall callReturnLocation;
     105        CodeLocationLabel callReturnLocation; // it's a near call in the old JIT, or a normal call in DFG
    106106        CodeLocationDataLabelPtr hotPathBegin;
    107107        CodeLocationNearCall hotPathOther;
     
    379379        bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
    380380
     381        void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); }
    381382        size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
    382         void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
    383383        CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
    384384
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r90371 r90423  
    17531753    emitExpressionInfo(divot, startOffset, endOffset);
    17541754
    1755 #if ENABLE(JIT)
    1756     m_codeBlock->addCallLinkInfo();
    1757 #endif
    1758 
    17591755    // Emit call.
    17601756    emitOpcode(opcodeID);
     
    18691865
    18701866    emitExpressionInfo(divot, startOffset, endOffset);
    1871 
    1872 #if ENABLE(JIT)
    1873     m_codeBlock->addCallLinkInfo();
    1874 #endif
    18751867
    18761868    emitOpcode(op_construct);
  • trunk/Source/JavaScriptCore/dfg/DFGAliasTracker.h

    r89611 r90423  
    6161            // integer index (this is good enough; the speculative path will only generate
    6262            // optimized accesses to handle integer subscripts).
    63             if (possibleAlias.child1 == base && equalIgnoringLaterNumericConversion(possibleAlias.child2, property))
     63            if (possibleAlias.child1() == base && equalIgnoringLaterNumericConversion(possibleAlias.child2(), property))
    6464                return m_candidateAliasGetByVal;
    6565        }
     
    9595        m_candidateAliasGetByVal = NoNode;
    9696    }
     97   
     98    void recordCall(NodeIndex call)
     99    {
     100        ASSERT_UNUSED(call, m_graph[call].op == Call);
     101        m_candidateAliasGetByVal = NoNode;
     102    }
    97103
    98104private:
     
    107113            return true;
    108114        Node& node2 = m_graph[op2];
    109         return (node2.op == ValueToNumber || node2.op == ValueToInt32) && op1 == node2.child1;
     115        return (node2.op == ValueToNumber || node2.op == ValueToInt32) && op1 == node2.child1();
    110116    }
    111117
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r90371 r90423  
    6363        , m_numLocals(codeBlock->m_numCalleeRegisters)
    6464        , m_preservedVars(codeBlock->m_numVars)
     65        , m_parameterSlots(0)
     66        , m_numPassedVarArgs(0)
    6567    {
    6668    }
     
    125127                return nodeIndex;
    126128            ASSERT(node.op == SetLocal);
    127             return node.child1;
     129            return node.child1();
    128130        }
    129131
     
    156158                return nodeIndex;
    157159            ASSERT(node.op == SetLocal);
    158             return node.child1;
     160            return node.child1();
    159161        }
    160162
     
    192194
    193195        if (node.op == UInt32ToNumber)
    194             return node.child1;
     196            return node.child1();
    195197
    196198        // Check for numeric constants boxed as JSValues.
     
    383385        return resultIndex;
    384386    }
     387   
     388    NodeIndex addToGraph(Node::VarArgTag, NodeType op)
     389    {
     390        NodeIndex resultIndex = (NodeIndex)m_graph.size();
     391        m_graph.append(Node(Node::VarArg, op, m_currentIndex, m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs));
     392       
     393        m_numPassedVarArgs = 0;
     394       
     395        if (op & NodeMustGenerate)
     396            m_graph.ref(resultIndex);
     397        return resultIndex;
     398    }
     399    void addVarArgChild(NodeIndex child)
     400    {
     401        m_graph.m_varArgChildren.append(child);
     402        m_numPassedVarArgs++;
     403    }
    385404
    386405    void predictArray(NodeIndex nodeIndex)
     
    397416
    398417        if (nodePtr->op == ValueToNumber)
    399             nodePtr = &m_graph[nodePtr->child1];
     418            nodePtr = &m_graph[nodePtr->child1()];
    400419
    401420        if (nodePtr->op == ValueToInt32)
    402             nodePtr = &m_graph[nodePtr->child1];
     421            nodePtr = &m_graph[nodePtr->child1()];
    403422
    404423        if (nodePtr->op == GetLocal)
     
    454473    // temporaries that persist across blocks (dues to ?:, &&, ||, etc).
    455474    unsigned m_preservedVars;
     475    // The number of slots (in units of sizeof(Register)) that we need to
     476    // preallocate for calls emanating from this frame. This includes the
     477    // size of the CallFrame, only if this is not a leaf function.  (I.e.
     478    // this is 0 if and only if this function is a leaf.)
     479    unsigned m_parameterSlots;
     480    // The number of var args passed to the next var arg node.
     481    unsigned m_numPassedVarArgs;
    456482
    457483    struct PhiStackEntry {
     
    10401066            LAST_OPCODE(op_ret);
    10411067        }
     1068           
     1069        case op_call: {
     1070            addVarArgChild(get(currentInstruction[1].u.operand));
     1071            int argCount = currentInstruction[2].u.operand;
     1072            int registerOffset = currentInstruction[3].u.operand;
     1073            int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize;
     1074            for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++)
     1075                addVarArgChild(get(argIdx));
     1076            NodeIndex call = addToGraph(Node::VarArg, Call);
     1077            aliases.recordCall(call);
     1078            Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
     1079            if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
     1080                set(putInstruction[1].u.operand, call);
     1081            if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)
     1082                m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;
     1083            NEXT_OPCODE(op_call);
     1084        }
     1085           
     1086        case op_call_put_result: {
     1087#if !ASSERT_DISABLED
     1088            Instruction* callInstruction = currentInstruction - OPCODE_LENGTH(op_call);
     1089            ASSERT(interpreter->getOpcodeID(callInstruction->u.opcode) == op_call);
     1090#endif
     1091            NEXT_OPCODE(op_call_put_result);
     1092        }
    10421093
    10431094        default:
     
    10721123                phiStack.append(PhiStackEntry(predecessorBlock, valueInPredecessor, varNo));
    10731124            } else if (m_graph[valueInPredecessor].op == GetLocal)
    1074                 valueInPredecessor = m_graph[valueInPredecessor].child1;
     1125                valueInPredecessor = m_graph[valueInPredecessor].child1();
    10751126            ASSERT(m_graph[valueInPredecessor].op == SetLocal || m_graph[valueInPredecessor].op == Phi);
    10761127
     
    10781129                m_graph.ref(valueInPredecessor);
    10791130
    1080             if (phiNode.child1 == NoNode) {
    1081                 phiNode.child1 = valueInPredecessor;
     1131            if (phiNode.child1() == NoNode) {
     1132                phiNode.children.fixed.child1 = valueInPredecessor;
    10821133                continue;
    10831134            }
    1084             if (phiNode.child2 == NoNode) {
    1085                 phiNode.child2 = valueInPredecessor;
     1135            if (phiNode.child2() == NoNode) {
     1136                phiNode.children.fixed.child2 = valueInPredecessor;
    10861137                continue;
    10871138            }
    1088             if (phiNode.child3 == NoNode) {
    1089                 phiNode.child3 = valueInPredecessor;
     1139            if (phiNode.child3() == NoNode) {
     1140                phiNode.children.fixed.child3 = valueInPredecessor;
    10901141                continue;
    10911142            }
     
    10961147                m_graph.ref(newPhi);
    10971148
    1098             newPhiNode.child1 = phiNode.child1;
    1099             newPhiNode.child2 = phiNode.child2;
    1100             newPhiNode.child3 = phiNode.child3;
    1101 
    1102             phiNode.child1 = newPhi;
    1103             phiNode.child1 = valueInPredecessor;
    1104             phiNode.child3 = NoNode;
     1149            newPhiNode.children.fixed.child1 = phiNode.child1();
     1150            newPhiNode.children.fixed.child2 = phiNode.child2();
     1151            newPhiNode.children.fixed.child3 = phiNode.child3();
     1152
     1153            phiNode.children.fixed.child1 = newPhi;
     1154            phiNode.children.fixed.child1 = valueInPredecessor;
     1155            phiNode.children.fixed.child3 = NoNode;
    11051156        }
    11061157    }
     
    11301181    for (size_t i = 0; i < sizeExcludingPhiNodes; ++i) {
    11311182        Node& node = m_graph[i];
     1183       
    11321184        if (!node.shouldGenerate())
    11331185            continue;
    1134 
     1186       
    11351187        // GetLocal nodes are effectively phi nodes in the graph, referencing
    11361188        // results from prior blocks.
     
    11401192            // order so that if a child is on its last use, and a
    11411193            // VirtualRegister is freed, then it may be reused for node.
    1142             scoreBoard.use(node.child1);
    1143             scoreBoard.use(node.child2);
    1144             scoreBoard.use(node.child3);
     1194            if (node.op & NodeHasVarArgs) {
     1195                for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
     1196                    scoreBoard.use(m_graph.m_varArgChildren[childIdx]);
     1197            } else {
     1198                scoreBoard.use(node.child1());
     1199                scoreBoard.use(node.child2());
     1200                scoreBoard.use(node.child3());
     1201            }
    11451202        }
    11461203
     
    11581215    // for the function (and checked for on entry). Since we perform a new and
    11591216    // different allocation of temporaries, more registers may now be required.
    1160     unsigned calleeRegisters = scoreBoard.allocatedCount() + m_preservedVars;
     1217    unsigned calleeRegisters = scoreBoard.allocatedCount() + m_preservedVars + m_parameterSlots;
    11611218    if ((unsigned)m_codeBlock->m_numCalleeRegisters < calleeRegisters)
    11621219        m_codeBlock->m_numCalleeRegisters = calleeRegisters;
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r89611 r90423  
    4242};
    4343
     44const char *Graph::opName(NodeType op)
     45{
     46    return dfgOpNames[op & NodeIdMask];
     47}
     48
    4449void Graph::dump(NodeIndex nodeIndex, CodeBlock* codeBlock)
    4550{
     
    7681    else
    7782        printf("-");
    78     printf(">\t%s(", dfgOpNames[op & NodeIdMask]);
    79     if (node.child1 != NoNode)
    80         printf("@%u", node.child1);
    81     if (node.child2 != NoNode)
    82         printf(", @%u", node.child2);
    83     if (node.child3 != NoNode)
    84         printf(", @%u", node.child3);
    85     bool hasPrinted = node.child1 != NoNode;
     83    printf(">\t%s(", opName(op));
     84    bool hasPrinted;
     85    if (op & NodeHasVarArgs) {
     86        for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++) {
     87            if (hasPrinted)
     88                printf(", ");
     89            else
     90                hasPrinted = true;
     91            printf("@%u", m_varArgChildren[childIdx]);
     92        }
     93    } else {
     94        if (node.child1() != NoNode)
     95            printf("@%u", node.child1());
     96        if (node.child2() != NoNode)
     97            printf(", @%u", node.child2());
     98        if (node.child3() != NoNode)
     99            printf(", @%u", node.child3());
     100        hasPrinted = node.child1() != NoNode;
     101    }
    86102
    87103    if (node.hasVarNumber()) {
     
    139155    Node& node = at(op);
    140156
    141     if (node.child1 == NoNode) {
    142         ASSERT(node.child2 == NoNode && node.child3 == NoNode);
    143         return;
     157    if (node.op & NodeHasVarArgs) {
     158        for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
     159            ref(m_varArgChildren[childIdx]);
     160    } else {
     161        if (node.child1() == NoNode) {
     162            ASSERT(node.child2() == NoNode && node.child3() == NoNode);
     163            return;
     164        }
     165        ref(node.child1());
     166
     167        if (node.child2() == NoNode) {
     168            ASSERT(node.child3() == NoNode);
     169            return;
     170        }
     171        ref(node.child2());
     172
     173        if (node.child3() == NoNode)
     174            return;
     175        ref(node.child3());
    144176    }
    145     ref(node.child1);
    146 
    147     if (node.child2 == NoNode) {
    148         ASSERT(node.child3 == NoNode);
    149         return;
    150     }
    151     ref(node.child2);
    152 
    153     if (node.child3 == NoNode)
    154         return;
    155     ref(node.child3);
    156177}
    157178
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r84860 r90423  
    161161    }
    162162
     163#ifndef NDEBUG
     164    static const char *opName(NodeType);
     165#endif
     166
    163167    Vector< OwnPtr<BasicBlock> , 8> m_blocks;
     168    Vector<NodeIndex, 16> m_varArgChildren;
    164169private:
    165170
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r90193 r90423  
    301301void JITCodeGenerator::useChildren(Node& node)
    302302{
    303     NodeIndex child1 = node.child1;
    304     if (child1 == NoNode) {
    305         ASSERT(node.child2 == NoNode && node.child3 == NoNode);
    306         return;
    307     }
    308     use(child1);
    309 
    310     NodeIndex child2 = node.child2;
    311     if (child2 == NoNode) {
    312         ASSERT(node.child3 == NoNode);
    313         return;
    314     }
    315     use(child2);
    316 
    317     NodeIndex child3 = node.child3;
    318     if (child3 == NoNode)
    319         return;
    320     use(child3);
     303    if (node.op & NodeHasVarArgs) {
     304        for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
     305            use(m_jit.graph().m_varArgChildren[childIdx]);
     306    } else {
     307        NodeIndex child1 = node.child1();
     308        if (child1 == NoNode) {
     309            ASSERT(node.child2() == NoNode && node.child3() == NoNode);
     310            return;
     311        }
     312        use(child1);
     313       
     314        NodeIndex child2 = node.child2();
     315        if (child2 == NoNode) {
     316            ASSERT(node.child3() == NoNode);
     317            return;
     318        }
     319        use(child2);
     320       
     321        NodeIndex child3 = node.child3();
     322        if (child3 == NoNode)
     323            return;
     324        use(child3);
     325    }
    321326}
    322327
     
    424429
    425430    m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToStore, callToSlowCase, callToDone, static_cast<int8_t>(baseGPR), static_cast<int8_t>(valueGPR), static_cast<int8_t>(scratchGPR));
     431}
     432
     433void JITCodeGenerator::emitCall(Node& node, GPRReg targetGPR)
     434{
     435    // the call instruction's first child is either the function (normal call) or the
     436    // receiver (method call). subsequent children are the arguments.
     437    int numArgs = node.numChildren() - 1;
     438   
     439    // amount of stuff (in units of sizeof(Register)) that we need to place at the
     440    // top of the JS stack.
     441    int callDataSize = 0;
     442
     443    // first there are the arguments
     444    callDataSize += numArgs;
     445   
     446    // and then there is the call frame header
     447    callDataSize += RegisterFile::CallFrameHeaderSize;
     448   
     449    m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numArgs))), addressOfCallData(RegisterFile::ArgumentCount));
     450    m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
     451   
     452    for (int argIdx = 0; argIdx < numArgs; argIdx++) {
     453        JSValueOperand arg(this, m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx]);
     454        GPRReg argGPR = arg.gpr();
     455       
     456        m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
     457    }
     458   
     459    switch (node.op) {
     460    case Call:
     461        m_jit.storePtr(targetGPR, addressOfCallData(RegisterFile::Callee));
     462        break;
     463       
     464    default:
     465        ASSERT_NOT_REACHED();
     466    }
     467   
     468    flushRegisters();
     469   
     470    GPRResult result(this);
     471    GPRReg resultGPR = result.gpr();
     472
     473    JITCompiler::DataLabelPtr targetToCheck;
     474    JITCompiler::Jump slowPath;
     475   
     476    switch (node.op) {
     477    case Call:
     478        slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, targetGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
     479        m_jit.loadPtr(MacroAssembler::Address(targetGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
     480        m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
     481        break;
     482       
     483    default:
     484        ASSERT_NOT_REACHED();
     485    }
     486
     487    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
     488   
     489    JITCompiler::Call fastCall = m_jit.nearCall();
     490    m_jit.notifyCall(fastCall, m_jit.graph()[m_compileIndex].exceptionInfo);
     491   
     492    JITCompiler::Jump done = m_jit.jump();
     493   
     494    slowPath.link(&m_jit);
     495   
     496    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     497    JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(operationLinkCall, m_jit.graph()[m_compileIndex].exceptionInfo);
     498    m_jit.move(Imm32(numArgs), GPRInfo::regT1);
     499    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
     500    m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), m_jit.graph()[m_compileIndex].exceptionInfo);
     501   
     502    done.link(&m_jit);
     503   
     504    m_jit.move(GPRInfo::returnValueGPR, resultGPR);
     505   
     506    jsValueResult(resultGPR, m_compileIndex);
     507   
     508    m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);
    426509}
    427510
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h

    r90193 r90423  
    523523    void cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
    524524    void cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
     525   
     526    MacroAssembler::Address addressOfCallData(int idx)
     527    {
     528        return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));
     529    }
     530   
     531    void emitCall(Node&, GPRReg targetGPR);
    525532
    526533    // Called once a node has completed code generation but prior to setting
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r90324 r90423  
    295295        m_calls.clear();
    296296        m_propertyAccesses.clear();
     297        m_jsCalls.clear();
    297298        rewindToLabel(speculativePathBegin);
    298299
     
    370371
    371372    // Link all calls out from the JIT code to their respective functions.
    372     for (unsigned i = 0; i < m_calls.size(); ++i)
    373         linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
     373    for (unsigned i = 0; i < m_calls.size(); ++i) {
     374        if (m_calls[i].m_function.value())
     375            linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
     376    }
    374377
    375378    if (m_codeBlock->needsCallReturnIndices()) {
    376379        m_codeBlock->callReturnIndexVector().reserveCapacity(exceptionCheckCount);
    377380        for (unsigned i = 0; i < m_calls.size(); ++i) {
    378             if (m_calls[i].m_exceptionCheck.isSet()) {
     381            if (m_calls[i].m_handlesExceptions) {
    379382                unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
    380383                unsigned exceptionInfo = m_calls[i].m_exceptionInfo;
     
    397400        info.u.unset.scratchGPR = m_propertyAccesses[i].m_scratchGPR;
    398401    }
    399 
     402   
     403    m_codeBlock->setNumberOfCallLinkInfos(m_jsCalls.size());
     404    for (unsigned i = 0; i < m_jsCalls.size(); ++i) {
     405        CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
     406        info.isCall = m_jsCalls[i].m_isCall;
     407        info.callReturnLocation = CodeLocationLabel(linkBuffer.locationOf(m_jsCalls[i].m_slowCall));
     408        info.hotPathBegin = linkBuffer.locationOf(m_jsCalls[i].m_targetToCheck);
     409        info.hotPathOther = linkBuffer.locationOfNearCall(m_jsCalls[i].m_fastCall);
     410    }
     411   
    400412    // FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs.
    401413    linkBuffer.link(callRegisterFileCheck, cti_register_file_check);
     
    403415
    404416    entryWithArityCheck = linkBuffer.locationOf(arityCheck);
    405     entry = linkBuffer.finalizeCode();
     417    entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
    406418}
    407419
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r90324 r90423  
    6666        : m_call(call)
    6767        , m_function(function)
     68        , m_handlesExceptions(false)
    6869    {
    6970    }
     
    7576        , m_exceptionCheck(exceptionCheck)
    7677        , m_exceptionInfo(exceptionInfo)
     78        , m_handlesExceptions(true)
     79    {
     80    }
     81
     82    // Constructor for a call that may cause exceptions, but which are handled
     83    // through some mechanism other than the in-line exception handler.
     84    CallRecord(MacroAssembler::Call call, FunctionPtr function, ExceptionInfo exceptionInfo)
     85        : m_call(call)
     86        , m_function(function)
     87        , m_exceptionInfo(exceptionInfo)
     88        , m_handlesExceptions(true)
    7789    {
    7890    }
     
    8294    MacroAssembler::Jump m_exceptionCheck;
    8395    ExceptionInfo m_exceptionInfo;
     96    bool m_handlesExceptions;
    8497};
    8598
     
    159172        return Address(GPRInfo::callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
    160173    }
     174   
     175    // Notify the JIT of a call that does not require linking.
     176    void notifyCall(Call call, unsigned exceptionInfo)
     177    {
     178        m_calls.append(CallRecord(call, FunctionPtr(), exceptionInfo));
     179    }
    161180
    162181    // Add a call out from JIT code, without an exception check.
     
    172191        Call functionCall = call();
    173192        Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception));
     193        m_calls.append(CallRecord(functionCall, function, exceptionCheck, exceptionInfo));
     194        return functionCall;
     195    }
     196   
     197    // Add a call out from JIT code, with a fast exception check that tests if the return value is zero.
     198    Call appendCallWithFastExceptionCheck(const FunctionPtr& function, unsigned exceptionInfo)
     199    {
     200        Call functionCall = call();
     201        Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR);
    174202        m_calls.append(CallRecord(functionCall, function, exceptionCheck, exceptionInfo));
    175203        return functionCall;
     
    240268        m_propertyAccesses.append(PropertyAccessRecord(functionCall, deltaCheckImmToCall, deltaCallToStructCheck, deltaCallToLoadOrStore, deltaCallToSlowCase, deltaCallToDone,  baseGPR, valueGPR, scratchGPR));
    241269    }
     270   
     271    void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, bool isCall, unsigned exceptionInfo)
     272    {
     273        m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, isCall, exceptionInfo));
     274    }
    242275
    243276private:
     
    262295
    263296    struct PropertyAccessRecord {
    264         PropertyAccessRecord(JITCompiler::Call functionCall, int8_t deltaCheckImmToCall, int8_t deltaCallToStructCheck, int8_t deltaCallToLoadOrStore, int8_t deltaCallToSlowCase, int8_t deltaCallToDone, int8_t baseGPR, int8_t valueGPR, int8_t scratchGPR)
     297        PropertyAccessRecord(Call functionCall, int8_t deltaCheckImmToCall, int8_t deltaCallToStructCheck, int8_t deltaCallToLoadOrStore, int8_t deltaCallToSlowCase, int8_t deltaCallToDone, int8_t baseGPR, int8_t valueGPR, int8_t scratchGPR)
    265298            : m_functionCall(functionCall)
    266299            , m_deltaCheckImmToCall(deltaCheckImmToCall)
     
    285318        int8_t m_scratchGPR;
    286319    };
     320   
     321    struct JSCallRecord {
     322        JSCallRecord(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, bool isCall, unsigned exceptionInfo)
     323            : m_fastCall(fastCall)
     324            , m_slowCall(slowCall)
     325            , m_targetToCheck(targetToCheck)
     326            , m_isCall(isCall)
     327            , m_exceptionInfo(exceptionInfo)
     328        {
     329        }
     330       
     331        Call m_fastCall;
     332        Call m_slowCall;
     333        DataLabelPtr m_targetToCheck;
     334        bool m_isCall;
     335        unsigned m_exceptionInfo;
     336    };
    287337
    288338    Vector<PropertyAccessRecord, 4> m_propertyAccesses;
     339    Vector<JSCallRecord, 4> m_jsCalls;
    289340};
    290341
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r90371 r90423  
    7777#define NodeIsBranch      0x80000
    7878#define NodeIsTerminal   0x100000
     79#define NodeHasVarArgs   0x200000
    7980
    8081// These values record the result type of the node (as checked by NodeResultMask, above), 0 for no result.
     
    139140    macro(CompareStrictEq, NodeResultJS) \
    140141    \
     142    /* Calls. */\
     143    macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     144    \
    141145    /* Nodes for misc operations. */\
    142146    macro(Breakpoint, NodeMustGenerate) \
     
    178182// Node represents a single operation in the data flow graph.
    179183struct Node {
     184    enum VarArgTag { VarArg };
     185
    180186    // Construct a node with up to 3 children, no immediate value.
    181187    Node(NodeType op, ExceptionInfo exceptionInfo, NodeIndex child1 = NoNode, NodeIndex child2 = NoNode, NodeIndex child3 = NoNode)
    182188        : op(op)
    183189        , exceptionInfo(exceptionInfo)
    184         , child1(child1)
    185         , child2(child2)
    186         , child3(child3)
    187190        , m_virtualRegister(InvalidVirtualRegister)
    188191        , m_refCount(0)
    189192    {
     193        ASSERT(!(op & NodeHasVarArgs));
     194        children.fixed.child1 = child1;
     195        children.fixed.child2 = child2;
     196        children.fixed.child3 = child3;
    190197    }
    191198
     
    194201        : op(op)
    195202        , exceptionInfo(exceptionInfo)
    196         , child1(child1)
    197         , child2(child2)
    198         , child3(child3)
    199203        , m_virtualRegister(InvalidVirtualRegister)
    200204        , m_refCount(0)
    201205        , m_opInfo(imm.m_value)
    202206    {
     207        ASSERT(!(op & NodeHasVarArgs));
     208        children.fixed.child1 = child1;
     209        children.fixed.child2 = child2;
     210        children.fixed.child3 = child3;
    203211    }
    204212
     
    207215        : op(op)
    208216        , exceptionInfo(exceptionInfo)
    209         , child1(child1)
    210         , child2(child2)
    211         , child3(child3)
    212217        , m_virtualRegister(InvalidVirtualRegister)
    213218        , m_refCount(0)
     
    215220        , m_opInfo2(imm2.m_value)
    216221    {
     222        ASSERT(!(op & NodeHasVarArgs));
     223        children.fixed.child1 = child1;
     224        children.fixed.child2 = child2;
     225        children.fixed.child3 = child3;
     226    }
     227   
     228    // Construct a node with a variable number of children and no immediate values.
     229    Node(VarArgTag, NodeType op, ExceptionInfo exceptionInfo, unsigned firstChild, unsigned numChildren)
     230        : op(op)
     231        , exceptionInfo(exceptionInfo)
     232        , m_virtualRegister(InvalidVirtualRegister)
     233        , m_refCount(0)
     234    {
     235        ASSERT(op & NodeHasVarArgs);
     236        children.variable.firstChild = firstChild;
     237        children.variable.numChildren = numChildren;
    217238    }
    218239
     
    355376        return mustGenerate() ? m_refCount - 1 : m_refCount;
    356377    }
    357 
     378   
     379    NodeIndex child1()
     380    {
     381        ASSERT(!(op & NodeHasVarArgs));
     382        return children.fixed.child1;
     383    }
     384
     385    NodeIndex child2()
     386    {
     387        ASSERT(!(op & NodeHasVarArgs));
     388        return children.fixed.child2;
     389    }
     390
     391    NodeIndex child3()
     392    {
     393        ASSERT(!(op & NodeHasVarArgs));
     394        return children.fixed.child3;
     395    }
     396   
     397    unsigned firstChild()
     398    {
     399        ASSERT(op & NodeHasVarArgs);
     400        return children.variable.firstChild;
     401    }
     402   
     403    unsigned numChildren()
     404    {
     405        ASSERT(op & NodeHasVarArgs);
     406        return children.variable.numChildren;
     407    }
     408   
    358409    // This enum value describes the type of the node.
    359410    NodeType op;
     
    361412    ExceptionInfo exceptionInfo;
    362413    // References to up to 3 children (0 for no child).
    363     NodeIndex child1, child2, child3;
     414    union {
     415        struct {
     416            NodeIndex child1, child2, child3;
     417        } fixed;
     418        struct {
     419            unsigned firstChild;
     420            unsigned numChildren;
     421        } variable;
     422    } children;
    364423
    365424private:
  • trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp

    r90371 r90423  
    266266void NonSpeculativeJIT::basicArithOp(NodeType op, Node &node)
    267267{
    268     JSValueOperand arg1(this, node.child1);
    269     JSValueOperand arg2(this, node.child2);
     268    JSValueOperand arg1(this, node.child1());
     269    JSValueOperand arg2(this, node.child2());
    270270   
    271271    GPRReg arg1GPR = arg1.gpr();
     
    278278    JITCompiler::JumpList slowPath;
    279279   
    280     if (!isKnownInteger(node.child1))
     280    if (!isKnownInteger(node.child1()))
    281281        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
    282     if (!isKnownInteger(node.child2))
     282    if (!isKnownInteger(node.child2()))
    283283        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
    284284   
     
    347347    // FIXME: should do some peephole to fuse compare/branch
    348348       
    349     JSValueOperand arg1(this, node.child1);
    350     JSValueOperand arg2(this, node.child2);
     349    JSValueOperand arg1(this, node.child1());
     350    JSValueOperand arg2(this, node.child2());
    351351    GPRReg arg1GPR = arg1.gpr();
    352352    GPRReg arg2GPR = arg2.gpr();
     
    357357    JITCompiler::JumpList slowPath;
    358358   
    359     if (!isKnownInteger(node.child1))
     359    if (!isKnownInteger(node.child1()))
    360360        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
    361     if (!isKnownInteger(node.child2))
     361    if (!isKnownInteger(node.child2()))
    362362        slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
    363363   
     
    398398    switch (op) {
    399399    case ConvertThis: {
    400         JSValueOperand thisValue(this, node.child1);
     400        JSValueOperand thisValue(this, node.child1());
    401401        GPRReg thisGPR = thisValue.gpr();
    402402        flushRegisters();
     
    425425
    426426    case SetLocal: {
    427         JSValueOperand value(this, node.child1);
     427        JSValueOperand value(this, node.child1());
    428428        m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
    429429        noResult(m_compileIndex);
     
    434434    case BitOr:
    435435    case BitXor:
    436         if (isInt32Constant(node.child1)) {
    437             IntegerOperand op2(this, node.child2);
     436        if (isInt32Constant(node.child1())) {
     437            IntegerOperand op2(this, node.child2());
    438438            GPRTemporary result(this, op2);
    439439
    440             bitOp(op, valueOfInt32Constant(node.child1), op2.gpr(), result.gpr());
     440            bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
    441441
    442442            integerResult(result.gpr(), m_compileIndex);
    443         } else if (isInt32Constant(node.child2)) {
    444             IntegerOperand op1(this, node.child1);
     443        } else if (isInt32Constant(node.child2())) {
     444            IntegerOperand op1(this, node.child1());
    445445            GPRTemporary result(this, op1);
    446446
    447             bitOp(op, valueOfInt32Constant(node.child2), op1.gpr(), result.gpr());
     447            bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
    448448
    449449            integerResult(result.gpr(), m_compileIndex);
    450450        } else {
    451             IntegerOperand op1(this, node.child1);
    452             IntegerOperand op2(this, node.child2);
     451            IntegerOperand op1(this, node.child1());
     452            IntegerOperand op2(this, node.child2());
    453453            GPRTemporary result(this, op1, op2);
    454454
     
    464464    case BitLShift:
    465465    case BitURShift:
    466         if (isInt32Constant(node.child2)) {
    467             IntegerOperand op1(this, node.child1);
     466        if (isInt32Constant(node.child2())) {
     467            IntegerOperand op1(this, node.child1());
    468468            GPRTemporary result(this, op1);
    469469
    470             int shiftAmount = valueOfInt32Constant(node.child2) & 0x1f;
     470            int shiftAmount = valueOfInt32Constant(node.child2()) & 0x1f;
    471471            // Shifts by zero should have been optimized out of the graph!
    472472            ASSERT(shiftAmount);
     
    476476        } else {
    477477            // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
    478             IntegerOperand op1(this, node.child1);
    479             IntegerOperand op2(this, node.child2);
     478            IntegerOperand op1(this, node.child1());
     479            IntegerOperand op2(this, node.child2());
    480480            GPRTemporary result(this, op1);
    481481
     
    489489
    490490    case UInt32ToNumber: {
    491         IntegerOperand op1(this, node.child1);
     491        IntegerOperand op1(this, node.child1());
    492492        FPRTemporary boxer(this);
    493493        GPRTemporary result(this, op1);
     
    514514
    515515    case ValueToInt32: {
    516         ASSERT(!isInt32Constant(node.child1));
    517 
    518         if (isKnownInteger(node.child1)) {
    519             IntegerOperand op1(this, node.child1);
     516        ASSERT(!isInt32Constant(node.child1()));
     517
     518        if (isKnownInteger(node.child1())) {
     519            IntegerOperand op1(this, node.child1());
    520520            GPRTemporary result(this, op1);
    521521            m_jit.move(op1.gpr(), result.gpr());
     
    524524        }
    525525
    526         GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister()];
     526        GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1()].virtualRegister()];
    527527        if ((childInfo.registerFormat() | DataFormatJS) == DataFormatJSDouble) {
    528             DoubleOperand op1(this, node.child1);
     528            DoubleOperand op1(this, node.child1());
    529529            GPRTemporary result(this);
    530530            numberToInt32(op1.fpr(), result.gpr());
     
    533533        }
    534534
    535         JSValueOperand op1(this, node.child1);
     535        JSValueOperand op1(this, node.child1());
    536536        GPRTemporary result(this, op1);
    537537        valueToInt32(op1, result.gpr());
     
    541541
    542542    case ValueToNumber: {
    543         ASSERT(!isInt32Constant(node.child1));
    544         ASSERT(!isDoubleConstant(node.child1));
    545 
    546         if (isKnownNumeric(node.child1)) {
    547             JSValueOperand op1(this, node.child1);
     543        ASSERT(!isInt32Constant(node.child1()));
     544        ASSERT(!isDoubleConstant(node.child1()));
     545
     546        if (isKnownNumeric(node.child1())) {
     547            JSValueOperand op1(this, node.child1());
    548548            GPRTemporary result(this, op1);
    549549            m_jit.move(op1.gpr(), result.gpr());
     
    552552        }
    553553
    554         JSValueOperand op1(this, node.child1);
     554        JSValueOperand op1(this, node.child1());
    555555        GPRTemporary result(this);
    556556        valueToNumber(op1, result.gpr());
     
    561561    case ValueAdd:
    562562    case ArithAdd: {
    563         if (isInt32Constant(node.child1)) {
    564             knownConstantArithOp(op, node.child2, node.child1, true);
     563        if (isInt32Constant(node.child1())) {
     564            knownConstantArithOp(op, node.child2(), node.child1(), true);
    565565            break;
    566566        }
    567567       
    568         if (isInt32Constant(node.child2)) {
    569             knownConstantArithOp(op, node.child1, node.child2, false);
     568        if (isInt32Constant(node.child2())) {
     569            knownConstantArithOp(op, node.child1(), node.child2(), false);
    570570            break;
    571571        }
     
    576576       
    577577    case ArithSub: {
    578         if (isInt32Constant(node.child2)) {
    579             knownConstantArithOp(ArithSub, node.child1, node.child2, false);
     578        if (isInt32Constant(node.child2())) {
     579            knownConstantArithOp(ArithSub, node.child1(), node.child2(), false);
    580580            break;
    581581        }
     
    591591
    592592    case ArithDiv: {
    593         DoubleOperand op1(this, node.child1);
    594         DoubleOperand op2(this, node.child2);
     593        DoubleOperand op1(this, node.child1());
     594        DoubleOperand op2(this, node.child2());
    595595        FPRTemporary result(this, op1);
    596596        FPRReg op1FPR = op1.fpr();
     
    605605
    606606    case ArithMod: {
    607         JSValueOperand op1(this, node.child1);
    608         JSValueOperand op2(this, node.child2);
     607        JSValueOperand op1(this, node.child1());
     608        JSValueOperand op2(this, node.child2());
    609609        GPRTemporary eax(this, X86Registers::eax);
    610610        GPRTemporary edx(this, X86Registers::edx);
     
    624624        JITCompiler::Jump modByZero;
    625625   
    626         if (!isKnownInteger(node.child1))
     626        if (!isKnownInteger(node.child1()))
    627627            firstOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op1GPR, GPRInfo::tagTypeNumberRegister);
    628         if (!isKnownInteger(node.child2))
     628        if (!isKnownInteger(node.child2()))
    629629            secondOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister);
    630630   
     
    656656        done.append(m_jit.jump());
    657657   
    658         if (!isKnownInteger(node.child1)) {
     658        if (!isKnownInteger(node.child1())) {
    659659            firstOpNotInt.link(&m_jit);
    660660       
    661661            JITCompiler::Jump secondOpNotInt2;
    662662       
    663             if (!isKnownInteger(node.child2))
     663            if (!isKnownInteger(node.child2()))
    664664                secondOpNotInt2 = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister);
    665665           
     
    667667            m_jit.convertInt32ToDouble(op2GPR, op2FPR);
    668668
    669             if (!isKnownInteger(node.child2)) {
     669            if (!isKnownInteger(node.child2())) {
    670670                JITCompiler::Jump gotSecondOp = m_jit.jump();
    671671           
     
    683683        }
    684684   
    685         if (!isKnownInteger(node.child2)) {
     685        if (!isKnownInteger(node.child2())) {
    686686            secondOpNotInt.link(&m_jit);
    687687       
     
    691691        }
    692692   
    693         if (!isKnownInteger(node.child1))
     693        if (!isKnownInteger(node.child1()))
    694694            gotDoubleArgs.link(&m_jit);
    695695   
    696         if (!isKnownInteger(node.child1) || !isKnownInteger(node.child2)) {
     696        if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
    697697            silentSpillAllRegisters(X86Registers::edx);
    698698            setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(op1FPR, op2FPR);
     
    709709
    710710    case LogicalNot: {
    711         JSValueOperand arg1(this, node.child1);
     711        JSValueOperand arg1(this, node.child1());
    712712        GPRTemporary result(this);
    713713
     
    758758
    759759    case GetByVal: {
    760         JSValueOperand base(this, node.child1);
    761         JSValueOperand property(this, node.child2);
     760        JSValueOperand base(this, node.child1());
     761        JSValueOperand property(this, node.child2());
    762762
    763763        GPRTemporary storage(this);
     
    810810    case PutByVal:
    811811    case PutByValAlias: {
    812         JSValueOperand arg1(this, node.child1);
    813         JSValueOperand arg2(this, node.child2);
    814         JSValueOperand arg3(this, node.child3);
     812        JSValueOperand arg1(this, node.child1());
     813        JSValueOperand arg2(this, node.child2());
     814        JSValueOperand arg3(this, node.child3());
    815815        GPRReg arg1GPR = arg1.gpr();
    816816        GPRReg arg2GPR = arg2.gpr();
     
    826826
    827827    case GetById: {
    828         JSValueOperand base(this, node.child1);
     828        JSValueOperand base(this, node.child1());
    829829        GPRReg baseGPR = base.gpr();
    830830        GPRTemporary result(this, base);
     
    840840
    841841    case PutById: {
    842         JSValueOperand base(this, node.child1);
    843         JSValueOperand value(this, node.child2);
     842        JSValueOperand base(this, node.child1());
     843        JSValueOperand value(this, node.child2());
    844844        GPRTemporary scratch(this);
    845845        GPRReg valueGPR = value.gpr();
     
    855855
    856856    case PutByIdDirect: {
    857         JSValueOperand base(this, node.child1);
    858         JSValueOperand value(this, node.child2);
     857        JSValueOperand base(this, node.child1());
     858        JSValueOperand value(this, node.child2());
    859859        GPRTemporary scratch(this);
    860860        GPRReg valueGPR = value.gpr();
     
    881881
    882882    case PutGlobalVar: {
    883         JSValueOperand value(this, node.child1);
     883        JSValueOperand value(this, node.child1());
    884884        GPRTemporary globalObject(this);
    885885        GPRTemporary scratch(this);
     
    908908
    909909    case Branch: {
    910         JSValueOperand value(this, node.child1);
     910        JSValueOperand value(this, node.child1());
    911911        GPRReg valueGPR = value.gpr();
    912912        flushRegisters();
     
    937937
    938938        // Return the result in returnValueGPR.
    939         JSValueOperand op1(this, node.child1);
     939        JSValueOperand op1(this, node.child1());
    940940        m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
    941941
     
    953953
    954954    case CheckHasInstance: {
    955         JSValueOperand base(this, node.child1);
     955        JSValueOperand base(this, node.child1());
    956956        GPRTemporary structure(this);
    957957
     
    981981
    982982    case InstanceOf: {
    983         JSValueOperand value(this, node.child1);
    984         JSValueOperand base(this, node.child2);
    985         JSValueOperand prototype(this, node.child3);
     983        JSValueOperand value(this, node.child1());
     984        JSValueOperand base(this, node.child2());
     985        JSValueOperand prototype(this, node.child3());
    986986        GPRTemporary scratch(this, base);
    987987
     
    10521052        ASSERT_NOT_REACHED();
    10531053#endif
     1054        break;
     1055       
     1056    case Call:
     1057        JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
     1058        GPRReg calleeGPR = callee.gpr();
     1059        emitCall(node, calleeGPR);
     1060        break;
    10541061    }
    10551062
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r90401 r90423  
    4343        "jmp _" STRINGIZE(function) "WithReturnAddress" "\n" \
    4444    );
     45#define FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
    4546#define FUNCTION_WRAPPER_WITH_ARG4_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
    4647#define FUNCTION_WRAPPER_WITH_ARG5_RETURN_ADDRESS(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
     
    398399}
    399400
     401EncodedJSValue getHostCallReturnValue();
     402EncodedJSValue getHostCallReturnValueWithExecState(ExecState*);
     403
     404asm (
     405".globl _" STRINGIZE(getHostCallReturnValue) "\n"
     406"_" STRINGIZE(getHostCallReturnValue) ":" "\n"
     407    "mov -40(%r13), %r13\n"
     408    "mov %r13, %rdi\n"
     409    "jmp _" STRINGIZE(getHostCallReturnValueWithExecState) "\n"
     410);
     411
     412EncodedJSValue getHostCallReturnValueWithExecState(ExecState* exec)
     413{
     414    return JSValue::encode(exec->globalData().hostCallReturnValue);
     415}
     416
     417static void* handleHostCall(ExecState* execCallee, JSValue callee)
     418{
     419    ExecState* exec = execCallee->callerFrame();
     420    JSGlobalData* globalData = &exec->globalData();
     421    CallData callData;
     422    CallType callType = getCallData(callee, callData);
     423   
     424    ASSERT(callType != CallTypeJS);
     425   
     426    if (callType == CallTypeHost) {
     427        if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
     428            globalData->exception = createStackOverflowError(exec);
     429            return 0;
     430        }
     431       
     432        execCallee->setScopeChain(exec->scopeChain());
     433       
     434        globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
     435       
     436        if (globalData->exception)
     437            return 0;
     438        return reinterpret_cast<void*>(getHostCallReturnValue);
     439    }
     440   
     441    ASSERT(callType == CallTypeNone);
     442    exec->globalData().exception = createNotAFunctionError(exec, callee);
     443    return 0;
     444}
     445
     446void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr);
     447FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
     448void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
     449{
     450    ExecState* exec = execCallee->callerFrame();
     451    JSGlobalData* globalData = &exec->globalData();
     452    JSValue calleeAsValue = execCallee->calleeAsValue();
     453    JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     454    if (!calleeAsFunctionCell)
     455        return handleHostCall(execCallee, calleeAsValue);
     456    JSFunction* callee = asFunction(calleeAsFunctionCell);
     457    ExecutableBase* executable = callee->executable();
     458   
     459    MacroAssemblerCodePtr codePtr;
     460    CodeBlock* codeBlock = 0;
     461    if (executable->isHostFunction())
     462        codePtr = executable->generatedJITCodeForCall().addressForCall();
     463    else {
     464        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
     465        JSObject* error = functionExecutable->compileForCall(exec, callee->scope());
     466        if (error) {
     467            globalData->exception = createStackOverflowError(exec);
     468            return 0;
     469        }
     470        codeBlock = &functionExecutable->generatedBytecodeForCall();
     471        if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
     472            codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
     473        else
     474            codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
     475        execCallee->setScopeChain(callee->scope());
     476    }
     477    CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
     478    if (!callLinkInfo.seenOnce())
     479        callLinkInfo.setSeen();
     480    else
     481        dfgLinkCall(execCallee, callLinkInfo, codeBlock, callee, codePtr);
     482    return codePtr.executableAddress();
     483}
     484
     485void* operationVirtualCall(ExecState* execCallee)
     486{
     487    ExecState* exec = execCallee->callerFrame();
     488    JSGlobalData* globalData = &exec->globalData();
     489    JSValue calleeAsValue = execCallee->calleeAsValue();
     490    JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     491    if (!calleeAsFunctionCell)
     492        return handleHostCall(execCallee, calleeAsValue);
     493   
     494    JSFunction* function = asFunction(calleeAsFunctionCell);
     495    ExecutableBase* executable = function->executable();
     496    if (executable->isHostFunction())
     497        return executable->generatedJITCodeForCall().addressForCall().executableAddress();
     498
     499    FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
     500    JSObject* error = functionExecutable->compileForCall(exec, function->scope());
     501    if (error) {
     502        exec->globalData().exception = error;
     503        return 0;
     504    }
     505    execCallee->setScopeChain(function->scope());
     506    return functionExecutable->generatedJITCodeForCallWithArityCheck().executableAddress();
     507}
     508
    400509EncodedJSValue operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, EncodedJSValue encodedPrototype)
    401510{
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r90371 r90423  
    8181bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
    8282bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
     83void* operationVirtualCall(ExecState*);
     84void* operationLinkCall(ExecState*);
    8385
    8486// This method is used to lookup an exception hander, keyed by faultLocation, which is
  • trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp

    r90193 r90423  
    376376}
    377377
     378void dfgLinkCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr)
     379{
     380    CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
     381   
     382    RepatchBuffer repatchBuffer(callerCodeBlock);
     383   
     384    if (!calleeCodeBlock || static_cast<int>(exec->argumentCountIncludingThis()) == calleeCodeBlock->m_numParameters) {
     385        ASSERT(!callLinkInfo.isLinked());
     386        callLinkInfo.callee.set(exec->callerFrame()->globalData(), callLinkInfo.hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
     387        repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr);
     388    }
     389   
     390    repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall);
     391}
     392
    378393} } // namespace JSC::DFG
    379394
  • trunk/Source/JavaScriptCore/dfg/DFGRepatch.h

    r90035 r90423  
    3737void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
    3838void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
     39void dfgLinkCall(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr);
    3940
    4041} } // namespace JSC::DFG
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r90371 r90423  
    364364    }
    365365
    366     if (isInt32Constant(node.child1)) {
    367         int32_t imm = valueOfInt32Constant(node.child1);
    368         SpeculateIntegerOperand op2(this, node.child2);
     366    if (isInt32Constant(node.child1())) {
     367        int32_t imm = valueOfInt32Constant(node.child1());
     368        SpeculateIntegerOperand op2(this, node.child2());
    369369        addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
    370     } else if (isInt32Constant(node.child2)) {
    371         SpeculateIntegerOperand op1(this, node.child1);
    372         int32_t imm = valueOfInt32Constant(node.child2);
     370    } else if (isInt32Constant(node.child2())) {
     371        SpeculateIntegerOperand op1(this, node.child1());
     372        int32_t imm = valueOfInt32Constant(node.child2());
    373373        addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
    374374    } else {
    375         SpeculateIntegerOperand op1(this, node.child1);
    376         SpeculateIntegerOperand op2(this, node.child2);
     375        SpeculateIntegerOperand op1(this, node.child1());
     376        SpeculateIntegerOperand op2(this, node.child2());
    377377        addBranch(m_jit.branch32(condition, op1.gpr(), op2.gpr()), taken);
    378378    }
     
    399399    }
    400400
    401     JSValueOperand op1(this, node.child1);
    402     JSValueOperand op2(this, node.child2);
     401    JSValueOperand op1(this, node.child1());
     402    JSValueOperand op2(this, node.child2());
    403403    GPRReg op1GPR = op1.gpr();
    404404    GPRReg op2GPR = op2.gpr();
     
    424424        ASSERT(node.adjustedRefCount() == 1);
    425425
    426         if (shouldSpeculateInteger(node.child1, node.child2))
     426        if (shouldSpeculateInteger(node.child1(), node.child2()))
    427427            compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
    428428        else
    429429            compilePeepHoleCall(node, branchNodeIndex, operation);
    430430
    431         use(node.child1);
    432         use(node.child2);
     431        use(node.child1());
     432        use(node.child2());
    433433        m_compileIndex = branchNodeIndex;
    434434        return true;
     
    436436
    437437    // Normal case, not fused to branch.
    438     SpeculateIntegerOperand op1(this, node.child1);
    439     SpeculateIntegerOperand op2(this, node.child2);
     438    SpeculateIntegerOperand op1(this, node.child1());
     439    SpeculateIntegerOperand op2(this, node.child2());
    440440    GPRTemporary result(this, op1, op2);
    441441
     
    483483        switch (m_jit.graph().getPrediction(node.local())) {
    484484        case PredictInt32: {
    485             SpeculateIntegerOperand value(this, node.child1);
     485            SpeculateIntegerOperand value(this, node.child1());
    486486            m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
    487487            noResult(m_compileIndex);
     
    489489        }
    490490        case PredictArray: {
    491             SpeculateCellOperand cell(this, node.child1);
     491            SpeculateCellOperand cell(this, node.child1());
    492492            m_jit.storePtr(cell.gpr(), JITCompiler::addressFor(node.local()));
    493493            noResult(m_compileIndex);
     
    496496
    497497        default: {
    498             JSValueOperand value(this, node.child1);
     498            JSValueOperand value(this, node.child1());
    499499            m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
    500500            noResult(m_compileIndex);
     
    508508    case BitOr:
    509509    case BitXor:
    510         if (isInt32Constant(node.child1)) {
    511             SpeculateIntegerOperand op2(this, node.child2);
     510        if (isInt32Constant(node.child1())) {
     511            SpeculateIntegerOperand op2(this, node.child2());
    512512            GPRTemporary result(this, op2);
    513513
    514             bitOp(op, valueOfInt32Constant(node.child1), op2.gpr(), result.gpr());
     514            bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
    515515
    516516            integerResult(result.gpr(), m_compileIndex);
    517         } else if (isInt32Constant(node.child2)) {
    518             SpeculateIntegerOperand op1(this, node.child1);
     517        } else if (isInt32Constant(node.child2())) {
     518            SpeculateIntegerOperand op1(this, node.child1());
    519519            GPRTemporary result(this, op1);
    520520
    521             bitOp(op, valueOfInt32Constant(node.child2), op1.gpr(), result.gpr());
     521            bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
    522522
    523523            integerResult(result.gpr(), m_compileIndex);
    524524        } else {
    525             SpeculateIntegerOperand op1(this, node.child1);
    526             SpeculateIntegerOperand op2(this, node.child2);
     525            SpeculateIntegerOperand op1(this, node.child1());
     526            SpeculateIntegerOperand op2(this, node.child2());
    527527            GPRTemporary result(this, op1, op2);
    528528
     
    538538    case BitLShift:
    539539    case BitURShift:
    540         if (isInt32Constant(node.child2)) {
    541             SpeculateIntegerOperand op1(this, node.child1);
     540        if (isInt32Constant(node.child2())) {
     541            SpeculateIntegerOperand op1(this, node.child1());
    542542            GPRTemporary result(this, op1);
    543543
    544             shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2) & 0x1f, result.gpr());
     544            shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
    545545
    546546            integerResult(result.gpr(), m_compileIndex);
    547547        } else {
    548548            // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
    549             SpeculateIntegerOperand op1(this, node.child1);
    550             SpeculateIntegerOperand op2(this, node.child2);
     549            SpeculateIntegerOperand op1(this, node.child1());
     550            SpeculateIntegerOperand op2(this, node.child2());
    551551            GPRTemporary result(this, op1);
    552552
     
    560560
    561561    case UInt32ToNumber: {
    562         IntegerOperand op1(this, node.child1);
     562        IntegerOperand op1(this, node.child1());
    563563        GPRTemporary result(this, op1);
    564564
     
    572572
    573573    case ValueToInt32: {
    574         SpeculateIntegerOperand op1(this, node.child1);
     574        SpeculateIntegerOperand op1(this, node.child1());
    575575        GPRTemporary result(this, op1);
    576576        m_jit.move(op1.gpr(), result.gpr());
     
    580580
    581581    case ValueToNumber: {
    582         if (isInteger(node.child1)) {
    583             SpeculateIntegerOperand op1(this, node.child1);
     582        if (isInteger(node.child1())) {
     583            SpeculateIntegerOperand op1(this, node.child1());
    584584            GPRTemporary result(this, op1);
    585585            m_jit.move(op1.gpr(), result.gpr());
     
    587587            break;
    588588        }
    589         SpeculateDoubleOperand op1(this, node.child1);
     589        SpeculateDoubleOperand op1(this, node.child1());
    590590        FPRTemporary result(this, op1);
    591591        m_jit.moveDouble(op1.fpr(), result.fpr());
     
    596596    case ValueAdd:
    597597    case ArithAdd: {
    598         if (shouldSpeculateInteger(node.child1, node.child2)) {
    599             if (isInt32Constant(node.child1)) {
    600                 int32_t imm1 = valueOfInt32Constant(node.child1);
    601                 SpeculateIntegerOperand op2(this, node.child2);
     598        if (shouldSpeculateInteger(node.child1(), node.child2())) {
     599            if (isInt32Constant(node.child1())) {
     600                int32_t imm1 = valueOfInt32Constant(node.child1());
     601                SpeculateIntegerOperand op2(this, node.child2());
    602602                GPRTemporary result(this);
    603603
     
    608608            }
    609609               
    610             if (isInt32Constant(node.child2)) {
    611                 SpeculateIntegerOperand op1(this, node.child1);
    612                 int32_t imm2 = valueOfInt32Constant(node.child2);
     610            if (isInt32Constant(node.child2())) {
     611                SpeculateIntegerOperand op1(this, node.child1());
     612                int32_t imm2 = valueOfInt32Constant(node.child2());
    613613                GPRTemporary result(this);
    614614
     
    619619            }
    620620               
    621             SpeculateIntegerOperand op1(this, node.child1);
    622             SpeculateIntegerOperand op2(this, node.child2);
     621            SpeculateIntegerOperand op1(this, node.child1());
     622            SpeculateIntegerOperand op2(this, node.child2());
    623623            GPRTemporary result(this, op1, op2);
    624624
     
    639639        }
    640640
    641         SpeculateDoubleOperand op1(this, node.child1);
    642         SpeculateDoubleOperand op2(this, node.child2);
     641        SpeculateDoubleOperand op1(this, node.child1());
     642        SpeculateDoubleOperand op2(this, node.child2());
    643643        FPRTemporary result(this, op1, op2);
    644644
     
    652652
    653653    case ArithSub: {
    654         if (shouldSpeculateInteger(node.child1, node.child2)) {
    655             if (isInt32Constant(node.child2)) {
    656                 SpeculateIntegerOperand op1(this, node.child1);
    657                 int32_t imm2 = valueOfInt32Constant(node.child2);
     654        if (shouldSpeculateInteger(node.child1(), node.child2())) {
     655            if (isInt32Constant(node.child2())) {
     656                SpeculateIntegerOperand op1(this, node.child1());
     657                int32_t imm2 = valueOfInt32Constant(node.child2());
    658658                GPRTemporary result(this);
    659659
     
    664664            }
    665665               
    666             SpeculateIntegerOperand op1(this, node.child1);
    667             SpeculateIntegerOperand op2(this, node.child2);
     666            SpeculateIntegerOperand op1(this, node.child1());
     667            SpeculateIntegerOperand op2(this, node.child2());
    668668            GPRTemporary result(this);
    669669
     
    674674        }
    675675
    676         SpeculateDoubleOperand op1(this, node.child1);
    677         SpeculateDoubleOperand op2(this, node.child2);
     676        SpeculateDoubleOperand op1(this, node.child1());
     677        SpeculateDoubleOperand op2(this, node.child2());
    678678        FPRTemporary result(this, op1);
    679679
     
    687687
    688688    case ArithMul: {
    689         if (shouldSpeculateInteger(node.child1, node.child2)) {
    690             SpeculateIntegerOperand op1(this, node.child1);
    691             SpeculateIntegerOperand op2(this, node.child2);
     689        if (shouldSpeculateInteger(node.child1(), node.child2())) {
     690            SpeculateIntegerOperand op1(this, node.child1());
     691            SpeculateIntegerOperand op2(this, node.child2());
    692692            GPRTemporary result(this);
    693693
     
    705705        }
    706706
    707         SpeculateDoubleOperand op1(this, node.child1);
    708         SpeculateDoubleOperand op2(this, node.child2);
     707        SpeculateDoubleOperand op1(this, node.child1());
     708        SpeculateDoubleOperand op2(this, node.child2());
    709709        FPRTemporary result(this, op1, op2);
    710710
     
    719719
    720720    case ArithDiv: {
    721         SpeculateDoubleOperand op1(this, node.child1);
    722         SpeculateDoubleOperand op2(this, node.child2);
     721        SpeculateDoubleOperand op1(this, node.child1());
     722        SpeculateDoubleOperand op2(this, node.child2());
    723723        FPRTemporary result(this, op1);
    724724
     
    732732
    733733    case ArithMod: {
    734         SpeculateIntegerOperand op1(this, node.child1);
    735         SpeculateIntegerOperand op2(this, node.child2);
     734        SpeculateIntegerOperand op1(this, node.child1());
     735        SpeculateIntegerOperand op2(this, node.child2());
    736736        GPRTemporary eax(this, X86Registers::eax);
    737737        GPRTemporary edx(this, X86Registers::edx);
     
    760760
    761761    case LogicalNot: {
    762         JSValueOperand value(this, node.child1);
     762        JSValueOperand value(this, node.child1());
    763763        GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
    764764
     
    799799
    800800    case CompareStrictEq: {
    801         SpeculateIntegerOperand op1(this, node.child1);
    802         SpeculateIntegerOperand op2(this, node.child2);
     801        SpeculateIntegerOperand op1(this, node.child1());
     802        SpeculateIntegerOperand op2(this, node.child2());
    803803        GPRTemporary result(this, op1, op2);
    804804
     
    812812
    813813    case GetByVal: {
    814         NodeIndex alias = node.child3;
     814        NodeIndex alias = node.child3();
    815815        if (alias != NoNode) {
    816816            // FIXME: result should be able to reuse child1, child2. Should have an 'UnusedOperand' type.
    817             JSValueOperand aliasedValue(this, node.child3);
     817            JSValueOperand aliasedValue(this, node.child3());
    818818            GPRTemporary result(this, aliasedValue);
    819819            m_jit.move(aliasedValue.gpr(), result.gpr());
     
    822822        }
    823823
    824         SpeculateCellOperand base(this, node.child1);
    825         SpeculateStrictInt32Operand property(this, node.child2);
     824        SpeculateCellOperand base(this, node.child1());
     825        SpeculateStrictInt32Operand property(this, node.child2());
    826826        GPRTemporary storage(this);
    827827
     
    836836        // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
    837837        // If we have predicted the base to be type array, we can skip the check.
    838         Node& baseNode = m_jit.graph()[node.child1];
     838        Node& baseNode = m_jit.graph()[node.child1()];
    839839        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
    840840            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
     
    853853
    854854    case PutByVal: {
    855         SpeculateCellOperand base(this, node.child1);
    856         SpeculateStrictInt32Operand property(this, node.child2);
    857         JSValueOperand value(this, node.child3);
     855        SpeculateCellOperand base(this, node.child1());
     856        SpeculateStrictInt32Operand property(this, node.child2());
     857        JSValueOperand value(this, node.child3());
    858858        GPRTemporary scratch(this);
    859859
     
    868868        // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
    869869        // If we have predicted the base to be type array, we can skip the check.
    870         Node& baseNode = m_jit.graph()[node.child1];
     870        Node& baseNode = m_jit.graph()[node.child1()];
    871871        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
    872872            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
     
    910910
    911911    case PutByValAlias: {
    912         SpeculateCellOperand base(this, node.child1);
    913         SpeculateStrictInt32Operand property(this, node.child2);
    914         JSValueOperand value(this, node.child3);
     912        SpeculateCellOperand base(this, node.child1());
     913        SpeculateStrictInt32Operand property(this, node.child2());
     914        JSValueOperand value(this, node.child3());
    915915        GPRTemporary scratch(this);
    916916       
     
    942942
    943943    case Branch: {
    944         JSValueOperand value(this, node.child1);
     944        JSValueOperand value(this, node.child1());
    945945        GPRReg valueReg = value.gpr();
    946946
     
    978978
    979979        // Return the result in returnValueGPR.
    980         JSValueOperand op1(this, node.child1);
     980        JSValueOperand op1(this, node.child1());
    981981        m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
    982982
     
    994994
    995995    case ConvertThis: {
    996         SpeculateCellOperand thisValue(this, node.child1);
     996        SpeculateCellOperand thisValue(this, node.child1());
    997997        GPRTemporary temp(this);
    998998
     
    10051005
    10061006    case GetById: {
    1007         SpeculateCellOperand base(this, node.child1);
     1007        SpeculateCellOperand base(this, node.child1());
    10081008        GPRTemporary result(this, base);
    10091009
     
    10171017
    10181018    case PutById: {
    1019         SpeculateCellOperand base(this, node.child1);
    1020         JSValueOperand value(this, node.child2);
     1019        SpeculateCellOperand base(this, node.child1());
     1020        JSValueOperand value(this, node.child2());
    10211021        GPRTemporary scratch(this);
    10221022
     
    10281028
    10291029    case PutByIdDirect: {
    1030         SpeculateCellOperand base(this, node.child1);
    1031         JSValueOperand value(this, node.child2);
     1030        SpeculateCellOperand base(this, node.child1());
     1031        JSValueOperand value(this, node.child2());
    10321032        GPRTemporary scratch(this);
    10331033
     
    10501050
    10511051    case PutGlobalVar: {
    1052         JSValueOperand value(this, node.child1);
     1052        JSValueOperand value(this, node.child1());
    10531053        GPRTemporary globalObject(this);
    10541054        GPRTemporary scratch(this);
     
    10691069
    10701070    case CheckHasInstance: {
    1071         SpeculateCellOperand base(this, node.child1);
     1071        SpeculateCellOperand base(this, node.child1());
    10721072        GPRTemporary structure(this);
    10731073
     
    10811081
    10821082    case InstanceOf: {
    1083         SpeculateCellOperand value(this, node.child1);
     1083        SpeculateCellOperand value(this, node.child1());
    10841084        // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
    1085         SpeculateCellOperand prototype(this, node.child3);
     1085        SpeculateCellOperand prototype(this, node.child3());
    10861086
    10871087        GPRTemporary scratch(this);
     
    11261126        ASSERT_NOT_REACHED();
    11271127#endif
     1128        break;
     1129       
     1130    case Call:
     1131        JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
     1132        GPRReg calleeGPR = callee.gpr();
     1133        emitCall(node, calleeGPR);
     1134        break;
    11281135    }
    11291136
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r90371 r90423  
    153153        // Check if the lastNode is a branch on this node.
    154154        Node& lastNode = m_jit.graph()[lastNodeIndex];
    155         return lastNode.op == Branch && lastNode.child1 == m_compileIndex ? lastNodeIndex : NoNode;
     155        return lastNode.op == Branch && lastNode.child1() == m_compileIndex ? lastNodeIndex : NoNode;
    156156    }
    157157
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r86727 r90423  
    3939    class ExecState : private Register {
    4040    public:
     41        JSValue calleeAsValue() const { return this[RegisterFile::Callee].jsValue(); }
    4142        JSObject* callee() const { return this[RegisterFile::Callee].function(); }
    4243        CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r90414 r90423  
    7575    , m_codeBlock(codeBlock)
    7676    , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
    77     , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)
    7877    , m_bytecodeOffset((unsigned)-1)
    7978#if USE(JSVALUE32_64)
     
    356355    }
    357356
    358     ASSERT(m_callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
     357    ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
    359358
    360359#ifndef NDEBUG
     
    465464
    466465    ASSERT(m_propertyAccessInstructionIndex == m_propertyAccessCompilationInfo.size());
    467     ASSERT(m_callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
     466    ASSERT(m_callLinkInfoIndex == m_callStructureStubCompilationInfo.size());
    468467
    469468#ifndef NDEBUG
     
    589588        info.hotPathBegin = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
    590589    }
     590    m_codeBlock->setNumberOfCallLinkInfos(m_callStructureStubCompilationInfo.size());
    591591    for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
    592592        CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
    593593        info.isCall = m_callStructureStubCompilationInfo[i].isCall;
    594         info.callReturnLocation = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation);
     594        info.callReturnLocation = CodeLocationLabel(patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation));
    595595        info.hotPathBegin = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
    596596        info.hotPathOther = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].hotPathOther);
     
    607607        *functionEntryArityCheck = patchBuffer.locationOf(arityCheck);
    608608
    609     return patchBuffer.finalizeCode();
     609    return JITCode(patchBuffer.finalizeCode(), JITCode::BaselineJIT);
    610610}
    611611
     
    624624    // patch the call so we do not continue to try to link.
    625625    if (kind == CodeForCall) {
    626         repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
     626        repatchBuffer.relink(CodeLocationNearCall(callLinkInfo->callReturnLocation), globalData->jitStubs->ctiVirtualCall());
    627627        return;
    628628    }
    629629
    630630    ASSERT(kind == CodeForConstruct);
    631     repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());
     631    repatchBuffer.relink(CodeLocationNearCall(callLinkInfo->callReturnLocation), globalData->jitStubs->ctiVirtualConstruct());
    632632}
    633633
  • trunk/Source/JavaScriptCore/jit/JITCall.cpp

    r89885 r90423  
    133133    addSlowCase(jumpToSlow);
    134134    ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump);
     135   
     136    ASSERT(m_callStructureStubCompilationInfo.size() == callLinkInfoIndex);
     137    m_callStructureStubCompilationInfo.append(StructureStubCompilationInfo());
    135138    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
    136139    m_callStructureStubCompilationInfo[callLinkInfoIndex].isCall = opcodeID != op_construct;
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r86883 r90423  
    3838    class JSGlobalData;
    3939    class RegisterFile;
    40 
     40   
    4141    class JITCode {
    4242        typedef MacroAssemblerCodeRef CodeRef;
    4343        typedef MacroAssemblerCodePtr CodePtr;
    4444    public:
     45        enum JITType { HostCallThunk, BaselineJIT, DFGJIT };
     46
    4547        JITCode()
    4648        {
    4749        }
    4850
    49         JITCode(const CodeRef ref)
     51        JITCode(const CodeRef ref, JITType jitType)
    5052            : m_ref(ref)
     53            , m_jitType(jitType)
    5154        {
    5255        }
     
    9497            return m_ref.m_executablePool.get();
    9598        }
     99       
     100        JITType jitType()
     101        {
     102            return m_jitType;
     103        }
    96104
    97105        // Host functions are a bit special; they have a m_code pointer but they
     
    99107        static JITCode HostFunction(CodePtr code)
    100108        {
    101             return JITCode(code.dataLocation(), 0, 0);
     109            return JITCode(code.dataLocation(), 0, 0, HostCallThunk);
    102110        }
    103111
     
    109117
    110118    private:
    111         JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
     119        JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size, JITType jitType)
    112120            : m_ref(code, executablePool, size)
     121            , m_jitType(jitType)
    113122        {
    114123        }
    115124
    116125        CodeRef m_ref;
     126        JITType m_jitType;
    117127    };
    118128
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r87826 r90423  
    3636    class NativeExecutable;
    3737    class VPtrHackExecutable;
     38    namespace DFG {
     39    class JITCodeGenerator;
     40    }
    3841
    3942    EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
     
    4144    class JSFunction : public JSObjectWithGlobalObject {
    4245        friend class JIT;
     46        friend class DFG::JITCodeGenerator;
    4347        friend class JSGlobalData;
    4448
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r88473 r90423  
    235235#if ENABLE(JIT)
    236236        ReturnAddressPtr exceptionLocation;
     237        JSValue hostCallReturnValue;
    237238#endif
    238239
Note: See TracChangeset for help on using the changeset viewer.