Changeset 89611 in webkit


Ignore:
Timestamp:
Jun 23, 2011, 2:04:40 PM (14 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=63218
DFG JIT - remove machine type guarantees from graph

Reviewed by Sam Weinig.

The DFG JIT currently makes assumptions about the types of machine registers
that certain nodes will be loaded into. This will be broken as we generate
nodes to produce both integer and double code paths. Remove int<->double
conversions nodes. This design decision also gave rise to multiple types of
constant nodes, requiring separate handling for each type. Merge these back
into JSConstant.

  • dfg/DFGAliasTracker.h:

(JSC::DFG::AliasTracker::equalIgnoringLaterNumericConversion):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getToInt32):
(JSC::DFG::ByteCodeParser::getToNumber):
(JSC::DFG::ByteCodeParser::toInt32):
(JSC::DFG::ByteCodeParser::toNumber):
(JSC::DFG::ByteCodeParser::isInt32Constant):
(JSC::DFG::ByteCodeParser::isDoubleConstant):
(JSC::DFG::ByteCodeParser::valueOfInt32Constant):
(JSC::DFG::ByteCodeParser::valueOfDoubleConstant):
(JSC::DFG::ByteCodeParser::one):
(JSC::DFG::ByteCodeParser::predictInt32):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGJITCodeGenerator.h:

(JSC::DFG::JITCodeGenerator::silentFillGPR):
(JSC::DFG::JITCodeGenerator::silentFillFPR):
(JSC::DFG::JITCodeGenerator::isJSConstant):
(JSC::DFG::JITCodeGenerator::isDoubleConstant):
(JSC::DFG::JITCodeGenerator::valueOfJSConstantAsImmPtr):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::fillNumericToDouble):
(JSC::DFG::JITCompiler::fillInt32ToInteger):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::isJSConstant):
(JSC::DFG::JITCompiler::isInt32Constant):
(JSC::DFG::JITCompiler::isDoubleConstant):
(JSC::DFG::JITCompiler::valueOfJSConstant):
(JSC::DFG::JITCompiler::valueOfInt32Constant):
(JSC::DFG::JITCompiler::valueOfDoubleConstant):

  • dfg/DFGNode.h:

(JSC::DFG::Node::Node):
(JSC::DFG::Node::isConstant):
(JSC::DFG::Node::notTakenBytecodeOffset):

  • dfg/DFGNonSpeculativeJIT.cpp:

(JSC::DFG::NonSpeculativeJIT::isKnownInteger):
(JSC::DFG::NonSpeculativeJIT::isKnownNumeric):
(JSC::DFG::NonSpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
(JSC::DFG::SpeculativeJIT::compile):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r89594 r89611  
     12011-06-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=63218
     6        DFG JIT - remove machine type guarantees from graph
     7
     8        The DFG JIT currently makes assumptions about the types of machine registers
     9        that certain nodes will be loaded into. This will be broken as we generate
     10        nodes to produce both integer and double code paths. Remove int<->double
     11        conversions nodes. This design decision also gave rise to multiple types of
     12        constant nodes, requiring separate handling for each type. Merge these back
     13        into JSConstant.
     14
     15        * dfg/DFGAliasTracker.h:
     16        (JSC::DFG::AliasTracker::equalIgnoringLaterNumericConversion):
     17        * dfg/DFGByteCodeParser.cpp:
     18        (JSC::DFG::ByteCodeParser::getToInt32):
     19        (JSC::DFG::ByteCodeParser::getToNumber):
     20        (JSC::DFG::ByteCodeParser::toInt32):
     21        (JSC::DFG::ByteCodeParser::toNumber):
     22        (JSC::DFG::ByteCodeParser::isInt32Constant):
     23        (JSC::DFG::ByteCodeParser::isDoubleConstant):
     24        (JSC::DFG::ByteCodeParser::valueOfInt32Constant):
     25        (JSC::DFG::ByteCodeParser::valueOfDoubleConstant):
     26        (JSC::DFG::ByteCodeParser::one):
     27        (JSC::DFG::ByteCodeParser::predictInt32):
     28        * dfg/DFGGraph.cpp:
     29        (JSC::DFG::Graph::dump):
     30        * dfg/DFGJITCodeGenerator.h:
     31        (JSC::DFG::JITCodeGenerator::silentFillGPR):
     32        (JSC::DFG::JITCodeGenerator::silentFillFPR):
     33        (JSC::DFG::JITCodeGenerator::isJSConstant):
     34        (JSC::DFG::JITCodeGenerator::isDoubleConstant):
     35        (JSC::DFG::JITCodeGenerator::valueOfJSConstantAsImmPtr):
     36        * dfg/DFGJITCompiler.cpp:
     37        (JSC::DFG::JITCompiler::fillNumericToDouble):
     38        (JSC::DFG::JITCompiler::fillInt32ToInteger):
     39        * dfg/DFGJITCompiler.h:
     40        (JSC::DFG::JITCompiler::isJSConstant):
     41        (JSC::DFG::JITCompiler::isInt32Constant):
     42        (JSC::DFG::JITCompiler::isDoubleConstant):
     43        (JSC::DFG::JITCompiler::valueOfJSConstant):
     44        (JSC::DFG::JITCompiler::valueOfInt32Constant):
     45        (JSC::DFG::JITCompiler::valueOfDoubleConstant):
     46        * dfg/DFGNode.h:
     47        (JSC::DFG::Node::Node):
     48        (JSC::DFG::Node::isConstant):
     49        (JSC::DFG::Node::notTakenBytecodeOffset):
     50        * dfg/DFGNonSpeculativeJIT.cpp:
     51        (JSC::DFG::NonSpeculativeJIT::isKnownInteger):
     52        (JSC::DFG::NonSpeculativeJIT::isKnownNumeric):
     53        (JSC::DFG::NonSpeculativeJIT::compile):
     54        * dfg/DFGSpeculativeJIT.cpp:
     55        (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
     56        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     57        (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
     58        (JSC::DFG::SpeculativeJIT::compile):
     59
    1602011-06-23  Jungshik Shin  <jshin@chromium.org>
    261
  • trunk/Source/JavaScriptCore/dfg/DFGAliasTracker.h

    r81154 r89611  
    107107            return true;
    108108        Node& node2 = m_graph[op2];
    109         return (node2.op == ValueToNumber || node2.op == ValueToInt32 || node2.op == NumberToInt32) && op1 == node2.child1;
     109        return (node2.op == ValueToNumber || node2.op == ValueToInt32) && op1 == node2.child1;
    110110    }
    111111
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r87359 r89611  
    176176    NodeIndex getToInt32(int operand)
    177177    {
    178         // Avoid wastefully adding a JSConstant node to the graph, only to
    179         // replace it with a Int32Constant (which is what would happen if
    180         // we called 'toInt32(get(operand))' in this case).
    181         if (operand >= FirstConstantRegisterIndex) {
    182             JSValue v = m_codeBlock->getConstant(operand);
    183             if (v.isInt32())
    184                 return getInt32Constant(v.asInt32(), operand - FirstConstantRegisterIndex);
    185         }
    186178        return toInt32(get(operand));
    187179    }
    188180    NodeIndex getToNumber(int operand)
    189181    {
    190         // Avoid wastefully adding a JSConstant node to the graph, only to
    191         // replace it with a DoubleConstant (which is what would happen if
    192         // we called 'toNumber(get(operand))' in this case).
    193         if (operand >= FirstConstantRegisterIndex) {
    194             JSValue v = m_codeBlock->getConstant(operand);
    195             if (v.isNumber())
    196                 return getDoubleConstant(v.uncheckedGetNumber(), operand - FirstConstantRegisterIndex);
    197         }
    198182        return toNumber(get(operand));
    199183    }
     
    207191            return index;
    208192
    209         if (node.hasDoubleResult()) {
    210             if (node.op == DoubleConstant)
    211                 return getInt32Constant(JSC::toInt32(valueOfDoubleConstant(index)), node.constantNumber());
    212             // 'NumberToInt32(Int32ToNumber(X))' == X, and 'NumberToInt32(UInt32ToNumber(X)) == X'
    213             if (node.op == Int32ToNumber || node.op == UInt32ToNumber)
    214                 return node.child1;
    215 
    216             // We unique NumberToInt32 nodes in a map to prevent duplicate conversions.
    217             pair<UnaryOpMap::iterator, bool> result = m_numberToInt32Nodes.add(index, NoNode);
    218             // Either we added a new value, or the existing value in the map is non-zero.
    219             ASSERT(result.second == (result.first->second == NoNode));
    220             if (result.second)
    221                 result.first->second = addToGraph(NumberToInt32, index);
    222             return result.first->second;
    223         }
     193        if (node.op == UInt32ToNumber)
     194            return node.child1;
    224195
    225196        // Check for numeric constants boxed as JSValues.
     
    227198            JSValue v = valueOfJSConstant(index);
    228199            if (v.isInt32())
    229                 return getInt32Constant(v.asInt32(), node.constantNumber());
     200                return getJSConstant(node.constantNumber());
    230201            if (v.isNumber())
    231                 return getInt32Constant(JSC::toInt32(v.uncheckedGetNumber()), node.constantNumber());
     202                return getJSConstant(node.constantNumber());
    232203        }
    233204
     
    240211        Node& node = m_graph[index];
    241212
    242         if (node.hasDoubleResult())
     213        if (node.hasDoubleResult() || node.hasInt32Result())
    243214            return index;
    244 
    245         if (node.hasInt32Result()) {
    246             if (node.op == Int32Constant)
    247                 return getDoubleConstant(valueOfInt32Constant(index), node.constantNumber());
    248 
    249             // We unique Int32ToNumber nodes in a map to prevent duplicate conversions.
    250             pair<UnaryOpMap::iterator, bool> result = m_int32ToNumberNodes.add(index, NoNode);
    251             // Either we added a new value, or the existing value in the map is non-zero.
    252             ASSERT(result.second == (result.first->second == NoNode));
    253             if (result.second)
    254                 result.first->second = addToGraph(Int32ToNumber, index);
    255             return result.first->second;
    256         }
    257215
    258216        if (node.op == JSConstant) {
    259217            JSValue v = valueOfJSConstant(index);
    260218            if (v.isNumber())
    261                 return getDoubleConstant(v.uncheckedGetNumber(), node.constantNumber());
     219                return getJSConstant(node.constantNumber());
    262220        }
    263221
     
    265223    }
    266224
    267 
    268     // Used in implementing get, above, where the operand is a constant.
    269     NodeIndex getInt32Constant(int32_t value, unsigned constant)
    270     {
    271         NodeIndex index = m_constants[constant].asInt32;
    272         if (index != NoNode)
    273             return index;
    274         NodeIndex resultIndex = addToGraph(Int32Constant, OpInfo(constant));
    275         m_graph[resultIndex].setInt32Constant(value);
    276         m_constants[constant].asInt32 = resultIndex;
    277         return resultIndex;
    278     }
    279     NodeIndex getDoubleConstant(double value, unsigned constant)
    280     {
    281         NodeIndex index = m_constants[constant].asNumeric;
    282         if (index != NoNode)
    283             return index;
    284         NodeIndex resultIndex = addToGraph(DoubleConstant, OpInfo(constant));
    285         m_graph[resultIndex].setDoubleConstant(value);
    286         m_constants[constant].asNumeric = resultIndex;
    287         return resultIndex;
    288     }
    289225    NodeIndex getJSConstant(unsigned constant)
    290226    {
     
    309245
    310246    // Convenience methods for checking nodes for constants.
    311     bool isInt32Constant(NodeIndex index)
    312     {
    313         return m_graph[index].op == Int32Constant;
    314     }
    315     bool isDoubleConstant(NodeIndex index)
    316     {
    317         return m_graph[index].op == DoubleConstant;
    318     }
    319247    bool isJSConstant(NodeIndex index)
    320248    {
    321249        return m_graph[index].op == JSConstant;
    322250    }
    323 
     251    bool isInt32Constant(NodeIndex nodeIndex)
     252    {
     253        return isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isInt32();
     254    }
     255    bool isDoubleConstant(NodeIndex nodeIndex)
     256    {
     257        return isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isNumber();
     258    }
    324259    // Convenience methods for getting constant values.
    325     int32_t valueOfInt32Constant(NodeIndex index)
    326     {
    327         ASSERT(isInt32Constant(index));
    328         return m_graph[index].int32Constant();
    329     }
    330     double valueOfDoubleConstant(NodeIndex index)
    331     {
    332         ASSERT(isDoubleConstant(index));
    333         return m_graph[index].numericConstant();
    334     }
    335260    JSValue valueOfJSConstant(NodeIndex index)
    336261    {
    337262        ASSERT(isJSConstant(index));
    338263        return m_codeBlock->getConstant(FirstConstantRegisterIndex + m_graph[index].constantNumber());
     264    }
     265    int32_t valueOfInt32Constant(NodeIndex nodeIndex)
     266    {
     267        ASSERT(isInt32Constant(nodeIndex));
     268        return valueOfJSConstant(nodeIndex).asInt32();
     269    }
     270    double valueOfDoubleConstant(NodeIndex nodeIndex)
     271    {
     272        ASSERT(isDoubleConstant(nodeIndex));
     273        double value;
     274        bool okay = valueOfJSConstant(nodeIndex).getNumber(value);
     275        ASSERT_UNUSED(okay, okay);
     276        return value;
    339277    }
    340278
     
    399337                JSValue testMe = m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1);
    400338                if (testMe.isInt32() && testMe.asInt32() == 1)
    401                     return getDoubleConstant(1, m_constant1);
     339                    return getJSConstant(m_constant1);
    402340            }
    403341
     
    412350        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).isInt32());
    413351        ASSERT(m_codeBlock->getConstant(FirstConstantRegisterIndex + m_constant1).asInt32() == 1);
    414         return getDoubleConstant(1, m_constant1);
     352        return getJSConstant(m_constant1);
    415353    }
    416354
     
    462400
    463401        if (nodePtr->op == ValueToInt32)
    464             nodePtr = &m_graph[nodePtr->child1];
    465 
    466         if (nodePtr->op == NumberToInt32)
    467402            nodePtr = &m_graph[nodePtr->child1];
    468403
     
    534469    Vector<PhiStackEntry, 16> m_argumentPhiStack;
    535470    Vector<PhiStackEntry, 16> m_localPhiStack;
    536 
    537     // These maps are used to unique ToNumber and ToInt32 operations.
    538     typedef HashMap<NodeIndex, NodeIndex> UnaryOpMap;
    539     UnaryOpMap m_int32ToNumberNodes;
    540     UnaryOpMap m_numberToInt32Nodes;
    541471};
    542472
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r84860 r89611  
    104104        hasPrinted = true;
    105105    }
    106     if (op == Int32Constant) {
    107         printf("%s$%u{%d|0x%08x}", hasPrinted ? ", " : "", node.constantNumber(), node.int32Constant(), node.int32Constant());
    108         hasPrinted = true;
    109     }
    110     if (op == DoubleConstant) {
    111         printf("%s$%u{%f})", hasPrinted ? ", " : "", node.constantNumber(), node.numericConstant());
    112         hasPrinted = true;
    113     }
    114106    if (op == JSConstant) {
    115107        printf("%s$%u", hasPrinted ? ", " : "", node.constantNumber());
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r85271 r89611  
    191191        GPRReg gpr = info.gpr();
    192192        m_gprs.lock(gpr);
    193 
    194193        m_jit.convertInt32ToDouble(gpr, fpr);
    195 
    196         m_gprs.release(gpr);
    197194        m_gprs.unlock(gpr);
    198         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    199         info.fillDouble(fpr);
    200195        return fpr;
    201196    }
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h

    r88280 r89611  
    204204        if (registerFormat == DataFormatInteger) {
    205205            if (node.isConstant()) {
    206                 ASSERT(isIntegerConstant(nodeIndex));
    207                 m_jit.move(Imm32(valueOfIntegerConstant(nodeIndex)), info.gpr());
     206                ASSERT(isInt32Constant(nodeIndex));
     207                m_jit.move(Imm32(valueOfInt32Constant(nodeIndex)), info.gpr());
    208208            } else
    209209                m_jit.load32(JITCompiler::addressFor(spillMe), info.gpr());
     
    212212
    213213        if (node.isConstant())
    214             m_jit.move(constantAsJSValueAsImmPtr(nodeIndex), info.gpr());
     214            m_jit.move(valueOfJSConstantAsImmPtr(nodeIndex), info.gpr());
    215215        else {
    216216            ASSERT(registerFormat & DataFormatJS || registerFormat == DataFormatCell);
     
    228228        ASSERT(info.registerFormat() == DataFormatDouble);
    229229
    230         if (node.isConstant())
    231             m_jit.move(constantAsJSValueAsImmPtr(nodeIndex), info.gpr());
    232         else {
     230        if (node.isConstant()) {
     231            ASSERT(isDoubleConstant(nodeIndex));
     232            m_jit.move(JITCompiler::ImmPtr(bitwise_cast<void*>(valueOfDoubleConstant(nodeIndex))), canTrample);
     233            m_jit.movePtrToDouble(canTrample, info.fpr());
     234        } else {
    233235            m_jit.loadPtr(JITCompiler::addressFor(spillMe), canTrample);
    234236            unboxDouble(canTrample, info.fpr());
     
    382384    // Checks/accessors for constant values.
    383385    bool isConstant(NodeIndex nodeIndex) { return m_jit.isConstant(nodeIndex); }
     386    bool isJSConstant(NodeIndex nodeIndex) { return m_jit.isJSConstant(nodeIndex); }
    384387    bool isInt32Constant(NodeIndex nodeIndex) { return m_jit.isInt32Constant(nodeIndex); }
    385388    bool isDoubleConstant(NodeIndex nodeIndex) { return m_jit.isDoubleConstant(nodeIndex); }
    386     bool isJSConstant(NodeIndex nodeIndex) { return m_jit.isJSConstant(nodeIndex); }
    387389    int32_t valueOfInt32Constant(NodeIndex nodeIndex) { return m_jit.valueOfInt32Constant(nodeIndex); }
    388390    double valueOfDoubleConstant(NodeIndex nodeIndex) { return m_jit.valueOfDoubleConstant(nodeIndex); }
    389391    JSValue valueOfJSConstant(NodeIndex nodeIndex) { return m_jit.valueOfJSConstant(nodeIndex); }
    390 
    391     bool isDoubleConstantWithInt32Value(NodeIndex nodeIndex, int32_t& out)
    392     {
    393         if (!m_jit.isDoubleConstant(nodeIndex))
    394             return false;
    395         double value = m_jit.valueOfDoubleConstant(nodeIndex);
    396 
    397         int32_t asInt32 = static_cast<int32_t>(value);
    398         if (value != asInt32)
    399             return false;
    400         if (!asInt32 && signbit(value))
    401             return false;
    402 
    403         out = asInt32;
    404         return true;
    405     }
    406 
    407     bool isJSConstantWithInt32Value(NodeIndex nodeIndex, int32_t& out)
    408     {
    409         if (!m_jit.isJSConstant(nodeIndex))
    410             return false;
    411         JSValue value = m_jit.valueOfJSConstant(nodeIndex);
    412 
    413         if (!value.isInt32())
    414             return false;
    415        
    416         out = value.asInt32();
    417         return true;
    418     }
    419 
    420     bool isIntegerConstant(NodeIndex nodeIndex)
    421     {
    422         int32_t unused;
    423         return isInt32Constant(nodeIndex)
    424             || isDoubleConstantWithInt32Value(nodeIndex, unused)
    425             || isJSConstantWithInt32Value(nodeIndex, unused);
    426     }
    427 
    428     int32_t valueOfIntegerConstant(NodeIndex nodeIndex)
    429     {
    430         if (isInt32Constant(nodeIndex))
    431             return valueOfInt32Constant(nodeIndex);
    432         int32_t result = 0;
    433         bool okay = isDoubleConstantWithInt32Value(nodeIndex, result);
    434         if (okay)
    435             return result;
    436         okay = isJSConstantWithInt32Value(nodeIndex, result);
    437         ASSERT_UNUSED(okay, okay);
    438         return result;
    439     }
    440392
    441393    Identifier* identifier(unsigned index)
     
    478430#endif
    479431
    480     // Get the JSValue representation of a constant.
    481     JSValue constantAsJSValue(NodeIndex nodeIndex)
    482     {
    483         Node& node = m_jit.graph()[nodeIndex];
    484         if (isInt32Constant(nodeIndex))
    485             return jsNumber(node.int32Constant());
    486         if (isDoubleConstant(nodeIndex))
    487             return JSValue(JSValue::EncodeAsDouble, node.numericConstant());
    488         ASSERT(isJSConstant(nodeIndex));
    489         return valueOfJSConstant(nodeIndex);
    490     }
    491     MacroAssembler::ImmPtr constantAsJSValueAsImmPtr(NodeIndex nodeIndex)
    492     {
    493         return MacroAssembler::ImmPtr(JSValue::encode(constantAsJSValue(nodeIndex)));
     432    MacroAssembler::ImmPtr valueOfJSConstantAsImmPtr(NodeIndex nodeIndex)
     433    {
     434        return MacroAssembler::ImmPtr(JSValue::encode(valueOfJSConstant(nodeIndex)));
    494435    }
    495436
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r88093 r89611  
    4646
    4747    if (node.isConstant()) {
    48         ASSERT(node.op == DoubleConstant);
     48        ASSERT(isDoubleConstant(nodeIndex));
    4949        move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(nodeIndex)))), temporary);
    5050        movePtrToDouble(temporary, fpr);
     
    6868
    6969    if (node.isConstant()) {
    70         ASSERT(node.op == Int32Constant);
     70        ASSERT(isInt32Constant(nodeIndex));
    7171        move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
    7272    } else {
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r87431 r89611  
    180180        return graph()[nodeIndex].isConstant();
    181181    }
     182    bool isJSConstant(NodeIndex nodeIndex)
     183    {
     184        return graph()[nodeIndex].isConstant();
     185    }
    182186    bool isInt32Constant(NodeIndex nodeIndex)
    183187    {
    184         return graph()[nodeIndex].op == Int32Constant;
     188        return isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isInt32();
    185189    }
    186190    bool isDoubleConstant(NodeIndex nodeIndex)
    187191    {
    188         return graph()[nodeIndex].op == DoubleConstant;
    189     }
    190     bool isJSConstant(NodeIndex nodeIndex)
    191     {
    192         return graph()[nodeIndex].op == JSConstant;
    193     }
    194 
     192        return isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isNumber();
     193    }
    195194    // Helper methods get constant values from nodes.
    196     int32_t valueOfInt32Constant(NodeIndex nodeIndex)
    197     {
    198         ASSERT(isInt32Constant(nodeIndex));
    199         return graph()[nodeIndex].int32Constant();
    200     }
    201     double valueOfDoubleConstant(NodeIndex nodeIndex)
    202     {
    203         ASSERT(isDoubleConstant(nodeIndex));
    204         return graph()[nodeIndex].numericConstant();
    205     }
    206195    JSValue valueOfJSConstant(NodeIndex nodeIndex)
    207196    {
     
    209198        unsigned constantIndex = graph()[nodeIndex].constantNumber();
    210199        return codeBlock()->constantRegister(FirstConstantRegisterIndex + constantIndex).get();
     200    }
     201    int32_t valueOfInt32Constant(NodeIndex nodeIndex)
     202    {
     203        ASSERT(isInt32Constant(nodeIndex));
     204        return valueOfJSConstant(nodeIndex).asInt32();
     205    }
     206    double valueOfDoubleConstant(NodeIndex nodeIndex)
     207    {
     208        ASSERT(isDoubleConstant(nodeIndex));
     209        return valueOfJSConstant(nodeIndex).uncheckedGetNumber();
    211210    }
    212211
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r88093 r89611  
    8686#define FOR_EACH_DFG_OP(macro) \
    8787    /* Nodes for constants. */\
    88     macro(JSConstant, NodeResultJS | NodeIsConstant) \
    89     macro(Int32Constant, NodeResultJS | NodeIsConstant) \
    90     macro(DoubleConstant, NodeResultJS | NodeIsConstant) \
     88    macro(JSConstant, NodeResultJS) \
    9189    macro(ConvertThis, NodeResultJS) \
    9290    \
     
    104102    macro(BitURShift, NodeResultInt32) \
    105103    /* Bitwise operators call ToInt32 on their operands. */\
    106     macro(NumberToInt32, NodeResultInt32) \
    107104    macro(ValueToInt32, NodeResultInt32 | NodeMustGenerate) \
    108105    /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
     
    116113    macro(ArithMod, NodeResultDouble) \
    117114    /* Arithmetic operators call ToNumber on their operands. */\
    118     macro(Int32ToNumber, NodeResultDouble) \
    119115    macro(ValueToNumber, NodeResultDouble | NodeMustGenerate) \
    120116    \
     
    212208        , m_refCount(0)
    213209        , m_opInfo(imm1.m_value)
    214     {
    215         m_constantValue.opInfo2 = imm2.m_value;
     210        , m_opInfo2(imm2.m_value)
     211    {
    216212    }
    217213
     
    223219    bool isConstant()
    224220    {
    225         return op & NodeIsConstant;
     221        return op == JSConstant;
    226222    }
    227223
     
    293289    }
    294290
    295     int32_t int32Constant()
    296     {
    297         ASSERT(op == Int32Constant);
    298         return m_constantValue.asInt32;
    299     }
    300 
    301     void setInt32Constant(int32_t value)
    302     {
    303         ASSERT(op == Int32Constant);
    304         m_constantValue.asInt32 = value;
    305     }
    306 
    307     double numericConstant()
    308     {
    309         ASSERT(op == DoubleConstant);
    310         return m_constantValue.asDouble;
    311     }
    312 
    313     void setDoubleConstant(double value)
    314     {
    315         ASSERT(op == DoubleConstant);
    316         m_constantValue.asDouble = value;
    317     }
    318 
    319291    bool isJump()
    320292    {
     
    341313    {
    342314        ASSERT(isBranch());
    343         return m_constantValue.opInfo2;
     315        return m_opInfo2;
    344316    }
    345317
     
    391363    // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
    392364    unsigned m_refCount;
    393     // An immediate value, accesses type-checked via accessors above.
    394     unsigned m_opInfo;
    395     // The value of an int32/double constant.
    396     union {
    397         int32_t asInt32;
    398         double asDouble;
    399         unsigned opInfo2;
    400     } m_constantValue;
     365    // Immediate values, accesses type-checked via accessors above.
     366    unsigned m_opInfo, m_opInfo2;
    401367};
    402368
  • trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp

    r85271 r89611  
    104104    silentFillAllRegisters(result);
    105105    JITCompiler::Jump hasCalledToInt32 = m_jit.jump();
    106    
     106
    107107    // Then handle integers.
    108108    isInteger.link(&m_jit);
     
    128128bool NonSpeculativeJIT::isKnownInteger(NodeIndex nodeIndex)
    129129{
     130    if (isInt32Constant(nodeIndex))
     131        return true;
     132
    130133    GenerationInfo& info = m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()];
    131134
     
    139142
    140143    ASSERT(isConstant(nodeIndex));
    141     return isInt32Constant(nodeIndex);
     144    return false;
    142145}
    143146
    144147bool NonSpeculativeJIT::isKnownNumeric(NodeIndex nodeIndex)
    145148{
     149    if (isInt32Constant(nodeIndex) || isDoubleConstant(nodeIndex))
     150        return true;
     151
    146152    GenerationInfo& info = m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()];
    147153
     
    157163
    158164    ASSERT(isConstant(nodeIndex));
    159     return isInt32Constant(nodeIndex) || isDoubleConstant(nodeIndex);
     165    return false;
    160166}
    161167
     
    185191    }
    186192
    187     case Int32Constant:
    188     case DoubleConstant:
    189193    case JSConstant:
    190194        initConstantInfo(m_compileIndex);
     
    280284    }
    281285
    282     case Int32ToNumber: {
    283         IntegerOperand op1(this, node.child1);
    284         FPRTemporary result(this);
    285         m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
    286         doubleResult(result.fpr(), m_compileIndex);
    287         break;
    288     }
    289 
    290     case NumberToInt32:
    291286    case ValueToInt32: {
    292287        ASSERT(!isInt32Constant(node.child1));
     
    300295        }
    301296
    302         if (isKnownNumeric(node.child1)) {
     297        GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister()];
     298        if ((childInfo.registerFormat() || DataFormatJS) == DataFormatJSDouble) {
    303299            DoubleOperand op1(this, node.child1);
    304300            GPRTemporary result(this);
     
    307303            break;
    308304        }
    309 
    310         // We should have handled this via isKnownInteger, or isKnownNumeric!
    311         ASSERT(op != NumberToInt32);
    312305
    313306        JSValueOperand op1(this, node.child1);
     
    330323        }
    331324
    332         if (isKnownNumeric(node.child1)) {
     325        GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1].virtualRegister()];
     326        if ((childInfo.registerFormat() || DataFormatJS) == DataFormatJSDouble) {
    333327            DoubleOperand op1(this, node.child1);
    334328            FPRTemporary result(this, op1);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r89084 r89611  
    5050                return gpr;
    5151            }
    52             m_jit.move(constantAsJSValueAsImmPtr(nodeIndex), gpr);
     52            m_jit.move(valueOfJSConstantAsImmPtr(nodeIndex), gpr);
    5353        } else {
    5454            DataFormat spillFormat = info.spillFormat();
     
    186186
    187187        if (node.isConstant()) {
    188             JSValue jsValue = constantAsJSValue(nodeIndex);
     188            JSValue jsValue = valueOfJSConstant(nodeIndex);
    189189            if (jsValue.isCell()) {
    190190                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     
    249249    }
    250250
    251     int32_t imm;
    252     if (isJSConstantWithInt32Value(node.child1, imm)) {
     251    if (isInt32Constant(node.child1)) {
     252        int32_t imm = valueOfInt32Constant(node.child1);
    253253        SpeculateIntegerOperand op2(this, node.child2);
    254254        addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
    255     } else if (isJSConstantWithInt32Value(node.child2, imm)) {
    256         SpeculateIntegerOperand op1(this, node.child1);
     255    } else if (isInt32Constant(node.child2)) {
     256        SpeculateIntegerOperand op1(this, node.child1);
     257        int32_t imm = valueOfInt32Constant(node.child2);
    257258        addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
    258259    } else {
     
    303304
    304305    switch (op) {
    305     case Int32Constant:
    306     case DoubleConstant:
    307306    case JSConstant:
    308307        initConstantInfo(m_compileIndex);
     
    423422    }
    424423
    425     case NumberToInt32: {
     424    case ValueToInt32: {
    426425        SpeculateIntegerOperand op1(this, node.child1);
    427426        GPRTemporary result(this, op1);
     
    431430    }
    432431
    433     case Int32ToNumber: {
     432    case ValueToNumber: {
    434433        SpeculateIntegerOperand op1(this, node.child1);
    435434        GPRTemporary result(this, op1);
     
    439438    }
    440439
    441     case ValueToInt32: {
    442         SpeculateIntegerOperand op1(this, node.child1);
    443         GPRTemporary result(this, op1);
    444         m_jit.move(op1.gpr(), result.gpr());
    445         integerResult(result.gpr(), m_compileIndex, op1.format());
    446         break;
    447     }
    448 
    449     case ValueToNumber: {
    450         SpeculateIntegerOperand op1(this, node.child1);
    451         GPRTemporary result(this, op1);
    452         m_jit.move(op1.gpr(), result.gpr());
    453         integerResult(result.gpr(), m_compileIndex, op1.format());
    454         break;
    455     }
    456 
    457440    case ValueAdd:
    458441    case ArithAdd: {
    459         int32_t imm1;
    460         if (isDoubleConstantWithInt32Value(node.child1, imm1)) {
     442        if (isInt32Constant(node.child1)) {
     443            int32_t imm1 = valueOfInt32Constant(node.child1);
    461444            SpeculateIntegerOperand op2(this, node.child2);
    462445            GPRTemporary result(this);
     
    468451        }
    469452           
    470         int32_t imm2;
    471         if (isDoubleConstantWithInt32Value(node.child2, imm2)) {
     453        if (isInt32Constant(node.child2)) {
    472454            SpeculateIntegerOperand op1(this, node.child1);
     455            int32_t imm2 = valueOfInt32Constant(node.child2);
    473456            GPRTemporary result(this);
    474457
     
    500483
    501484    case ArithSub: {
    502         int32_t imm2;
    503         if (isDoubleConstantWithInt32Value(node.child2, imm2)) {
     485        if (isInt32Constant(node.child2)) {
    504486            SpeculateIntegerOperand op1(this, node.child1);
     487            int32_t imm2 = valueOfInt32Constant(node.child2);
    505488            GPRTemporary result(this);
    506489
Note: See TracChangeset for help on using the changeset viewer.