Changeset 84860 in webkit


Ignore:
Timestamp:
Apr 25, 2011 6:40:25 PM (13 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=59405
DFG JIT - add type speculation for integer & array types, for vars & args.

Reviewed by Geoff Garen.

If a var or argument is used as the base for a GetByVal or PutByVal access
we are speculating that it is of type Array (we only generate code on the
speculative path to perform array accesses). By typing the var or args slot
as Array, and checking on entry to the function (in the case of args), and
each time the local is written to, we can avoid a type check at each point
the array is accessed. This will typically hoist type checks out of loops.

Similarly, any local that is incremented or decremented, or is the input or
output or a bitwise operator, is likely to be an integer. By typing the
local as int32 we can avoid speculation checks on access, and tagging when
writing to the slot. All accesses can become 32bit instead of 64.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::set):
(JSC::DFG::ByteCodeParser::predictArray):
(JSC::DFG::ByteCodeParser::predictInt32):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGGraph.h:

(JSC::DFG::PredictionSlot::PredictionSlot):
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::predict):
(JSC::DFG::Graph::getPrediction):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::compileFunction):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::tagFor):
(JSC::DFG::JITCompiler::payloadFor):

  • dfg/DFGNode.h:
  • dfg/DFGNonSpeculativeJIT.cpp:

(JSC::DFG::NonSpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::initializeVariableTypes):

  • dfg/DFGSpeculativeJIT.h:
  • runtime/Executable.cpp:

(JSC::tryDFGCompile):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r84855 r84860  
     12011-04-25  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Geoff Garen.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=59405
     6        DFG JIT - add type speculation for integer & array types, for vars & args.
     7
     8        If a var or argument is used as the base for a GetByVal or PutByVal access
     9        we are speculating that it is of type Array (we only generate code on the
     10        speculative path to perform array accesses). By typing the var or args slot
     11        as Array, and checking on entry to the function (in the case of args), and
     12        each time the local is written to, we can avoid a type check at each point
     13        the array is accessed. This will typically hoist type checks out of loops.
     14
     15        Similarly, any local that is incremented or decremented, or is the input or
     16        output or a bitwise operator, is likely to be an integer. By typing the
     17        local as int32 we can avoid speculation checks on access, and tagging when
     18        writing to the slot. All accesses can become 32bit instead of 64.
     19
     20        * dfg/DFGByteCodeParser.cpp:
     21        (JSC::DFG::ByteCodeParser::set):
     22        (JSC::DFG::ByteCodeParser::predictArray):
     23        (JSC::DFG::ByteCodeParser::predictInt32):
     24        (JSC::DFG::ByteCodeParser::parseBlock):
     25        * dfg/DFGGraph.h:
     26        (JSC::DFG::PredictionSlot::PredictionSlot):
     27        (JSC::DFG::Graph::Graph):
     28        (JSC::DFG::Graph::predict):
     29        (JSC::DFG::Graph::getPrediction):
     30        * dfg/DFGJITCompiler.cpp:
     31        (JSC::DFG::JITCompiler::compileFunction):
     32        * dfg/DFGJITCompiler.h:
     33        (JSC::DFG::JITCompiler::tagFor):
     34        (JSC::DFG::JITCompiler::payloadFor):
     35        * dfg/DFGNode.h:
     36        * dfg/DFGNonSpeculativeJIT.cpp:
     37        (JSC::DFG::NonSpeculativeJIT::compile):
     38        * dfg/DFGSpeculativeJIT.cpp:
     39        (JSC::DFG::SpeculativeJIT::compile):
     40        (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
     41        (JSC::DFG::SpeculativeJIT::initializeVariableTypes):
     42        * dfg/DFGSpeculativeJIT.h:
     43        * runtime/Executable.cpp:
     44        (JSC::tryDFGCompile):
     45
    1462011-04-25  David Levin  <levin@chromium.org>
    247
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r84846 r84860  
    9292
    9393        // Is this an argument?
    94         if (operand < 0)
     94        if (operandIsArgument(operand))
    9595            return getArgument(operand);
    9696
     
    9898        return getLocal((unsigned)operand);
    9999    }
    100     void set(int operand, NodeIndex value)
    101     {
     100    void set(int operand, NodeIndex value, PredictedType prediction = PredictNone)
     101    {
     102        m_graph.predict(operand, prediction);
     103
    102104        // Is this an argument?
    103         if (operand < 0) {
     105        if (operandIsArgument(operand)) {
    104106            setArgument(operand, value);
    105107            return;
     
    441443    }
    442444
     445    void predictArray(NodeIndex nodeIndex)
     446    {
     447        Node* nodePtr = &m_graph[nodeIndex];
     448
     449        if (nodePtr->op == GetLocal)
     450            m_graph.predict(nodePtr->local(), PredictArray);
     451    }
     452
     453    void predictInt32(NodeIndex nodeIndex)
     454    {
     455        Node* nodePtr = &m_graph[nodeIndex];
     456
     457        if (nodePtr->op == ValueToNumber)
     458            nodePtr = &m_graph[nodePtr->child1];
     459
     460        if (nodePtr->op == ValueToInt32)
     461            nodePtr = &m_graph[nodePtr->child1];
     462
     463        if (nodePtr->op == NumberToInt32)
     464            nodePtr = &m_graph[nodePtr->child1];
     465
     466        if (nodePtr->op == GetLocal)
     467            m_graph.predict(nodePtr->local(), PredictInt32);
     468    }
     469
    443470    JSGlobalData* m_globalData;
    444471    CodeBlock* m_codeBlock;
     
    561588            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    562589            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    563             set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2));
     590            predictInt32(op1);
     591            predictInt32(op2);
     592            set(currentInstruction[1].u.operand, addToGraph(BitAnd, op1, op2), PredictInt32);
    564593            NEXT_OPCODE(op_bitand);
    565594        }
     
    568597            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    569598            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    570             set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2));
     599            predictInt32(op1);
     600            predictInt32(op2);
     601            set(currentInstruction[1].u.operand, addToGraph(BitOr, op1, op2), PredictInt32);
    571602            NEXT_OPCODE(op_bitor);
    572603        }
     
    575606            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    576607            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
    577             set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2));
     608            predictInt32(op1);
     609            predictInt32(op2);
     610            set(currentInstruction[1].u.operand, addToGraph(BitXor, op1, op2), PredictInt32);
    578611            NEXT_OPCODE(op_bitxor);
    579612        }
     
    582615            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    583616            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
     617            predictInt32(op1);
     618            predictInt32(op2);
    584619            NodeIndex result;
    585620            // Optimize out shifts by zero.
     
    588623            else
    589624                result = addToGraph(BitRShift, op1, op2);
    590             set(currentInstruction[1].u.operand, result);
     625            set(currentInstruction[1].u.operand, result, PredictInt32);
    591626            NEXT_OPCODE(op_rshift);
    592627        }
     
    595630            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    596631            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
     632            predictInt32(op1);
     633            predictInt32(op2);
    597634            NodeIndex result;
    598635            // Optimize out shifts by zero.
     
    601638            else
    602639                result = addToGraph(BitLShift, op1, op2);
    603             set(currentInstruction[1].u.operand, result);
     640            set(currentInstruction[1].u.operand, result, PredictInt32);
    604641            NEXT_OPCODE(op_lshift);
    605642        }
     
    608645            NodeIndex op1 = getToInt32(currentInstruction[2].u.operand);
    609646            NodeIndex op2 = getToInt32(currentInstruction[3].u.operand);
     647            predictInt32(op1);
     648            predictInt32(op2);
    610649            NodeIndex result;
    611650            // The result of a zero-extending right shift is treated as an unsigned value.
     
    628667                result = addToGraph(UInt32ToNumber, result);
    629668            }
    630             set(currentInstruction[1].u.operand, result);
     669            set(currentInstruction[1].u.operand, result, PredictInt32);
    631670            NEXT_OPCODE(op_urshift);
    632671        }
     
    637676            unsigned srcDst = currentInstruction[1].u.operand;
    638677            NodeIndex op = getToNumber(srcDst);
     678            predictInt32(op);
    639679            set(srcDst, addToGraph(ArithAdd, op, one()));
    640680            NEXT_OPCODE(op_pre_inc);
     
    645685            unsigned srcDst = currentInstruction[2].u.operand;
    646686            NodeIndex op = getToNumber(srcDst);
     687            predictInt32(op);
    647688            set(result, op);
    648689            set(srcDst, addToGraph(ArithAdd, op, one()));
     
    653694            unsigned srcDst = currentInstruction[1].u.operand;
    654695            NodeIndex op = getToNumber(srcDst);
     696            predictInt32(op);
    655697            set(srcDst, addToGraph(ArithSub, op, one()));
    656698            NEXT_OPCODE(op_pre_dec);
     
    661703            unsigned srcDst = currentInstruction[2].u.operand;
    662704            NodeIndex op = getToNumber(srcDst);
     705            predictInt32(op);
    663706            set(result, op);
    664707            set(srcDst, addToGraph(ArithSub, op, one()));
     
    795838            NodeIndex base = get(currentInstruction[2].u.operand);
    796839            NodeIndex property = get(currentInstruction[3].u.operand);
     840            predictArray(base);
     841            predictInt32(property);
    797842
    798843            NodeIndex getByVal = addToGraph(GetByVal, base, property, aliases.lookupGetByVal(base, property));
     
    807852            NodeIndex property = get(currentInstruction[2].u.operand);
    808853            NodeIndex value = get(currentInstruction[3].u.operand);
     854            predictArray(base);
     855            predictInt32(property);
    809856
    810857            NodeIndex aliasedGet = aliases.lookupGetByVal(base, property);
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r84744 r84860  
    9898    if (node.hasLocal()) {
    9999        int local = node.local();
    100         if (local < 0)
     100        if (operandIsArgument(local))
    101101            printf("%sarg%u", hasPrinted ? ", " : "", local - codeBlock->thisRegister());
    102102        else
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r84748 r84860  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include <RegisterFile.h>
    3132#include <dfg/DFGNode.h>
    3233#include <wtf/Vector.h>
     
    3839
    3940namespace DFG {
     41
     42// helper function to distinguish vars & temporaries from arguments.
     43inline bool operandIsArgument(int operand) { return operand < 0; }
     44
     45typedef uint8_t PredictedType;
     46static const PredictedType PredictNone  = 0;
     47static const PredictedType PredictCell  = 0x01;
     48static const PredictedType PredictArray = 0x03;
     49static const PredictedType PredictInt32 = 0x04;
     50
     51struct PredictionSlot {
     52public:
     53    PredictionSlot()
     54        : m_value(PredictNone)
     55    {
     56    }
     57    PredictedType m_value;
     58};
    4059
    4160typedef uint32_t BlockIndex;
     
    87106class Graph : public Vector<Node, 64> {
    88107public:
     108    Graph(unsigned numArguments, unsigned numVariables)
     109        : m_argumentPredictions(numArguments)
     110        , m_variablePredictions(numVariables)
     111    {
     112    }
     113
    89114    // Mark a node as being referenced.
    90115    void ref(NodeIndex nodeIndex)
     
    102127#endif
    103128
    104     Vector< OwnPtr<BasicBlock> , 8> m_blocks;
    105 
    106129    BlockIndex blockIndexForBytecodeOffset(unsigned bytecodeBegin)
    107130    {
     
    117140    }
    118141
     142    void predict(int operand, PredictedType prediction)
     143    {
     144        if (operandIsArgument(operand)) {
     145            unsigned argument = operand + m_argumentPredictions.size() + RegisterFile::CallFrameHeaderSize;
     146            m_argumentPredictions[argument].m_value |= prediction;
     147        } else if ((unsigned)operand < m_variablePredictions.size())
     148            m_variablePredictions[operand].m_value |= prediction;
     149           
     150    }
     151
     152    PredictedType getPrediction(int operand)
     153    {
     154        if (operandIsArgument(operand)) {
     155            unsigned argument = operand + m_argumentPredictions.size() + RegisterFile::CallFrameHeaderSize;
     156            return m_argumentPredictions[argument].m_value;
     157        }
     158        if ((unsigned)operand < m_variablePredictions.size())
     159            return m_variablePredictions[operand].m_value;
     160        return PredictNone;
     161    }
     162
     163    Vector< OwnPtr<BasicBlock> , 8> m_blocks;
    119164private:
     165
    120166    // When a node's refCount goes from 0 to 1, it must (logically) recursively ref all of its children, and vice versa.
    121167    void refChildren(NodeIndex);
     168
     169    Vector<PredictionSlot, 16> m_argumentPredictions;
     170    Vector<PredictionSlot, 16> m_variablePredictions;
    122171};
    123172
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r84675 r84860  
    265265    Label speculativePathBegin = label();
    266266    SpeculativeJIT speculative(*this);
     267#if !DFG_DEBUG_LOCAL_DISBALE_SPECULATIVE
    267268    bool compiledSpeculative = speculative.compile();
     269#else
     270    bool compiledSpeculative = false;
     271#endif
    268272
    269273    // Next, generate the non-speculative path. We pass this a SpeculationCheckIndexIterator
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r84462 r84860  
    206206#endif
    207207
    208     Address addressForArgument(int32_t argument)
    209     {
    210         return Address(callFrameRegister, (argument - (m_codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize)) * sizeof(Register));
    211     }
    212 
    213208    static Address addressForGlobalVar(RegisterID global, int32_t varNumber)
    214209    {
     
    219214    {
    220215        return Address(callFrameRegister, virtualRegister * sizeof(Register));
     216    }
     217
     218    static Address tagFor(VirtualRegister virtualRegister)
     219    {
     220        return Address(callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
     221    }
     222
     223    static Address payloadFor(VirtualRegister virtualRegister)
     224    {
     225        return Address(callFrameRegister, virtualRegister * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
    221226    }
    222227
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r84744 r84860  
    4141// Disable the DFG JIT without having to touch Platform.h!
    4242#define DFG_DEBUG_LOCAL_DISBALE 0
     43// Disable the SpeculativeJIT without having to touch Platform.h!
     44#define DFG_DEBUG_LOCAL_DISBALE_SPECULATIVE 0
    4345// Generate stats on how successful we were in making use of the DFG jit, and remaining on the hot path.
    4446#define DFG_SUCCESS_STATS 0
  • trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp

    r84744 r84860  
    174174void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, Node& node)
    175175{
    176     // ...
    177     if (checkIterator.hasCheckAtIndex(m_compileIndex))
     176    // Check for speculation checks from the corresponding instruction in the
     177    // speculative path. Do not check for NodeIndex 0, since this is checked
     178    // in the outermost compile layer, at the head of the non-speculative path
     179    // (for index 0 we may need to check regardless of whether or not the node
     180    // will be generated, since argument type speculation checks will appear
     181    // as speculation checks at this index).
     182    if (m_compileIndex && checkIterator.hasCheckAtIndex(m_compileIndex))
    178183        trackEntry(m_jit.label());
    179184
     
    202207        m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.registerID());
    203208
    204         // jsValueResult, but don't useChildren!
     209        // Like jsValueResult, but don't useChildren - our children are phi nodes,
     210        // and don't represent values within this dataflow with virtual registers.
    205211        VirtualRegister virtualRegister = node.virtualRegister();
    206212        m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
     
    684690void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator)
    685691{
     692    // Check for speculation checks added at function entry (checking argument types).
     693    if (checkIterator.hasCheckAtIndex(m_compileIndex))
     694        trackEntry(m_jit.label());
     695
    686696    ASSERT(!m_compileIndex);
    687697    for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r84744 r84860  
    286286    case GetLocal: {
    287287        GPRTemporary result(this);
    288         m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.registerID());
    289 
    290         // jsValueResult, but don't useChildren!
    291         VirtualRegister virtualRegister = node.virtualRegister();
    292         m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
    293         m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), DataFormatJS);
     288        PredictedType prediction = m_jit.graph().getPrediction(node.local());
     289        if (prediction == PredictInt32) {
     290            m_jit.load32(JITCompiler::payloadFor(node.local()), result.registerID());
     291
     292            // Like integerResult, but don't useChildren - our children are phi nodes,
     293            // and don't represent values within this dataflow with virtual registers.
     294            VirtualRegister virtualRegister = node.virtualRegister();
     295            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
     296            m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
     297        } else {
     298            m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.registerID());
     299
     300            // Like jsValueResult, but don't useChildren - our children are phi nodes,
     301            // and don't represent values within this dataflow with virtual registers.
     302            VirtualRegister virtualRegister = node.virtualRegister();
     303            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
     304            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), (prediction == PredictArray) ? DataFormatJSCell : DataFormatJS);
     305        }
    294306        break;
    295307    }
    296308
    297309    case SetLocal: {
    298         JSValueOperand value(this, node.child1);
    299         m_jit.storePtr(value.registerID(), JITCompiler::addressFor(node.local()));
    300         noResult(m_compileIndex);
     310        switch (m_jit.graph().getPrediction(node.local())) {
     311        case PredictInt32: {
     312            SpeculateIntegerOperand value(this, node.child1);
     313            m_jit.store32(value.registerID(), JITCompiler::payloadFor(node.local()));
     314            noResult(m_compileIndex);
     315            break;
     316        }
     317        case PredictArray: {
     318            SpeculateCellOperand cell(this, node.child1);
     319            m_jit.storePtr(cell.registerID(), JITCompiler::addressFor(node.local()));
     320            noResult(m_compileIndex);
     321            break;
     322        }
     323
     324        default: {
     325            JSValueOperand value(this, node.child1);
     326            m_jit.storePtr(value.registerID(), JITCompiler::addressFor(node.local()));
     327            noResult(m_compileIndex);
     328            break;
     329        }
     330        }
    301331        break;
    302332    }
     
    631661
    632662        // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
    633         speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
     663        // If we have predicted the base to be type array, we can skip the check.
     664        Node& baseNode = m_jit.graph()[node.child1];
     665        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
     666            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
    634667        speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
    635668
     
    658691
    659692        // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
    660         speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
     693        // If we have predicted the base to be type array, we can skip the check.
     694        Node& baseNode = m_jit.graph()[node.child1];
     695        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
     696            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
    661697        speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
    662698
     
    869905}
    870906
     907// If we are making type predictions about our arguments then
     908// we need to check that they are correct on function entry.
     909void SpeculativeJIT::checkArgumentTypes()
     910{
     911    ASSERT(!m_compileIndex);
     912    for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
     913        VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i);
     914        if (m_jit.graph().getPrediction(virtualRegister) == PredictInt32)
     915        switch (m_jit.graph().getPrediction(virtualRegister)) {
     916        case PredictInt32:
     917            speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), JITCompiler::tagTypeNumberRegister));
     918            break;
     919
     920        case PredictArray: {
     921            GPRTemporary temp(this);
     922            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.registerID());
     923            speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.registerID(), JITCompiler::tagMaskRegister));
     924            speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.registerID()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
     925            break;
     926        }
     927
     928        default:
     929            break;
     930        }
     931    }
     932}
     933
     934// For any vars that we will be treating as numeric, write 0 to
     935// the var on entry. Throughout the block we will only read/write
     936// to the payload, by writing the tag now we prevent the GC from
     937// misinterpreting values as pointers.
     938void SpeculativeJIT::initializeVariableTypes()
     939{
     940    ASSERT(!m_compileIndex);
     941    for (int var = 0; var < m_jit.codeBlock()->m_numVars; ++var) {
     942        if (m_jit.graph().getPrediction(var) == PredictInt32)
     943            m_jit.storePtr(JITCompiler::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var));
     944    }
     945}
     946
    871947bool SpeculativeJIT::compile()
    872948{
     949    checkArgumentTypes();
     950    initializeVariableTypes();
     951
    873952    ASSERT(!m_compileIndex);
    874953    for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r84705 r84860  
    136136    void compile(BasicBlock&);
    137137
     138    void checkArgumentTypes();
     139    void initializeVariableTypes();
     140
    138141    bool isDoubleConstantWithInt32Value(NodeIndex nodeIndex, int32_t& out)
    139142    {
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r84556 r84860  
    205205#endif
    206206
    207     DFG::Graph dfg;
     207    DFG::Graph dfg(codeBlock->m_numParameters, codeBlock->m_numVars);
    208208    if (!parse(dfg, globalData, codeBlock))
    209209        return false;
Note: See TracChangeset for help on using the changeset viewer.