Changeset 96377 in webkit


Ignore:
Timestamp:
Sep 29, 2011 4:29:09 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Refactor out trivially duplicated code in DFGJITCodeGenerator.
https://bugs.webkit.org/show_bug.cgi?id=69109

Reviewed by Oliver Hunt.

Some code is trivially redundant between DFGJITCodeGenerator.cpp & DFGJITCodeGenerator32_64.cpp

Basically move a JSVALUE64 specific code into a new DFGJITCodeGenerator64.cpp, leave common code
in DFGJITCodeGenerator.cpp, and remove copies from DFGJITCodeGenerator32_64.cpp.

For some function differences are trivial & make more sense to ifdef individually, and some
Operand methods make more sense left in DFGJITCodeGenerator.cpp alongside similar constructors.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGJITCodeGenerator.cpp:

(JSC::DFG::JITCodeGenerator::isKnownNotNumber):
(JSC::DFG::JITCodeGenerator::isKnownBoolean):
(JSC::DFG::JITCodeGenerator::writeBarrier):
(JSC::DFG::JITCodeGenerator::dump):
(JSC::DFG::JITCodeGenerator::checkConsistency):
(JSC::DFG::GPRTemporary::GPRTemporary):
(JSC::DFG::FPRTemporary::FPRTemporary):

  • dfg/DFGJITCodeGenerator32_64.cpp:
  • dfg/DFGJITCodeGenerator64.cpp: Copied from Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp.
  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::branchIfNotCell):

  • dfg/DFGJITCompilerInlineMethods.h:
Location:
trunk/Source/JavaScriptCore
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r96375 r96377  
     12011-09-29  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Refactor out trivially duplicated code in DFGJITCodeGenerator.
     4        https://bugs.webkit.org/show_bug.cgi?id=69109
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Some code is trivially redundant between DFGJITCodeGenerator.cpp & DFGJITCodeGenerator32_64.cpp
     9
     10        Basically move a JSVALUE64 specific code into a new DFGJITCodeGenerator64.cpp, leave common code
     11        in DFGJITCodeGenerator.cpp, and remove copies from DFGJITCodeGenerator32_64.cpp.
     12
     13        For some function differences are trivial & make more sense to ifdef individually, and some
     14        Operand methods make more sense left in DFGJITCodeGenerator.cpp alongside similar constructors.
     15
     16        * JavaScriptCore.xcodeproj/project.pbxproj:
     17        * dfg/DFGJITCodeGenerator.cpp:
     18        (JSC::DFG::JITCodeGenerator::isKnownNotNumber):
     19        (JSC::DFG::JITCodeGenerator::isKnownBoolean):
     20        (JSC::DFG::JITCodeGenerator::writeBarrier):
     21        (JSC::DFG::JITCodeGenerator::dump):
     22        (JSC::DFG::JITCodeGenerator::checkConsistency):
     23        (JSC::DFG::GPRTemporary::GPRTemporary):
     24        (JSC::DFG::FPRTemporary::FPRTemporary):
     25        * dfg/DFGJITCodeGenerator32_64.cpp:
     26        * dfg/DFGJITCodeGenerator64.cpp: Copied from Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp.
     27        * dfg/DFGJITCompiler.h:
     28        (JSC::DFG::JITCompiler::branchIfNotCell):
     29        * dfg/DFGJITCompilerInlineMethods.h:
     30
    1312011-09-28  Filip Pizlo  <fpizlo@apple.com>
    232
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r96375 r96377  
    304304                86880F1E14328BB900B08D42 /* DFGJITCompilerInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 86880F1A14328BB900B08D42 /* DFGJITCompilerInlineMethods.h */; };
    305305                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
     306                86880F44143531A800B08D42 /* DFGJITCodeGenerator64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F43143531A700B08D42 /* DFGJITCodeGenerator64.cpp */; };
    306307                868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA00117CEFD100B908B1 /* AtomicString.cpp */; };
    307308                868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA01117CEFD100B908B1 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    10701071                86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT32_64.cpp; path = dfg/DFGSpeculativeJIT32_64.cpp; sourceTree = "<group>"; };
    10711072                86880F311434FFAF00B08D42 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
     1073                86880F43143531A700B08D42 /* DFGJITCodeGenerator64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCodeGenerator64.cpp; path = dfg/DFGJITCodeGenerator64.cpp; sourceTree = "<group>"; };
    10721074                868BFA00117CEFD100B908B1 /* AtomicString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AtomicString.cpp; path = text/AtomicString.cpp; sourceTree = "<group>"; };
    10731075                868BFA01117CEFD100B908B1 /* AtomicString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicString.h; path = text/AtomicString.h; sourceTree = "<group>"; };
     
    22812283                                86EC9DBA1328DF82002B2AD7 /* DFGJITCodeGenerator.h */,
    22822284                                86880F1814328BB900B08D42 /* DFGJITCodeGenerator32_64.cpp */,
     2285                                86880F43143531A700B08D42 /* DFGJITCodeGenerator64.cpp */,
    22832286                                86EC9DBB1328DF82002B2AD7 /* DFGJITCompiler.cpp */,
    22842287                                86EC9DBC1328DF82002B2AD7 /* DFGJITCompiler.h */,
     
    33813384                                86880F1D14328BB900B08D42 /* DFGJITCompiler32_64.cpp in Sources */,
    33823385                                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
     3386                                86880F44143531A800B08D42 /* DFGJITCodeGenerator64.cpp in Sources */,
    33833387                        );
    33843388                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r96372 r96377  
    2828
    2929#if ENABLE(DFG_JIT)
    30 #if USE(JSVALUE64)
    31 
     30
     31#include "DFGJITCompilerInlineMethods.h"
    3232#include "DFGSpeculativeJIT.h"
    3333#include "LinkBuffer.h"
     
    4343    m_gprs = RegisterBank<GPRInfo>();
    4444    m_fprs = RegisterBank<FPRInfo>();
    45 }
    46 
    47 GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
    48 {
    49     Node& node = m_jit.graph()[nodeIndex];
    50     VirtualRegister virtualRegister = node.virtualRegister();
    51     GenerationInfo& info = m_generationInfo[virtualRegister];
    52 
    53     if (info.registerFormat() == DataFormatNone) {
    54         GPRReg gpr = allocate();
    55 
    56         if (node.hasConstant()) {
    57             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    58             if (isInt32Constant(nodeIndex)) {
    59                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
    60                 info.fillInteger(gpr);
    61                 returnFormat = DataFormatInteger;
    62                 return gpr;
    63             }
    64             if (isNumberConstant(nodeIndex)) {
    65                 JSValue jsValue = jsNumber(valueOfNumberConstant(nodeIndex));
    66                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    67             } else {
    68                 ASSERT(isJSConstant(nodeIndex));
    69                 JSValue jsValue = valueOfJSConstant(nodeIndex);
    70                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    71             }
    72         } else {
    73             ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
    74             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    75             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    76         }
    77 
    78         // Since we statically know that we're filling an integer, and values
    79         // in the RegisterFile are boxed, this must be DataFormatJSInteger.
    80         // We will check this with a jitAssert below.
    81         info.fillJSValue(gpr, DataFormatJSInteger);
    82         unlock(gpr);
    83     }
    84 
    85     switch (info.registerFormat()) {
    86     case DataFormatNone:
    87         // Should have filled, above.
    88     case DataFormatJSDouble:
    89     case DataFormatDouble:
    90     case DataFormatJS:
    91     case DataFormatCell:
    92     case DataFormatJSCell:
    93     case DataFormatBoolean:
    94     case DataFormatJSBoolean:
    95     case DataFormatStorage:
    96         // Should only be calling this function if we know this operand to be integer.
    97         ASSERT_NOT_REACHED();
    98 
    99     case DataFormatJSInteger: {
    100         GPRReg gpr = info.gpr();
    101         m_gprs.lock(gpr);
    102         m_jit.jitAssertIsJSInt32(gpr);
    103         returnFormat = DataFormatJSInteger;
    104         return gpr;
    105     }
    106 
    107     case DataFormatInteger: {
    108         GPRReg gpr = info.gpr();
    109         m_gprs.lock(gpr);
    110         m_jit.jitAssertIsInt32(gpr);
    111         returnFormat = DataFormatInteger;
    112         return gpr;
    113     }
    114     }
    115 
    116     ASSERT_NOT_REACHED();
    117     return InvalidGPRReg;
    118 }
    119 
    120 FPRReg JITCodeGenerator::fillDouble(NodeIndex nodeIndex)
    121 {
    122     Node& node = m_jit.graph()[nodeIndex];
    123     VirtualRegister virtualRegister = node.virtualRegister();
    124     GenerationInfo& info = m_generationInfo[virtualRegister];
    125 
    126     if (info.registerFormat() == DataFormatNone) {
    127         GPRReg gpr = allocate();
    128 
    129         if (node.hasConstant()) {
    130             if (isInt32Constant(nodeIndex)) {
    131                 // FIXME: should not be reachable?
    132                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
    133                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    134                 info.fillInteger(gpr);
    135                 unlock(gpr);
    136             } else if (isNumberConstant(nodeIndex)) {
    137                 FPRReg fpr = fprAllocate();
    138                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(nodeIndex)))), gpr);
    139                 m_jit.movePtrToDouble(gpr, fpr);
    140                 unlock(gpr);
    141 
    142                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    143                 info.fillDouble(fpr);
    144                 return fpr;
    145             } else {
    146                 // FIXME: should not be reachable?
    147                 ASSERT(isJSConstant(nodeIndex));
    148                 JSValue jsValue = valueOfJSConstant(nodeIndex);
    149                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    150                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    151                 info.fillJSValue(gpr, DataFormatJS);
    152                 unlock(gpr);
    153             }
    154         } else {
    155             DataFormat spillFormat = info.spillFormat();
    156             ASSERT(spillFormat & DataFormatJS);
    157             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    158             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    159             info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
    160             unlock(gpr);
    161         }
    162     }
    163 
    164     switch (info.registerFormat()) {
    165     case DataFormatNone:
    166         // Should have filled, above.
    167     case DataFormatCell:
    168     case DataFormatJSCell:
    169     case DataFormatBoolean:
    170     case DataFormatJSBoolean:
    171     case DataFormatStorage:
    172         // Should only be calling this function if we know this operand to be numeric.
    173         ASSERT_NOT_REACHED();
    174 
    175     case DataFormatJS: {
    176         GPRReg jsValueGpr = info.gpr();
    177         m_gprs.lock(jsValueGpr);
    178         FPRReg fpr = fprAllocate();
    179         GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
    180 
    181         JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    182 
    183         m_jit.jitAssertIsJSDouble(jsValueGpr);
    184 
    185         // First, if we get here we have a double encoded as a JSValue
    186         m_jit.move(jsValueGpr, tempGpr);
    187         unboxDouble(tempGpr, fpr);
    188         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
    189 
    190         // Finally, handle integers.
    191         isInteger.link(&m_jit);
    192         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
    193         hasUnboxedDouble.link(&m_jit);
    194 
    195         m_gprs.release(jsValueGpr);
    196         m_gprs.unlock(jsValueGpr);
    197         m_gprs.unlock(tempGpr);
    198         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    199         info.fillDouble(fpr);
    200         info.killSpilled();
    201         return fpr;
    202     }
    203 
    204     case DataFormatJSInteger:
    205     case DataFormatInteger: {
    206         FPRReg fpr = fprAllocate();
    207         GPRReg gpr = info.gpr();
    208         m_gprs.lock(gpr);
    209         m_jit.convertInt32ToDouble(gpr, fpr);
    210         m_gprs.unlock(gpr);
    211         return fpr;
    212     }
    213 
    214     // Unbox the double
    215     case DataFormatJSDouble: {
    216         GPRReg gpr = info.gpr();
    217         FPRReg fpr = fprAllocate();
    218         if (m_gprs.isLocked(gpr)) {
    219             // Make sure we don't trample gpr if it is in use.
    220             GPRReg temp = allocate();
    221             m_jit.move(gpr, temp);
    222             unboxDouble(temp, fpr);
    223             unlock(temp);
    224         } else
    225             unboxDouble(gpr, fpr);
    226 
    227         m_gprs.release(gpr);
    228         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
    229 
    230         info.fillDouble(fpr);
    231         return fpr;
    232     }
    233 
    234     case DataFormatDouble: {
    235         FPRReg fpr = info.fpr();
    236         m_fprs.lock(fpr);
    237         return fpr;
    238     }
    239     }
    240 
    241     ASSERT_NOT_REACHED();
    242     return InvalidFPRReg;
    243 }
    244 
    245 GPRReg JITCodeGenerator::fillJSValue(NodeIndex nodeIndex)
    246 {
    247     Node& node = m_jit.graph()[nodeIndex];
    248     VirtualRegister virtualRegister = node.virtualRegister();
    249     GenerationInfo& info = m_generationInfo[virtualRegister];
    250 
    251     switch (info.registerFormat()) {
    252     case DataFormatNone: {
    253         GPRReg gpr = allocate();
    254 
    255         if (node.hasConstant()) {
    256             if (isInt32Constant(nodeIndex)) {
    257                 info.fillJSValue(gpr, DataFormatJSInteger);
    258                 JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
    259                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    260             } else if (isNumberConstant(nodeIndex)) {
    261                 info.fillJSValue(gpr, DataFormatJSDouble);
    262                 JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(nodeIndex));
    263                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    264             } else {
    265                 ASSERT(isJSConstant(nodeIndex));
    266                 JSValue jsValue = valueOfJSConstant(nodeIndex);
    267                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
    268                 info.fillJSValue(gpr, DataFormatJS);
    269             }
    270 
    271             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    272         } else {
    273             DataFormat spillFormat = info.spillFormat();
    274             ASSERT(spillFormat & DataFormatJS);
    275             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    276             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    277             info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
    278         }
    279         return gpr;
    280     }
    281 
    282     case DataFormatInteger: {
    283         GPRReg gpr = info.gpr();
    284         // If the register has already been locked we need to take a copy.
    285         // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
    286         if (m_gprs.isLocked(gpr)) {
    287             GPRReg result = allocate();
    288             m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr, result);
    289             return result;
    290         }
    291         m_gprs.lock(gpr);
    292         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
    293         info.fillJSValue(gpr, DataFormatJSInteger);
    294         return gpr;
    295     }
    296 
    297     case DataFormatDouble: {
    298         FPRReg fpr = info.fpr();
    299         GPRReg gpr = boxDouble(fpr);
    300 
    301         // Update all info
    302         info.fillJSValue(gpr, DataFormatJSDouble);
    303         m_fprs.release(fpr);
    304         m_gprs.retain(gpr, virtualRegister, SpillOrderJS);
    305 
    306         return gpr;
    307     }
    308 
    309     case DataFormatCell:
    310         // No retag required on JSVALUE64!
    311     case DataFormatJS:
    312     case DataFormatJSInteger:
    313     case DataFormatJSDouble:
    314     case DataFormatJSCell:
    315     case DataFormatJSBoolean: {
    316         GPRReg gpr = info.gpr();
    317         m_gprs.lock(gpr);
    318         return gpr;
    319     }
    320        
    321     case DataFormatBoolean:
    322     case DataFormatStorage:
    323         // this type currently never occurs
    324         ASSERT_NOT_REACHED();
    325     }
    326 
    327     ASSERT_NOT_REACHED();
    328     return InvalidGPRReg;
    32945}
    33046
     
    476192}
    477193
    478 void JITCodeGenerator::nonSpeculativeValueToNumber(Node& node)
    479 {
    480     if (isKnownNumeric(node.child1())) {
    481         JSValueOperand op1(this, node.child1());
    482         GPRTemporary result(this, op1);
    483         m_jit.move(op1.gpr(), result.gpr());
    484         jsValueResult(result.gpr(), m_compileIndex);
    485         return;
    486     }
    487 
    488     JSValueOperand op1(this, node.child1());
    489     GPRTemporary result(this);
    490    
    491     ASSERT(!isInt32Constant(node.child1()));
    492     ASSERT(!isNumberConstant(node.child1()));
    493    
    494     GPRReg jsValueGpr = op1.gpr();
    495     GPRReg gpr = result.gpr();
    496     op1.use();
    497 
    498     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    499     JITCompiler::Jump nonNumeric = m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    500 
    501     // First, if we get here we have a double encoded as a JSValue
    502     m_jit.move(jsValueGpr, gpr);
    503     JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
    504 
    505     // Next handle cells (& other JS immediates)
    506     nonNumeric.link(&m_jit);
    507     silentSpillAllRegisters(gpr);
    508     m_jit.move(jsValueGpr, GPRInfo::argumentGPR1);
    509     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    510     appendCallWithExceptionCheck(dfgConvertJSValueToNumber);
    511     boxDouble(FPRInfo::returnValueFPR, gpr);
    512     silentFillAllRegisters(gpr);
    513     JITCompiler::Jump hasCalledToNumber = m_jit.jump();
    514    
    515     // Finally, handle integers.
    516     isInteger.link(&m_jit);
    517     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, jsValueGpr, gpr);
    518     hasUnboxedDouble.link(&m_jit);
    519     hasCalledToNumber.link(&m_jit);
    520    
    521     jsValueResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
    522 }
    523 
    524 void JITCodeGenerator::nonSpeculativeValueToInt32(Node& node)
    525 {
    526     ASSERT(!isInt32Constant(node.child1()));
    527    
    528     if (isKnownInteger(node.child1())) {
    529         IntegerOperand op1(this, node.child1());
    530         GPRTemporary result(this, op1);
    531         m_jit.move(op1.gpr(), result.gpr());
    532         integerResult(result.gpr(), m_compileIndex);
    533         return;
    534     }
    535    
    536     GenerationInfo& childInfo = m_generationInfo[m_jit.graph()[node.child1()].virtualRegister()];
    537     if (isJSDouble(childInfo.registerFormat())) {
    538         DoubleOperand op1(this, node.child1());
    539         GPRTemporary result(this);
    540         FPRReg fpr = op1.fpr();
    541         GPRReg gpr = result.gpr();
    542         op1.use();
    543         JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
    544        
    545         silentSpillAllRegisters(gpr);
    546        
    547         m_jit.moveDouble(fpr, FPRInfo::argumentFPR0);
    548         appendCallWithExceptionCheck(toInt32);
    549         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, gpr);
    550        
    551         silentFillAllRegisters(gpr);
    552        
    553         truncatedToInteger.link(&m_jit);
    554         integerResult(gpr, m_compileIndex, UseChildrenCalledExplicitly);
    555         return;
    556     }
    557    
    558     JSValueOperand op1(this, node.child1());
    559     GPRTemporary result(this, op1);
    560     GPRReg jsValueGpr = op1.gpr();
    561     GPRReg resultGPR = result.gpr();
    562     op1.use();
    563 
    564     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
    565 
    566     // First handle non-integers
    567     silentSpillAllRegisters(resultGPR);
    568     m_jit.move(jsValueGpr, GPRInfo::argumentGPR1);
    569     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    570     appendCallWithExceptionCheck(dfgConvertJSValueToInt32);
    571     m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, resultGPR);
    572     silentFillAllRegisters(resultGPR);
    573     JITCompiler::Jump hasCalledToInt32 = m_jit.jump();
    574 
    575     // Then handle integers.
    576     isInteger.link(&m_jit);
    577     m_jit.zeroExtend32ToPtr(jsValueGpr, resultGPR);
    578     hasCalledToInt32.link(&m_jit);
    579     integerResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
    580 }
    581 
    582 void JITCodeGenerator::nonSpeculativeUInt32ToNumber(Node& node)
    583 {
    584     IntegerOperand op1(this, node.child1());
    585     FPRTemporary boxer(this);
    586     GPRTemporary result(this, op1);
    587    
    588     JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0));
    589    
    590     m_jit.convertInt32ToDouble(op1.gpr(), boxer.fpr());
    591     m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), boxer.fpr());
    592    
    593     boxDouble(boxer.fpr(), result.gpr());
    594    
    595     JITCompiler::Jump done = m_jit.jump();
    596    
    597     positive.link(&m_jit);
    598    
    599     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, op1.gpr(), result.gpr());
    600    
    601     done.link(&m_jit);
    602    
    603     jsValueResult(result.gpr(), m_compileIndex);
    604 }
    605 
    606 void JITCodeGenerator::nonSpeculativeKnownConstantArithOp(NodeType op, NodeIndex regChild, NodeIndex immChild, bool commute)
    607 {
    608     JSValueOperand regArg(this, regChild);
    609     GPRReg regArgGPR = regArg.gpr();
    610     GPRTemporary result(this);
    611     GPRReg resultGPR = result.gpr();
    612     FPRTemporary tmp1(this);
    613     FPRTemporary tmp2(this);
    614     FPRReg tmp1FPR = tmp1.fpr();
    615     FPRReg tmp2FPR = tmp2.fpr();
    616    
    617     regArg.use();
    618     use(immChild);
    619 
    620     JITCompiler::Jump notInt;
    621    
    622     int32_t imm = valueOfInt32Constant(immChild);
    623        
    624     if (!isKnownInteger(regChild))
    625         notInt = m_jit.branchPtr(MacroAssembler::Below, regArgGPR, GPRInfo::tagTypeNumberRegister);
    626    
    627     JITCompiler::Jump overflow;
    628    
    629     switch (op) {
    630     case ValueAdd:
    631     case ArithAdd:
    632         overflow = m_jit.branchAdd32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
    633         break;
    634        
    635     case ArithSub:
    636         overflow = m_jit.branchSub32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
    637         break;
    638        
    639     default:
    640         ASSERT_NOT_REACHED();
    641     }
    642    
    643     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    644        
    645     JITCompiler::Jump done = m_jit.jump();
    646    
    647     overflow.link(&m_jit);
    648    
    649     JITCompiler::Jump notNumber;
    650    
    651     // first deal with overflow case
    652     m_jit.convertInt32ToDouble(regArgGPR, tmp2FPR);
    653    
    654     // now deal with not-int case, if applicable
    655     if (!isKnownInteger(regChild)) {
    656         JITCompiler::Jump haveValue = m_jit.jump();
    657        
    658         notInt.link(&m_jit);
    659        
    660         if (!isKnownNumeric(regChild)) {
    661             ASSERT(op == ValueAdd);
    662             notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, regArgGPR, GPRInfo::tagTypeNumberRegister);
    663         }
    664        
    665         m_jit.move(regArgGPR, resultGPR);
    666         m_jit.addPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    667         m_jit.movePtrToDouble(resultGPR, tmp2FPR);
    668        
    669         haveValue.link(&m_jit);
    670     }
    671    
    672     m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(immChild)))), resultGPR);
    673     m_jit.movePtrToDouble(resultGPR, tmp1FPR);
    674     switch (op) {
    675     case ValueAdd:
    676     case ArithAdd:
    677         m_jit.addDouble(tmp1FPR, tmp2FPR);
    678         break;
    679        
    680     case ArithSub:
    681         m_jit.subDouble(tmp1FPR, tmp2FPR);
    682         break;
    683            
    684     default:
    685         ASSERT_NOT_REACHED();
    686     }
    687    
    688     JITCompiler::Jump doneCaseConvertedToInt;
    689    
    690     if (op == ValueAdd) {
    691         JITCompiler::JumpList failureCases;
    692         m_jit.branchConvertDoubleToInt32(tmp2FPR, resultGPR, failureCases, tmp1FPR);
    693         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    694        
    695         doneCaseConvertedToInt = m_jit.jump();
    696        
    697         failureCases.link(&m_jit);
    698     }
    699    
    700     m_jit.moveDoubleToPtr(tmp2FPR, resultGPR);
    701     m_jit.subPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    702        
    703     if (!isKnownNumeric(regChild)) {
    704         ASSERT(notNumber.isSet());
    705         ASSERT(op == ValueAdd);
    706            
    707         JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
    708            
    709         notNumber.link(&m_jit);
    710            
    711         silentSpillAllRegisters(resultGPR);
    712         if (commute) {
    713             m_jit.move(regArgGPR, GPRInfo::argumentGPR2);
    714             m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR1);
    715         } else {
    716             m_jit.move(regArgGPR, GPRInfo::argumentGPR1);
    717             m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR2);
    718         }
    719         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    720         appendCallWithExceptionCheck(operationValueAddNotNumber);
    721         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    722         silentFillAllRegisters(resultGPR);
    723            
    724         doneCaseWasNumber.link(&m_jit);
    725     }
    726    
    727     done.link(&m_jit);
    728     if (doneCaseConvertedToInt.isSet())
    729         doneCaseConvertedToInt.link(&m_jit);
    730        
    731     jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
    732 }
    733 
    734 void JITCodeGenerator::nonSpeculativeBasicArithOp(NodeType op, Node &node)
    735 {
    736     JSValueOperand arg1(this, node.child1());
    737     JSValueOperand arg2(this, node.child2());
    738    
    739     FPRTemporary tmp1(this);
    740     FPRTemporary tmp2(this);
    741     FPRReg tmp1FPR = tmp1.fpr();
    742     FPRReg tmp2FPR = tmp2.fpr();
    743    
    744     GPRTemporary result(this);
    745 
    746     GPRReg arg1GPR = arg1.gpr();
    747     GPRReg arg2GPR = arg2.gpr();
    748    
    749     GPRReg resultGPR = result.gpr();
    750    
    751     arg1.use();
    752     arg2.use();
    753    
    754     JITCompiler::Jump child1NotInt;
    755     JITCompiler::Jump child2NotInt;
    756     JITCompiler::JumpList overflow;
    757    
    758     if (!isKnownInteger(node.child1()))
    759         child1NotInt = m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister);
    760     if (!isKnownInteger(node.child2()))
    761         child2NotInt = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
    762    
    763     switch (op) {
    764     case ValueAdd:
    765     case ArithAdd: {
    766         overflow.append(m_jit.branchAdd32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
    767         break;
    768     }
    769        
    770     case ArithSub: {
    771         overflow.append(m_jit.branchSub32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
    772         break;
    773     }
    774        
    775     case ArithMul: {
    776         overflow.append(m_jit.branchMul32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
    777         overflow.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR));
    778         break;
    779     }
    780        
    781     default:
    782         ASSERT_NOT_REACHED();
    783     }
    784    
    785     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    786        
    787     JITCompiler::Jump done = m_jit.jump();
    788    
    789     JITCompiler::JumpList haveFPRArguments;
    790 
    791     overflow.link(&m_jit);
    792        
    793     // both arguments are integers
    794     m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
    795     m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
    796        
    797     haveFPRArguments.append(m_jit.jump());
    798        
    799     JITCompiler::JumpList notNumbers;
    800        
    801     JITCompiler::Jump child2NotInt2;
    802        
    803     if (!isKnownInteger(node.child1())) {
    804         child1NotInt.link(&m_jit);
    805            
    806         if (!isKnownNumeric(node.child1())) {
    807             ASSERT(op == ValueAdd);
    808             notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg1GPR, GPRInfo::tagTypeNumberRegister));
    809         }
    810            
    811         m_jit.move(arg1GPR, resultGPR);
    812         unboxDouble(resultGPR, tmp1FPR);
    813            
    814         // child1 is converted to a double; child2 may either be an int or
    815         // a boxed double
    816            
    817         if (!isKnownInteger(node.child2())) {
    818             if (isKnownNumeric(node.child2()))
    819                 child2NotInt2 = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
    820             else {
    821                 ASSERT(op == ValueAdd);
    822                 JITCompiler::Jump child2IsInt = m_jit.branchPtr(MacroAssembler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
    823                 notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
    824                 child2NotInt2 = m_jit.jump();
    825                 child2IsInt.link(&m_jit);
    826             }
    827         }
    828            
    829         // child 2 is definitely an integer
    830         m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
    831            
    832         haveFPRArguments.append(m_jit.jump());
    833     }
    834        
    835     if (!isKnownInteger(node.child2())) {
    836         child2NotInt.link(&m_jit);
    837            
    838         if (!isKnownNumeric(node.child2())) {
    839             ASSERT(op == ValueAdd);
    840             notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
    841         }
    842            
    843         // child1 is definitely an integer, and child 2 is definitely not
    844            
    845         m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
    846            
    847         if (child2NotInt2.isSet())
    848             child2NotInt2.link(&m_jit);
    849            
    850         m_jit.move(arg2GPR, resultGPR);
    851         unboxDouble(resultGPR, tmp2FPR);
    852     }
    853        
    854     haveFPRArguments.link(&m_jit);
    855        
    856     switch (op) {
    857     case ValueAdd:
    858     case ArithAdd:
    859         m_jit.addDouble(tmp2FPR, tmp1FPR);
    860         break;
    861            
    862     case ArithSub:
    863         m_jit.subDouble(tmp2FPR, tmp1FPR);
    864         break;
    865            
    866     case ArithMul:
    867         m_jit.mulDouble(tmp2FPR, tmp1FPR);
    868         break;
    869            
    870     default:
    871         ASSERT_NOT_REACHED();
    872     }
    873    
    874     JITCompiler::Jump doneCaseConvertedToInt;
    875    
    876     if (op == ValueAdd) {
    877         JITCompiler::JumpList failureCases;
    878         m_jit.branchConvertDoubleToInt32(tmp1FPR, resultGPR, failureCases, tmp2FPR);
    879         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
    880        
    881         doneCaseConvertedToInt = m_jit.jump();
    882        
    883         failureCases.link(&m_jit);
    884     }
    885        
    886     boxDouble(tmp1FPR, resultGPR);
    887        
    888     if (!notNumbers.empty()) {
    889         ASSERT(op == ValueAdd);
    890            
    891         JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
    892            
    893         notNumbers.link(&m_jit);
    894            
    895         silentSpillAllRegisters(resultGPR);
    896         setupStubArguments(arg1GPR, arg2GPR);
    897         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    898         appendCallWithExceptionCheck(operationValueAddNotNumber);
    899         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    900         silentFillAllRegisters(resultGPR);
    901 
    902         doneCaseWasNumber.link(&m_jit);
    903     }
    904    
    905     done.link(&m_jit);
    906     if (doneCaseConvertedToInt.isSet())
    907         doneCaseConvertedToInt.link(&m_jit);
    908        
    909     jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
    910 }
    911 
    912 void JITCodeGenerator::nonSpeculativeArithMod(Node& node)
    913 {
    914     JSValueOperand op1(this, node.child1());
    915     JSValueOperand op2(this, node.child2());
    916     GPRTemporary eax(this, X86Registers::eax);
    917     GPRTemporary edx(this, X86Registers::edx);
    918 
    919     FPRTemporary op1Double(this);
    920     FPRTemporary op2Double(this);
    921    
    922     GPRReg op1GPR = op1.gpr();
    923     GPRReg op2GPR = op2.gpr();
    924    
    925     FPRReg op1FPR = op1Double.fpr();
    926     FPRReg op2FPR = op2Double.fpr();
    927        
    928     op1.use();
    929     op2.use();
    930    
    931     GPRReg temp2 = InvalidGPRReg;
    932     GPRReg unboxGPR;
    933     if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
    934         temp2 = allocate();
    935         m_jit.move(op2GPR, temp2);
    936         op2GPR = temp2;
    937         unboxGPR = temp2;
    938     } else if (op1GPR == X86Registers::eax)
    939         unboxGPR = X86Registers::edx;
    940     else
    941         unboxGPR = X86Registers::eax;
    942     ASSERT(unboxGPR != op1.gpr());
    943     ASSERT(unboxGPR != op2.gpr());
    944 
    945     JITCompiler::Jump firstOpNotInt;
    946     JITCompiler::Jump secondOpNotInt;
    947     JITCompiler::JumpList done;
    948     JITCompiler::Jump modByZero;
    949    
    950     if (!isKnownInteger(node.child1()))
    951         firstOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op1GPR, GPRInfo::tagTypeNumberRegister);
    952     if (!isKnownInteger(node.child2()))
    953         secondOpNotInt = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister);
    954    
    955     modByZero = m_jit.branchTest32(MacroAssembler::Zero, op2GPR);
    956    
    957     m_jit.move(op1GPR, eax.gpr());
    958     m_jit.assembler().cdq();
    959     m_jit.assembler().idivl_r(op2GPR);
    960    
    961     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, X86Registers::edx);
    962    
    963     done.append(m_jit.jump());
    964        
    965     JITCompiler::Jump gotDoubleArgs;
    966    
    967     modByZero.link(&m_jit);
    968        
    969     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(std::numeric_limits<double>::quiet_NaN()))), X86Registers::edx);
    970     done.append(m_jit.jump());
    971    
    972     if (!isKnownInteger(node.child1())) {
    973         firstOpNotInt.link(&m_jit);
    974        
    975         JITCompiler::Jump secondOpNotInt2;
    976        
    977         if (!isKnownInteger(node.child2()))
    978             secondOpNotInt2 = m_jit.branchPtr(MacroAssembler::Below, op2GPR, GPRInfo::tagTypeNumberRegister);
    979            
    980         // first op is a double, second op is an int.
    981         m_jit.convertInt32ToDouble(op2GPR, op2FPR);
    982 
    983         if (!isKnownInteger(node.child2())) {
    984             JITCompiler::Jump gotSecondOp = m_jit.jump();
    985            
    986             secondOpNotInt2.link(&m_jit);
    987            
    988             // first op is a double, second op is a double.
    989             m_jit.move(op2GPR, unboxGPR);
    990             unboxDouble(unboxGPR, op2FPR);
    991            
    992             gotSecondOp.link(&m_jit);
    993         }
    994        
    995         m_jit.move(op1GPR, unboxGPR);
    996         unboxDouble(unboxGPR, op1FPR);
    997        
    998         gotDoubleArgs = m_jit.jump();
    999     }
    1000    
    1001     if (!isKnownInteger(node.child2())) {
    1002         secondOpNotInt.link(&m_jit);
    1003        
    1004         // we know that the first op is an int, and the second is a double
    1005         m_jit.convertInt32ToDouble(op1GPR, op1FPR);
    1006         m_jit.move(op2GPR, unboxGPR);
    1007         unboxDouble(unboxGPR, op2FPR);
    1008     }
    1009    
    1010     if (!isKnownInteger(node.child1()))
    1011         gotDoubleArgs.link(&m_jit);
    1012    
    1013     if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
    1014         silentSpillAllRegisters(X86Registers::edx);
    1015         setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(op1FPR, op2FPR);
    1016         m_jit.appendCall(fmod);
    1017         boxDouble(FPRInfo::returnValueFPR, X86Registers::edx);
    1018         silentFillAllRegisters(X86Registers::edx);
    1019     }
    1020        
    1021     done.link(&m_jit);
    1022    
    1023     if (temp2 != InvalidGPRReg)
    1024         unlock(temp2);
    1025    
    1026     jsValueResult(X86Registers::edx, m_compileIndex, UseChildrenCalledExplicitly);
    1027 }
    1028 
    1029 void JITCodeGenerator::nonSpeculativeCheckHasInstance(Node& node)
    1030 {
    1031     JSValueOperand base(this, node.child1());
    1032     GPRTemporary structure(this);
    1033    
    1034     GPRReg baseReg = base.gpr();
    1035     GPRReg structureReg = structure.gpr();
    1036    
    1037     // Check that base is a cell.
    1038     MacroAssembler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseReg, GPRInfo::tagMaskRegister);
    1039    
    1040     // Check that base 'ImplementsHasInstance'.
    1041     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureReg);
    1042     MacroAssembler::Jump implementsHasInstance = m_jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::Address(structureReg, Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsHasInstance));
    1043    
    1044     // At this point we always throw, so no need to preserve registers.
    1045     baseNotCell.link(&m_jit);
    1046     m_jit.move(baseReg, GPRInfo::argumentGPR1);
    1047     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1048     // At some point we could optimize this to plant a direct jump, rather then checking
    1049     // for an exception (operationThrowHasInstanceError always throws). Probably not worth
    1050     // adding the extra interface to do this now, but we may also want this for op_throw.
    1051     appendCallWithExceptionCheck(operationThrowHasInstanceError);
    1052    
    1053     implementsHasInstance.link(&m_jit);
    1054     noResult(m_compileIndex);
    1055 }
    1056 
    1057 void JITCodeGenerator::nonSpeculativeInstanceOf(Node& node)
    1058 {
    1059     JSValueOperand value(this, node.child1());
    1060     JSValueOperand base(this, node.child2());
    1061     JSValueOperand prototype(this, node.child3());
    1062     GPRTemporary scratch(this, base);
    1063 
    1064     GPRReg valueReg = value.gpr();
    1065     GPRReg baseReg = base.gpr();
    1066     GPRReg prototypeReg = prototype.gpr();
    1067     GPRReg scratchReg = scratch.gpr();
    1068        
    1069     value.use();
    1070     base.use();
    1071     prototype.use();
    1072 
    1073     // Check that operands are cells (base is checked by CheckHasInstance, so we can just assert).
    1074     MacroAssembler::Jump valueNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueReg, GPRInfo::tagMaskRegister);
    1075     m_jit.jitAssertIsCell(baseReg);
    1076     MacroAssembler::Jump prototypeNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, prototypeReg, GPRInfo::tagMaskRegister);
    1077 
    1078     // Check that baseVal 'ImplementsDefaultHasInstance'.
    1079     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSCell::structureOffset()), scratchReg);
    1080     MacroAssembler::Jump notDefaultHasInstance = m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, Structure::typeInfoFlagsOffset()), TrustedImm32(ImplementsDefaultHasInstance));
    1081 
    1082     // Check that prototype is an object
    1083     m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
    1084     MacroAssembler::Jump protoNotObject = m_jit.branchIfNotObject(scratchReg);
    1085 
    1086     // Initialize scratchReg with the value being checked.
    1087     m_jit.move(valueReg, scratchReg);
    1088 
    1089     // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
    1090     MacroAssembler::Label loop(&m_jit);
    1091     m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
    1092     m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
    1093     MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
    1094     m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
    1095 
    1096     // No match - result is false.
    1097     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
    1098     MacroAssembler::Jump wasNotInstance = m_jit.jump();
    1099 
    1100     // Link to here if any checks fail that require us to try calling out to an operation to help,
    1101     // e.g. for an API overridden HasInstance.
    1102     valueNotCell.link(&m_jit);
    1103     prototypeNotCell.link(&m_jit);
    1104     notDefaultHasInstance.link(&m_jit);
    1105     protoNotObject.link(&m_jit);
    1106 
    1107     silentSpillAllRegisters(scratchReg);
    1108     setupStubArguments(valueReg, baseReg, prototypeReg);
    1109     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1110     appendCallWithExceptionCheck(operationInstanceOf);
    1111     m_jit.move(GPRInfo::returnValueGPR, scratchReg);
    1112     silentFillAllRegisters(scratchReg);
    1113 
    1114     MacroAssembler::Jump wasNotDefaultHasInstance = m_jit.jump();
    1115 
    1116     isInstance.link(&m_jit);
    1117     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
    1118 
    1119     wasNotInstance.link(&m_jit);
    1120     wasNotDefaultHasInstance.link(&m_jit);
    1121     jsValueResult(scratchReg, m_compileIndex, UseChildrenCalledExplicitly);
    1122 }
    1123 
    1124 JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
    1125 {
    1126     JITCompiler::DataLabelPtr structureToCompare;
    1127     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
    1128    
    1129     m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
    1130     JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
    1131    
    1132     JITCompiler::Jump done = m_jit.jump();
    1133 
    1134     structureCheck.link(&m_jit);
    1135    
    1136     if (slowPathTarget.isSet())
    1137         slowPathTarget.link(&m_jit);
    1138    
    1139     JITCompiler::Label slowCase = m_jit.label();
    1140 
    1141     silentSpillAllRegisters(resultGPR);
    1142     m_jit.move(baseGPR, GPRInfo::argumentGPR1);
    1143     m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR2);
    1144     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1145     JITCompiler::Call functionCall;
    1146     switch (nodeType) {
    1147     case GetById:
    1148         functionCall = appendCallWithExceptionCheck(operationGetByIdOptimize);
    1149         break;
    1150        
    1151     case GetMethod:
    1152         functionCall = appendCallWithExceptionCheck(operationGetMethodOptimize);
    1153         break;
    1154        
    1155     default:
    1156         ASSERT_NOT_REACHED();
    1157         return JITCompiler::Call();
    1158     }
    1159     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1160     silentFillAllRegisters(resultGPR);
    1161    
    1162     done.link(&m_jit);
    1163    
    1164     JITCompiler::Label doneLabel = m_jit.label();
    1165 
    1166     int16_t checkImmToCall = safeCast<int16_t>(m_jit.differenceBetween(structureToCompare, functionCall));
    1167     int16_t callToCheck = safeCast<int16_t>(m_jit.differenceBetween(functionCall, structureCheck));
    1168     int16_t callToLoad = safeCast<int16_t>(m_jit.differenceBetween(functionCall, loadWithPatch));
    1169     int16_t callToSlowCase = safeCast<int16_t>(m_jit.differenceBetween(functionCall, slowCase));
    1170     int16_t callToDone = safeCast<int16_t>(m_jit.differenceBetween(functionCall, doneLabel));
    1171    
    1172     m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToLoad, callToSlowCase, callToDone, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR), safeCast<int8_t>(scratchGPR));
    1173    
    1174     if (scratchGPR != resultGPR && scratchGPR != InvalidGPRReg)
    1175         unlock(scratchGPR);
    1176    
    1177     return functionCall;
    1178 }
    1179 
    1180194void JITCodeGenerator::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
    1181195{
     
    1232246    if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    1233247        hadCellCheck = true;
    1234         rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     248        rhsNotCell = m_jit.branchIfNotCell(valueGPR);
    1235249    }
    1236250
     
    1273287    if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    1274288        hadCellCheck = true;
    1275         rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
     289        rhsNotCell = m_jit.branchIfNotCell(valueGPR);
    1276290    }
    1277291   
     
    1292306}
    1293307
    1294 void JITCodeGenerator::cachedPutById(GPRReg baseGPR, GPRReg valueGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
    1295 {
    1296    
    1297     JITCompiler::DataLabelPtr structureToCompare;
    1298     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
    1299 
    1300     writeBarrier(baseGPR, valueGPR, valueIndex, WriteBarrierForPropertyAccess, scratchGPR);
    1301 
    1302     m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
    1303     JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
    1304 
    1305     JITCompiler::Jump done = m_jit.jump();
    1306 
    1307     structureCheck.link(&m_jit);
    1308 
    1309     if (slowPathTarget.isSet())
    1310         slowPathTarget.link(&m_jit);
    1311 
    1312     JITCompiler::Label slowCase = m_jit.label();
    1313 
    1314     silentSpillAllRegisters(InvalidGPRReg);
    1315     setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(valueGPR, baseGPR);
    1316     m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR3);
    1317     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1318     V_DFGOperation_EJJI optimizedCall;
    1319     if (m_jit.codeBlock()->isStrictMode()) {
    1320         if (putKind == Direct)
    1321             optimizedCall = operationPutByIdDirectStrictOptimize;
    1322         else
    1323             optimizedCall = operationPutByIdStrictOptimize;
    1324     } else {
    1325         if (putKind == Direct)
    1326             optimizedCall = operationPutByIdDirectNonStrictOptimize;
    1327         else
    1328             optimizedCall = operationPutByIdNonStrictOptimize;
    1329     }
    1330     JITCompiler::Call functionCall = appendCallWithExceptionCheck(optimizedCall);
    1331     silentFillAllRegisters(InvalidGPRReg);
    1332 
    1333     done.link(&m_jit);
    1334     JITCompiler::Label doneLabel = m_jit.label();
    1335 
    1336     int16_t checkImmToCall = safeCast<int16_t>(m_jit.differenceBetween(structureToCompare, functionCall));
    1337     int16_t callToCheck = safeCast<int16_t>(m_jit.differenceBetween(functionCall, structureCheck));
    1338     int16_t callToStore = safeCast<int16_t>(m_jit.differenceBetween(functionCall, storeWithPatch));
    1339     int16_t callToSlowCase = safeCast<int16_t>(m_jit.differenceBetween(functionCall, slowCase));
    1340     int16_t callToDone = safeCast<int16_t>(m_jit.differenceBetween(functionCall, doneLabel));
    1341 
    1342     m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToStore, callToSlowCase, callToDone, safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR));
    1343 }
    1344 
    1345 void JITCodeGenerator::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
    1346 {
    1347     JITCompiler::Call slowCall;
    1348     JITCompiler::DataLabelPtr structToCompare, protoObj, protoStructToCompare, putFunction;
    1349    
    1350     JITCompiler::Jump wrongStructure = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
    1351     protoObj = m_jit.moveWithPatch(JITCompiler::TrustedImmPtr(0), resultGPR);
    1352     JITCompiler::Jump wrongProtoStructure = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(resultGPR, JSCell::structureOffset()), protoStructToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
    1353    
    1354     putFunction = m_jit.moveWithPatch(JITCompiler::TrustedImmPtr(0), resultGPR);
    1355    
    1356     JITCompiler::Jump done = m_jit.jump();
    1357    
    1358     wrongStructure.link(&m_jit);
    1359     wrongProtoStructure.link(&m_jit);
    1360    
    1361     slowCall = cachedGetById(baseGPR, resultGPR, scratchGPR, identifierNumber, slowPathTarget, GetMethod);
    1362    
    1363     done.link(&m_jit);
    1364    
    1365     m_jit.addMethodGet(slowCall, structToCompare, protoObj, protoStructToCompare, putFunction);
    1366 }
    1367 
    1368 void JITCodeGenerator::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert)
    1369 {
    1370     JSValueOperand arg(this, operand);
    1371     GPRReg argGPR = arg.gpr();
    1372    
    1373     GPRTemporary result(this, arg);
    1374     GPRReg resultGPR = result.gpr();
    1375    
    1376     JITCompiler::Jump notCell;
    1377    
    1378     if (!isKnownCell(operand))
    1379         notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
    1380    
    1381     m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
    1382     m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultGPR);
    1383    
    1384     if (!isKnownCell(operand)) {
    1385         JITCompiler::Jump done = m_jit.jump();
    1386        
    1387         notCell.link(&m_jit);
    1388        
    1389         m_jit.move(argGPR, resultGPR);
    1390         m_jit.andPtr(JITCompiler::TrustedImm32(~TagBitUndefined), resultGPR);
    1391         m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(ValueNull), resultGPR);
    1392        
    1393         done.link(&m_jit);
    1394     }
    1395    
    1396     m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
    1397     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
    1398 }
    1399 
    1400 void JITCodeGenerator::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert)
    1401 {
    1402     Node& branchNode = m_jit.graph()[branchNodeIndex];
    1403     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
    1404     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
    1405    
    1406     if (taken == (m_block + 1)) {
    1407         invert = !invert;
    1408         BlockIndex tmp = taken;
    1409         taken = notTaken;
    1410         notTaken = tmp;
    1411     }
    1412 
    1413     JSValueOperand arg(this, operand);
    1414     GPRReg argGPR = arg.gpr();
    1415    
    1416     GPRTemporary result(this, arg);
    1417     GPRReg resultGPR = result.gpr();
    1418    
    1419     JITCompiler::Jump notCell;
    1420    
    1421     if (!isKnownCell(operand))
    1422         notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
    1423    
    1424     m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
    1425     addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined)), taken);
    1426    
    1427     if (!isKnownCell(operand)) {
    1428         addBranch(m_jit.jump(), notTaken);
    1429        
    1430         notCell.link(&m_jit);
    1431        
    1432         m_jit.move(argGPR, resultGPR);
    1433         m_jit.andPtr(JITCompiler::TrustedImm32(~TagBitUndefined), resultGPR);
    1434         addBranch(m_jit.branchPtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))), taken);
    1435     }
    1436    
    1437     if (notTaken != (m_block + 1))
    1438         addBranch(m_jit.jump(), notTaken);
    1439 }
    1440 
    1441 bool JITCodeGenerator::nonSpeculativeCompareNull(Node& node, NodeIndex operand, bool invert)
    1442 {
    1443     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    1444     if (branchNodeIndex != NoNode) {
    1445         ASSERT(node.adjustedRefCount() == 1);
    1446        
    1447         nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
    1448    
    1449         use(node.child1());
    1450         use(node.child2());
    1451         m_compileIndex = branchNodeIndex;
    1452        
    1453         return true;
    1454     }
    1455    
    1456     nonSpeculativeNonPeepholeCompareNull(operand, invert);
    1457    
    1458     return false;
    1459 }
    1460 
    1461 void JITCodeGenerator::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
    1462 {
    1463     Node& branchNode = m_jit.graph()[branchNodeIndex];
    1464     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
    1465     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
    1466 
    1467     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
    1468 
    1469     // The branch instruction will branch to the taken block.
    1470     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
    1471     if (taken == (m_block + 1)) {
    1472         cond = JITCompiler::invert(cond);
    1473         callResultCondition = JITCompiler::Zero;
    1474         BlockIndex tmp = taken;
    1475         taken = notTaken;
    1476         notTaken = tmp;
    1477     }
    1478 
    1479     JSValueOperand arg1(this, node.child1());
    1480     JSValueOperand arg2(this, node.child2());
    1481     GPRReg arg1GPR = arg1.gpr();
    1482     GPRReg arg2GPR = arg2.gpr();
    1483    
    1484     JITCompiler::JumpList slowPath;
    1485    
    1486     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
    1487         GPRResult result(this);
    1488         GPRReg resultGPR = result.gpr();
    1489    
    1490         arg1.use();
    1491         arg2.use();
    1492    
    1493         flushRegisters();
    1494 
    1495         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
    1496         addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
    1497     } else {
    1498         GPRTemporary result(this, arg2);
    1499         GPRReg resultGPR = result.gpr();
    1500    
    1501         arg1.use();
    1502         arg2.use();
    1503    
    1504         if (!isKnownInteger(node.child1()))
    1505             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
    1506         if (!isKnownInteger(node.child2()))
    1507             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
    1508    
    1509         addBranch(m_jit.branch32(cond, arg1GPR, arg2GPR), taken);
    1510    
    1511         if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
    1512             addBranch(m_jit.jump(), notTaken);
    1513    
    1514             slowPath.link(&m_jit);
    1515    
    1516             silentSpillAllRegisters(resultGPR);
    1517             setupStubArguments(arg1GPR, arg2GPR);
    1518             m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1519             appendCallWithExceptionCheck(helperFunction);
    1520             m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1521             silentFillAllRegisters(resultGPR);
    1522        
    1523             addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
    1524         }
    1525     }
    1526 
    1527     if (notTaken != (m_block + 1))
    1528         addBranch(m_jit.jump(), notTaken);
    1529 }
    1530 
    1531 void JITCodeGenerator::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
    1532 {
    1533     JSValueOperand arg1(this, node.child1());
    1534     JSValueOperand arg2(this, node.child2());
    1535     GPRReg arg1GPR = arg1.gpr();
    1536     GPRReg arg2GPR = arg2.gpr();
    1537    
    1538     JITCompiler::JumpList slowPath;
    1539    
    1540     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
    1541         GPRResult result(this);
    1542         GPRReg resultGPR = result.gpr();
    1543    
    1544         arg1.use();
    1545         arg2.use();
    1546    
    1547         flushRegisters();
    1548        
    1549         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
    1550        
    1551         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
    1552         jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1553     } else {
    1554         GPRTemporary result(this, arg2);
    1555         GPRReg resultGPR = result.gpr();
    1556 
    1557         arg1.use();
    1558         arg2.use();
    1559    
    1560         if (!isKnownInteger(node.child1()))
    1561             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
    1562         if (!isKnownInteger(node.child2()))
    1563             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
    1564    
    1565         m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
    1566    
    1567         if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
    1568             JITCompiler::Jump haveResult = m_jit.jump();
    1569    
    1570             slowPath.link(&m_jit);
    1571        
    1572             silentSpillAllRegisters(resultGPR);
    1573             setupStubArguments(arg1GPR, arg2GPR);
    1574             m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1575             appendCallWithExceptionCheck(helperFunction);
    1576             m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1577             silentFillAllRegisters(resultGPR);
    1578        
    1579             m_jit.andPtr(TrustedImm32(1), resultGPR);
    1580        
    1581             haveResult.link(&m_jit);
    1582         }
    1583        
    1584         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
    1585        
    1586         jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1587     }
    1588 }
    1589 
    1590308bool JITCodeGenerator::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
    1591309{
     
    1606324}
    1607325
    1608 void JITCodeGenerator::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
    1609 {
    1610     Node& branchNode = m_jit.graph()[branchNodeIndex];
    1611     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
    1612     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
    1613 
    1614     // The branch instruction will branch to the taken block.
    1615     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
    1616     if (taken == (m_block + 1)) {
    1617         invert = !invert;
    1618         BlockIndex tmp = taken;
    1619         taken = notTaken;
    1620         notTaken = tmp;
    1621     }
    1622    
    1623     JSValueOperand arg1(this, node.child1());
    1624     JSValueOperand arg2(this, node.child2());
    1625     GPRReg arg1GPR = arg1.gpr();
    1626     GPRReg arg2GPR = arg2.gpr();
    1627    
    1628     GPRTemporary result(this);
    1629     GPRReg resultGPR = result.gpr();
    1630    
    1631     arg1.use();
    1632     arg2.use();
    1633    
    1634     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
    1635         // see if we get lucky: if the arguments are cells and they reference the same
    1636         // cell, then they must be strictly equal.
    1637         addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken);
    1638        
    1639         silentSpillAllRegisters(resultGPR);
    1640         setupStubArguments(arg1GPR, arg2GPR);
    1641         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1642         appendCallWithExceptionCheck(operationCompareStrictEqCell);
    1643         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1644         silentFillAllRegisters(resultGPR);
    1645        
    1646         addBranch(m_jit.branchTest8(invert ? JITCompiler::NonZero : JITCompiler::Zero, resultGPR), taken);
    1647     } else {
    1648         m_jit.orPtr(arg1GPR, arg2GPR, resultGPR);
    1649        
    1650         JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
    1651        
    1652         JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
    1653        
    1654         addBranch(m_jit.branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR), taken);
    1655         addBranch(m_jit.jump(), notTaken);
    1656        
    1657         twoCellsCase.link(&m_jit);
    1658         addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken);
    1659        
    1660         numberCase.link(&m_jit);
    1661        
    1662         silentSpillAllRegisters(resultGPR);
    1663         setupStubArguments(arg1GPR, arg2GPR);
    1664         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1665         appendCallWithExceptionCheck(operationCompareStrictEq);
    1666         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1667         silentFillAllRegisters(resultGPR);
    1668        
    1669         addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, resultGPR), taken);
    1670     }
    1671    
    1672     if (notTaken != (m_block + 1))
    1673         addBranch(m_jit.jump(), notTaken);
    1674 }
    1675 
    1676 void JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
    1677 {
    1678     JSValueOperand arg1(this, node.child1());
    1679     JSValueOperand arg2(this, node.child2());
    1680     GPRReg arg1GPR = arg1.gpr();
    1681     GPRReg arg2GPR = arg2.gpr();
    1682    
    1683     GPRTemporary result(this);
    1684     GPRReg resultGPR = result.gpr();
    1685    
    1686     arg1.use();
    1687     arg2.use();
    1688    
    1689     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
    1690         // see if we get lucky: if the arguments are cells and they reference the same
    1691         // cell, then they must be strictly equal.
    1692         JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR);
    1693        
    1694         m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR);
    1695        
    1696         JITCompiler::Jump done = m_jit.jump();
    1697 
    1698         notEqualCase.link(&m_jit);
    1699        
    1700         silentSpillAllRegisters(resultGPR);
    1701         setupStubArguments(arg1GPR, arg2GPR);
    1702         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1703         appendCallWithExceptionCheck(operationCompareStrictEqCell);
    1704         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1705         silentFillAllRegisters(resultGPR);
    1706        
    1707         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR);
    1708         m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR);
    1709        
    1710         done.link(&m_jit);
    1711     } else {
    1712         m_jit.orPtr(arg1GPR, arg2GPR, resultGPR);
    1713        
    1714         JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
    1715        
    1716         JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
    1717        
    1718         m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
    1719        
    1720         JITCompiler::Jump done1 = m_jit.jump();
    1721        
    1722         twoCellsCase.link(&m_jit);
    1723         JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR);
    1724        
    1725         m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR);
    1726        
    1727         JITCompiler::Jump done2 = m_jit.jump();
    1728        
    1729         numberCase.link(&m_jit);
    1730         notEqualCase.link(&m_jit);
    1731        
    1732         silentSpillAllRegisters(resultGPR);
    1733         setupStubArguments(arg1GPR, arg2GPR);
    1734         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1735         appendCallWithExceptionCheck(operationCompareStrictEq);
    1736         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1737         silentFillAllRegisters(resultGPR);
    1738        
    1739         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR);
    1740 
    1741         done1.link(&m_jit);
    1742 
    1743         m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR);
    1744        
    1745         done2.link(&m_jit);
    1746     }
    1747    
    1748     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1749 }
    1750 
    1751326bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert)
    1752327{
     
    1768343   
    1769344    return false;
    1770 }
    1771 
    1772 void JITCodeGenerator::emitBranch(Node& node)
    1773 {
    1774     JSValueOperand value(this, node.child1());
    1775     GPRReg valueGPR = value.gpr();
    1776    
    1777     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
    1778     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
    1779    
    1780     if (isKnownBoolean(node.child1())) {
    1781         MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
    1782        
    1783         if (taken == (m_block + 1)) {
    1784             condition = MacroAssembler::Zero;
    1785             BlockIndex tmp = taken;
    1786             taken = notTaken;
    1787             notTaken = tmp;
    1788         }
    1789        
    1790         addBranch(m_jit.branchTest32(condition, valueGPR, TrustedImm32(true)), taken);
    1791         if (notTaken != (m_block + 1))
    1792             addBranch(m_jit.jump(), notTaken);
    1793        
    1794         noResult(m_compileIndex);
    1795     } else {
    1796         GPRTemporary result(this);
    1797         GPRReg resultGPR = result.gpr();
    1798        
    1799         bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
    1800    
    1801         if (predictBoolean) {
    1802             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
    1803             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
    1804         }
    1805        
    1806         if (m_isSpeculative && predictBoolean) {
    1807             speculationCheck(m_jit.jump());
    1808             value.use();
    1809         } else {
    1810             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
    1811             addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken);
    1812    
    1813             if (!predictBoolean) {
    1814                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
    1815                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
    1816             }
    1817    
    1818             value.use();
    1819    
    1820             silentSpillAllRegisters(resultGPR);
    1821             m_jit.move(valueGPR, GPRInfo::argumentGPR1);
    1822             m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1823             appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1824             m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1825             silentFillAllRegisters(resultGPR);
    1826    
    1827             addBranch(m_jit.branchTest8(MacroAssembler::NonZero, resultGPR), taken);
    1828             if (notTaken != (m_block + 1))
    1829                 addBranch(m_jit.jump(), notTaken);
    1830         }
    1831        
    1832         noResult(m_compileIndex, UseChildrenCalledExplicitly);
    1833     }
    1834 }
    1835 
    1836 void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)
    1837 {
    1838     JSValueOperand arg1(this, node.child1());
    1839     GPRTemporary result(this);
    1840    
    1841     GPRReg arg1GPR = arg1.gpr();
    1842     GPRReg resultGPR = result.gpr();
    1843    
    1844     arg1.use();
    1845    
    1846     m_jit.move(arg1GPR, resultGPR);
    1847     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
    1848     JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
    1849    
    1850     silentSpillAllRegisters(resultGPR);
    1851     m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
    1852     m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1853     appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
    1854     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1855     silentFillAllRegisters(resultGPR);
    1856    
    1857     fastCase.link(&m_jit);
    1858    
    1859     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
    1860     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
    1861 }
    1862 
    1863 void JITCodeGenerator::emitCall(Node& node)
    1864 {
    1865     P_DFGOperation_E slowCallFunction;
    1866     bool isCall;
    1867    
    1868     if (node.op == Call) {
    1869         slowCallFunction = operationLinkCall;
    1870         isCall = true;
    1871     } else {
    1872         ASSERT(node.op == Construct);
    1873         slowCallFunction = operationLinkConstruct;
    1874         isCall = false;
    1875     }
    1876    
    1877     NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
    1878     JSValueOperand callee(this, calleeNodeIndex);
    1879     GPRReg calleeGPR = callee.gpr();
    1880     use(calleeNodeIndex);
    1881    
    1882     // the call instruction's first child is either the function (normal call) or the
    1883     // receiver (method call). subsequent children are the arguments.
    1884     int numArgs = node.numChildren() - 1;
    1885    
    1886     // For constructors, the this argument is not passed but we have to make space
    1887     // for it.
    1888     int numPassedArgs = numArgs + (isCall ? 0 : 1);
    1889    
    1890     // amount of stuff (in units of sizeof(Register)) that we need to place at the
    1891     // top of the JS stack.
    1892     int callDataSize = 0;
    1893 
    1894     // first there are the arguments
    1895     callDataSize += numPassedArgs;
    1896    
    1897     // and then there is the call frame header
    1898     callDataSize += RegisterFile::CallFrameHeaderSize;
    1899    
    1900     m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numPassedArgs))), addressOfCallData(RegisterFile::ArgumentCount));
    1901     m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
    1902    
    1903     for (int argIdx = 0; argIdx < numArgs; argIdx++) {
    1904         NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
    1905         JSValueOperand arg(this, argNodeIndex);
    1906         GPRReg argGPR = arg.gpr();
    1907         use(argNodeIndex);
    1908        
    1909         m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx + (isCall ? 0 : 1)));
    1910     }
    1911    
    1912     m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
    1913    
    1914     flushRegisters();
    1915    
    1916     GPRResult result(this);
    1917     GPRReg resultGPR = result.gpr();
    1918 
    1919     JITCompiler::DataLabelPtr targetToCheck;
    1920     JITCompiler::Jump slowPath;
    1921    
    1922     slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
    1923     m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
    1924     m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
    1925 
    1926     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
    1927    
    1928     JITCompiler::Call fastCall = m_jit.nearCall();
    1929     m_jit.notifyCall(fastCall, m_jit.graph()[m_compileIndex].codeOrigin);
    1930    
    1931     JITCompiler::Jump done = m_jit.jump();
    1932    
    1933     slowPath.link(&m_jit);
    1934    
    1935     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1936     JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, m_jit.graph()[m_compileIndex].codeOrigin);
    1937     m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
    1938     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
    1939     m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), m_jit.graph()[m_compileIndex].codeOrigin);
    1940    
    1941     done.link(&m_jit);
    1942    
    1943     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    1944    
    1945     jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
    1946    
    1947     m_jit.addJSCall(fastCall, slowCall, targetToCheck, isCall, m_jit.graph()[m_compileIndex].codeOrigin);
    1948345}
    1949346
     
    1997394        if (info.registerFormat() == DataFormatDouble)
    1998395            fprintf(stderr, ":fpr%d\n", info.fpr());
    1999         else if (info.registerFormat() != DataFormatNone) {
     396        else if (info.registerFormat() != DataFormatNone
     397#if USE(JSVALUE32_64)
     398            && !(info.registerFormat() & DataFormatJS)
     399#endif
     400            ) {
    2000401            ASSERT(info.gpr() != InvalidGPRReg);
    2001402            fprintf(stderr, ":%s\n", GPRInfo::debugName(info.gpr()));
     
    2035436        case DataFormatNone:
    2036437            break;
    2037         case DataFormatInteger:
    2038         case DataFormatCell:
    2039438        case DataFormatJS:
    2040439        case DataFormatJSInteger:
    2041440        case DataFormatJSDouble:
    2042         case DataFormatJSCell: {
     441        case DataFormatJSCell:
     442#if USE(JSVALUE32_64)
     443            break;
     444#endif
     445        case DataFormatInteger:
     446        case DataFormatCell: {
    2043447            GPRReg gpr = info.gpr();
    2044448            ASSERT(gpr != InvalidGPRReg);
     
    2067471
    2068472        GenerationInfo& info = m_generationInfo[virtualRegister];
     473#if USE(JSVALUE64)
    2069474        if (iter.regID() != info.gpr()) {
    2070475            fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2071476            failed = true;
    2072477        }
     478#else
     479        if (!(info.registerFormat() & DataFormatJS)) {
     480            if (iter.regID() != info.gpr()) {
     481                fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
     482                failed = true;
     483            }
     484        } else {
     485            if (iter.regID() != info.tagGPR() && iter.regID() != info.payloadGPR()) {
     486                fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
     487                failed = true;
     488            }
     489        }
     490#endif
    2073491    }
    2074492
     
    2102520    , m_gpr(InvalidGPRReg)
    2103521{
     522#if CPU(X86)
     523    // we currenty lazily allocate the reg, as the number of regs on X86 is limited.
     524#else
    2104525    m_gpr = m_jit->allocate();
     526#endif
    2105527}
    2106528
     
    2186608}
    2187609
     610#if USE(JSVALUE64)
    2188611GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
    2189612    : m_jit(jit)
     
    2195618        m_gpr = m_jit->allocate();
    2196619}
     620#else
     621GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1, bool tag)
     622    : m_jit(jit)
     623    , m_gpr(InvalidGPRReg)
     624{
     625    if (!op1.isDouble() && m_jit->canReuse(op1.index()))
     626        m_gpr = m_jit->reuse(tag ? op1.tagGPR() : op1.payloadGPR());
     627    else
     628        m_gpr = m_jit->allocate();
     629}
     630#endif
    2197631
    2198632GPRTemporary::GPRTemporary(JITCodeGenerator* jit, StorageOperand& op1)
     
    2269703}
    2270704
     705#if USE(JSVALUE32_64)
     706FPRTemporary::FPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
     707    : m_jit(jit)
     708    , m_fpr(InvalidFPRReg)
     709{
     710    if (op1.isDouble() && m_jit->canReuse(op1.index()))
     711        m_fpr = m_jit->reuse(op1.fpr());
     712    else
     713        m_fpr = m_jit->fprAllocate();
     714}
     715#endif
     716
    2271717} } // namespace JSC::DFG
    2272718
    2273719#endif
    2274 #endif
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp

    r96372 r96377  
    2828
    2929#if ENABLE(DFG_JIT)
    30 #if USE(JSVALUE32_64)
    3130
    3231#include "DFGJITCompilerInlineMethods.h"
     
    3635namespace JSC { namespace DFG {
    3736
    38 const double JITCodeGenerator::twoToThe32 = (double)0x100000000ull;
    39 
    40 void JITCodeGenerator::clearGenerationInfo()
    41 {
    42     for (unsigned i = 0; i < m_generationInfo.size(); ++i)
    43         m_generationInfo[i] = GenerationInfo();
    44     m_gprs = RegisterBank<GPRInfo>();
    45     m_fprs = RegisterBank<FPRInfo>();
    46 }
     37#if USE(JSVALUE32_64)
    4738
    4839GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
     
    315306}
    316307
    317 GPRReg JITCodeGenerator::fillStorage(NodeIndex nodeIndex)
    318 {
    319     Node& node = m_jit.graph()[nodeIndex];
    320     VirtualRegister virtualRegister = node.virtualRegister();
    321     GenerationInfo& info = m_generationInfo[virtualRegister];
    322    
    323     switch (info.registerFormat()) {
    324     case DataFormatNone: {
    325         GPRReg gpr = allocate();
    326         ASSERT(info.spillFormat() == DataFormatStorage);
    327         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    328         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    329         info.fillStorage(gpr);
    330         return gpr;
    331     }
    332        
    333     case DataFormatStorage: {
    334         GPRReg gpr = info.gpr();
    335         m_gprs.lock(gpr);
    336         return gpr;
    337     }
    338        
    339     default:
    340         ASSERT_NOT_REACHED();
    341     }
    342    
    343     return InvalidGPRReg;
    344 }
    345 
    346 void JITCodeGenerator::useChildren(Node& node)
    347 {
    348     if (node.op & NodeHasVarArgs) {
    349         for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
    350             use(m_jit.graph().m_varArgChildren[childIdx]);
    351     } else {
    352         NodeIndex child1 = node.child1();
    353         if (child1 == NoNode) {
    354             ASSERT(node.child2() == NoNode && node.child3() == NoNode);
    355             return;
    356         }
    357         use(child1);
    358        
    359         NodeIndex child2 = node.child2();
    360         if (child2 == NoNode) {
    361             ASSERT(node.child3() == NoNode);
    362             return;
    363         }
    364         use(child2);
    365        
    366         NodeIndex child3 = node.child3();
    367         if (child3 == NoNode)
    368             return;
    369         use(child3);
    370     }
    371 }
    372 
    373 bool JITCodeGenerator::isStrictInt32(NodeIndex nodeIndex)
    374 {
    375     if (isInt32Constant(nodeIndex))
    376         return true;
    377    
    378     Node& node = m_jit.graph()[nodeIndex];
    379     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    380    
    381     return info.registerFormat() == DataFormatInteger;
    382 }
    383 
    384 bool JITCodeGenerator::isKnownInteger(NodeIndex nodeIndex)
    385 {
    386     if (isInt32Constant(nodeIndex))
    387         return true;
    388 
    389     Node& node = m_jit.graph()[nodeIndex];
    390    
    391     if (node.hasInt32Result())
    392         return true;
    393    
    394     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    395 
    396     return info.isJSInteger();
    397 }
    398 
    399 bool JITCodeGenerator::isKnownNumeric(NodeIndex nodeIndex)
    400 {
    401     if (isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex))
    402         return true;
    403 
    404     Node& node = m_jit.graph()[nodeIndex];
    405    
    406     if (node.hasNumberResult())
    407         return true;
    408    
    409     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    410 
    411     return info.isJSInteger() || info.isJSDouble();
    412 }
    413 
    414 bool JITCodeGenerator::isKnownCell(NodeIndex nodeIndex)
    415 {
    416     return m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()].isJSCell();
    417 }
    418 
    419 bool JITCodeGenerator::isKnownNotCell(NodeIndex nodeIndex)
    420 {
    421     Node& node = m_jit.graph()[nodeIndex];
    422     VirtualRegister virtualRegister = node.virtualRegister();
    423     GenerationInfo& info = m_generationInfo[virtualRegister];
    424     if (node.hasConstant() && !valueOfJSConstant(nodeIndex).isCell())
    425         return true;
    426     return !(info.isJSCell() || info.isUnknownJS());
    427 }
    428 
    429 bool JITCodeGenerator::isKnownNotInteger(NodeIndex nodeIndex)
    430 {
    431     Node& node = m_jit.graph()[nodeIndex];
    432     VirtualRegister virtualRegister = node.virtualRegister();
    433     GenerationInfo& info = m_generationInfo[virtualRegister];
    434 
    435     return info.isJSDouble() || info.isJSCell() || info.isJSBoolean()
    436         || (node.hasConstant() && !valueOfJSConstant(nodeIndex).isInt32());
    437 }
    438 
    439 bool JITCodeGenerator::isKnownNotNumber(NodeIndex nodeIndex)
    440 {
    441     Node& node = m_jit.graph()[nodeIndex];
    442     VirtualRegister virtualRegister = node.virtualRegister();
    443     GenerationInfo& info = m_generationInfo[virtualRegister];
    444    
    445     return (!info.isJSDouble() && !info.isJSInteger() && !info.isUnknownJS())
    446         || (node.hasConstant() && !isNumberConstant(nodeIndex));
    447 }
    448 
    449 bool JITCodeGenerator::isKnownBoolean(NodeIndex nodeIndex)
    450 {
    451     Node& node = m_jit.graph()[nodeIndex];
    452     if (node.hasBooleanResult())
    453         return true;
    454    
    455     if (isBooleanConstant(nodeIndex))
    456         return true;
    457    
    458     VirtualRegister virtualRegister = node.virtualRegister();
    459     GenerationInfo& info = m_generationInfo[virtualRegister];
    460    
    461     return info.isJSBoolean();
    462 }
    463 
    464308void JITCodeGenerator::nonSpeculativeValueToNumber(Node& node)
    465309{
     
    12261070   
    12271071    return functionCall;
    1228 }
    1229 
    1230 void JITCodeGenerator::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
    1231 {
    1232     UNUSED_PARAM(jit);
    1233     UNUSED_PARAM(owner);
    1234     UNUSED_PARAM(scratch1);
    1235     UNUSED_PARAM(scratch2);
    1236     UNUSED_PARAM(useKind);
    1237     ASSERT(owner != scratch1);
    1238     ASSERT(owner != scratch2);
    1239     ASSERT(scratch1 != scratch2);
    1240 
    1241 #if ENABLE(WRITE_BARRIER_PROFILING)
    1242     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1243 #endif
    1244     markCellCard(jit, owner, scratch1, scratch2);
    1245 }
    1246 
    1247 void JITCodeGenerator::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
    1248 {
    1249     UNUSED_PARAM(jit);
    1250     UNUSED_PARAM(owner);
    1251     UNUSED_PARAM(scratch1);
    1252     UNUSED_PARAM(scratch2);
    1253    
    1254 #if ENABLE(GGC)
    1255     jit.move(owner, scratch1);
    1256     jit.andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch1);
    1257     jit.move(owner, scratch2);
    1258     jit.rshift32(TrustedImm32(MarkedBlock::cardShift), scratch2);
    1259     jit.andPtr(TrustedImm32(MarkedBlock::cardMask), scratch2);
    1260     jit.store8(TrustedImm32(1), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfCards()));
    1261 #endif
    1262 }
    1263 
    1264 void JITCodeGenerator::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
    1265 {
    1266     UNUSED_PARAM(ownerGPR);
    1267     UNUSED_PARAM(valueGPR);
    1268     UNUSED_PARAM(scratch1);
    1269     UNUSED_PARAM(scratch2);
    1270     UNUSED_PARAM(useKind);
    1271 
    1272     if (isKnownNotCell(valueIndex))
    1273         return;
    1274 
    1275 #if ENABLE(WRITE_BARRIER_PROFILING)
    1276     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1277 #endif
    1278 
    1279 #if ENABLE(GGC)
    1280     JITCompiler::Jump rhsNotCell;
    1281     bool hadCellCheck = false;
    1282     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.graph().getPrediction(m_jit.graph()[valueIndex]))) {
    1283         hadCellCheck = true;
    1284         rhsNotCell = m_jit.branch32(MacroAssembler::NotEqual, valueGPR, TrustedImm32(JSValue::CellTag));
    1285     }
    1286 
    1287     GPRTemporary temp1;
    1288     GPRTemporary temp2;
    1289     if (scratch1 == InvalidGPRReg) {
    1290         GPRTemporary scratchGPR(this);
    1291         temp1.adopt(scratchGPR);
    1292         scratch1 = temp1.gpr();
    1293     }
    1294     if (scratch2 == InvalidGPRReg) {
    1295         GPRTemporary scratchGPR(this);
    1296         temp2.adopt(scratchGPR);
    1297         scratch2 = temp2.gpr();
    1298     }
    1299 
    1300     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
    1301     if (hadCellCheck)
    1302         rhsNotCell.link(&m_jit);
    1303 #endif
    1304 }
    1305 
    1306 void JITCodeGenerator::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch)
    1307 {
    1308     UNUSED_PARAM(owner);
    1309     UNUSED_PARAM(valueGPR);
    1310     UNUSED_PARAM(scratch);
    1311     UNUSED_PARAM(useKind);
    1312 
    1313     if (isKnownNotCell(valueIndex))
    1314         return;
    1315 
    1316 #if ENABLE(WRITE_BARRIER_PROFILING)
    1317     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1318 #endif
    1319 
    1320 #if ENABLE(GGC)
    1321     JITCompiler::Jump rhsNotCell;
    1322     bool hadCellCheck = false;
    1323     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.graph().getPrediction(m_jit.graph()[valueIndex]))) {
    1324         hadCellCheck = true;
    1325         rhsNotCell = m_jit.branch32(MacroAssembler::NotEqual, valueGPR, TrustedImm32(JSValue::CellTag));
    1326     }
    1327    
    1328     GPRTemporary temp;
    1329     if (scratch == InvalidGPRReg) {
    1330         GPRTemporary scratchGPR(this);
    1331         temp.adopt(scratchGPR);
    1332         scratch = temp.gpr();
    1333     }
    1334 
    1335     uint8_t* cardAddress = Heap::addressOfCardFor(owner);
    1336     m_jit.move(JITCompiler::TrustedImmPtr(cardAddress), scratch);
    1337     m_jit.store8(JITCompiler::TrustedImm32(1), JITCompiler::Address(scratch));
    1338 
    1339     if (hadCellCheck)
    1340         rhsNotCell.link(&m_jit);
    1341 #endif
    13421072}
    13431073
     
    16621392}
    16631393
    1664 bool JITCodeGenerator::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
    1665 {
    1666     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    1667     if (branchNodeIndex != NoNode) {
    1668         ASSERT(node.adjustedRefCount() == 1);
    1669        
    1670         nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
    1671    
    1672         m_compileIndex = branchNodeIndex;
    1673        
    1674         return true;
    1675     }
    1676    
    1677     nonSpeculativeNonPeepholeCompare(node, cond, helperFunction);
    1678    
    1679     return false;
    1680 }
    1681 
    16821394void JITCodeGenerator::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
    16831395{
     
    18041516}
    18051517
    1806 bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert)
    1807 {
    1808     if (!invert && (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2())))
    1809         return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
    1810    
    1811     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    1812     if (branchNodeIndex != NoNode) {
    1813         ASSERT(node.adjustedRefCount() == 1);
    1814        
    1815         nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
    1816    
    1817         m_compileIndex = branchNodeIndex;
    1818        
    1819         return true;
    1820     }
    1821    
    1822     nonSpeculativeNonPeepholeStrictEq(node, invert);
    1823    
    1824     return false;
    1825 }
    1826 
    18271518void JITCodeGenerator::emitBranch(Node& node)
    18281519{
     
    19031594}
    19041595
    1905 void JITCodeGenerator::speculationCheck(MacroAssembler::Jump jumpToFail)
    1906 {
    1907     ASSERT(m_isSpeculative);
    1908     static_cast<SpeculativeJIT*>(this)->speculationCheck(jumpToFail);
    1909 }
    1910 
    1911 #ifndef NDEBUG
    1912 static const char* dataFormatString(DataFormat format)
    1913 {
    1914     // These values correspond to the DataFormat enum.
    1915     const char* strings[] = {
    1916         "[  ]",
    1917         "[ i]",
    1918         "[ d]",
    1919         "[ c]",
    1920         "Err!",
    1921         "Err!",
    1922         "Err!",
    1923         "Err!",
    1924         "[J ]",
    1925         "[Ji]",
    1926         "[Jd]",
    1927         "[Jc]",
    1928         "Err!",
    1929         "Err!",
    1930         "Err!",
    1931         "Err!",
    1932     };
    1933     return strings[format];
    1934 }
    1935 
    1936 void JITCodeGenerator::dump(const char* label)
    1937 {
    1938     if (label)
    1939         fprintf(stderr, "<%s>\n", label);
    1940 
    1941     fprintf(stderr, "  gprs:\n");
    1942     m_gprs.dump();
    1943     fprintf(stderr, "  fprs:\n");
    1944     m_fprs.dump();
    1945     fprintf(stderr, "  VirtualRegisters:\n");
    1946     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
    1947         GenerationInfo& info = m_generationInfo[i];
    1948         if (info.alive())
    1949             fprintf(stderr, "    % 3d:%s%s", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
    1950         else
    1951             fprintf(stderr, "    % 3d:[__][__]", i);
    1952         if (info.registerFormat() == DataFormatDouble)
    1953             fprintf(stderr, ":fpr%d\n", info.fpr());
    1954         else if (info.registerFormat() != DataFormatNone && !(info.registerFormat() & DataFormatJS)) {
    1955             ASSERT(info.gpr() != InvalidGPRReg);
    1956             fprintf(stderr, ":%s\n", GPRInfo::debugName(info.gpr()));
    1957         } else
    1958             fprintf(stderr, "\n");
    1959     }
    1960     if (label)
    1961         fprintf(stderr, "</%s>\n", label);
    1962 }
    19631596#endif
    19641597
    1965 
    1966 #if ENABLE(DFG_CONSISTENCY_CHECK)
    1967 void JITCodeGenerator::checkConsistency()
    1968 {
    1969     bool failed = false;
    1970 
    1971     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
    1972         if (iter.isLocked()) {
    1973             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: gpr %s is locked.\n", iter.debugName());
    1974             failed = true;
    1975         }
    1976     }
    1977     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
    1978         if (iter.isLocked()) {
    1979             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: fpr %s is locked.\n", iter.debugName());
    1980             failed = true;
    1981         }
    1982     }
    1983 
    1984     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
    1985         VirtualRegister virtualRegister = (VirtualRegister)i;
    1986         GenerationInfo& info = m_generationInfo[virtualRegister];
    1987         if (!info.alive())
    1988             continue;
    1989         switch (info.registerFormat()) {
    1990         case DataFormatNone:
    1991         case DataFormatJS:
    1992         case DataFormatJSInteger:
    1993         case DataFormatJSDouble:
    1994         case DataFormatJSCell:
    1995             break;
    1996         case DataFormatInteger:
    1997         case DataFormatCell: {
    1998             GPRReg gpr = info.gpr();
    1999             ASSERT(gpr != InvalidGPRReg);
    2000             if (m_gprs.name(gpr) != virtualRegister) {
    2001                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (gpr %s).\n", virtualRegister, GPRInfo::debugName(gpr));
    2002                 failed = true;
    2003             }
    2004             break;
    2005         }
    2006         case DataFormatDouble: {
    2007             FPRReg fpr = info.fpr();
    2008             ASSERT(fpr != InvalidFPRReg);
    2009             if (m_fprs.name(fpr) != virtualRegister) {
    2010                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (fpr %s).\n", virtualRegister, FPRInfo::debugName(fpr));
    2011                 failed = true;
    2012             }
    2013             break;
    2014         }
    2015         }
    2016     }
    2017 
    2018     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
    2019         VirtualRegister virtualRegister = iter.name();
    2020         if (virtualRegister == InvalidVirtualRegister)
    2021             continue;
    2022 
    2023         GenerationInfo& info = m_generationInfo[virtualRegister];
    2024         if (!(info.registerFormat() & DataFormatJS)) {
    2025             if (iter.regID() != info.gpr()) {
    2026                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2027                 failed = true;
    2028             }
    2029         } else {
    2030             if (iter.regID() != info.tagGPR() && iter.regID() != info.payloadGPR()) {
    2031                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2032                 failed = true;
    2033             }
    2034         }
    2035     }
    2036 
    2037     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
    2038         VirtualRegister virtualRegister = iter.name();
    2039         if (virtualRegister == InvalidVirtualRegister)
    2040             continue;
    2041 
    2042         GenerationInfo& info = m_generationInfo[virtualRegister];
    2043         if (iter.regID() != info.fpr()) {
    2044             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2045             failed = true;
    2046         }
    2047     }
    2048 
    2049     if (failed) {
    2050         dump();
    2051         CRASH();
    2052     }
    2053 }
     1598} } // namespace JSC::DFG
     1599
    20541600#endif
    2055 
    2056 GPRTemporary::GPRTemporary()
    2057     : m_jit(0)
    2058     , m_gpr(InvalidGPRReg)
    2059 {
    2060 }
    2061 
    2062 GPRTemporary::GPRTemporary(JITCodeGenerator* jit)
    2063     : m_jit(jit)
    2064     , m_gpr(InvalidGPRReg)
    2065 {
    2066     // we currenty lazily allocate the reg, as the number of regs on X86 is limited.
    2067 }
    2068 
    2069 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, GPRReg specific)
    2070     : m_jit(jit)
    2071     , m_gpr(InvalidGPRReg)
    2072 {
    2073     m_gpr = m_jit->allocate(specific);
    2074 }
    2075 
    2076 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1)
    2077     : m_jit(jit)
    2078     , m_gpr(InvalidGPRReg)
    2079 {
    2080     if (m_jit->canReuse(op1.index()))
    2081         m_gpr = m_jit->reuse(op1.gpr());
    2082     else
    2083         m_gpr = m_jit->allocate();
    2084 }
    2085 
    2086 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
    2087     : m_jit(jit)
    2088     , m_gpr(InvalidGPRReg)
    2089 {
    2090     if (m_jit->canReuse(op1.index()))
    2091         m_gpr = m_jit->reuse(op1.gpr());
    2092     else if (m_jit->canReuse(op2.index()))
    2093         m_gpr = m_jit->reuse(op2.gpr());
    2094     else
    2095         m_gpr = m_jit->allocate();
    2096 }
    2097 
    2098 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateStrictInt32Operand& op1)
    2099     : m_jit(jit)
    2100     , m_gpr(InvalidGPRReg)
    2101 {
    2102     if (m_jit->canReuse(op1.index()))
    2103         m_gpr = m_jit->reuse(op1.gpr());
    2104     else
    2105         m_gpr = m_jit->allocate();
    2106 }
    2107 
    2108 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1)
    2109     : m_jit(jit)
    2110     , m_gpr(InvalidGPRReg)
    2111 {
    2112     if (m_jit->canReuse(op1.index()))
    2113         m_gpr = m_jit->reuse(op1.gpr());
    2114     else
    2115         m_gpr = m_jit->allocate();
    2116 }
    2117 
    2118 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1, IntegerOperand& op2)
    2119     : m_jit(jit)
    2120     , m_gpr(InvalidGPRReg)
    2121 {
    2122     if (m_jit->canReuse(op1.index()))
    2123         m_gpr = m_jit->reuse(op1.gpr());
    2124     else if (m_jit->canReuse(op2.index()))
    2125         m_gpr = m_jit->reuse(op2.gpr());
    2126     else
    2127         m_gpr = m_jit->allocate();
    2128 }
    2129 
    2130 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateCellOperand& op1)
    2131     : m_jit(jit)
    2132     , m_gpr(InvalidGPRReg)
    2133 {
    2134     if (m_jit->canReuse(op1.index()))
    2135         m_gpr = m_jit->reuse(op1.gpr());
    2136     else
    2137         m_gpr = m_jit->allocate();
    2138 }
    2139 
    2140 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateBooleanOperand& op1)
    2141     : m_jit(jit)
    2142     , m_gpr(InvalidGPRReg)
    2143 {
    2144     if (m_jit->canReuse(op1.index()))
    2145         m_gpr = m_jit->reuse(op1.gpr());
    2146     else
    2147         m_gpr = m_jit->allocate();
    2148 }
    2149 
    2150 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1, bool tag)
    2151     : m_jit(jit)
    2152     , m_gpr(InvalidGPRReg)
    2153 {
    2154     if (!op1.isDouble() && m_jit->canReuse(op1.index()))
    2155         m_gpr = m_jit->reuse(tag ? op1.tagGPR() : op1.payloadGPR());
    2156     else
    2157         m_gpr = m_jit->allocate();
    2158 }
    2159 
    2160 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, StorageOperand& op1)
    2161     : m_jit(jit)
    2162     , m_gpr(InvalidGPRReg)
    2163 {
    2164     if (m_jit->canReuse(op1.index()))
    2165         m_gpr = m_jit->reuse(op1.gpr());
    2166     else
    2167         m_gpr = m_jit->allocate();
    2168 }
    2169 
    2170 void GPRTemporary::adopt(GPRTemporary& other)
    2171 {
    2172     ASSERT(!m_jit);
    2173     ASSERT(m_gpr == InvalidGPRReg);
    2174     ASSERT(other.m_jit);
    2175     ASSERT(other.m_gpr != InvalidGPRReg);
    2176     m_jit = other.m_jit;
    2177     m_gpr = other.m_gpr;
    2178     other.m_jit = 0;
    2179     other.m_gpr = InvalidGPRReg;
    2180 }
    2181 
    2182 FPRTemporary::FPRTemporary(JITCodeGenerator* jit)
    2183     : m_jit(jit)
    2184     , m_fpr(InvalidFPRReg)
    2185 {
    2186     m_fpr = m_jit->fprAllocate();
    2187 }
    2188 
    2189 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1)
    2190     : m_jit(jit)
    2191     , m_fpr(InvalidFPRReg)
    2192 {
    2193     if (m_jit->canReuse(op1.index()))
    2194         m_fpr = m_jit->reuse(op1.fpr());
    2195     else
    2196         m_fpr = m_jit->fprAllocate();
    2197 }
    2198 
    2199 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1, DoubleOperand& op2)
    2200     : m_jit(jit)
    2201     , m_fpr(InvalidFPRReg)
    2202 {
    2203     if (m_jit->canReuse(op1.index()))
    2204         m_fpr = m_jit->reuse(op1.fpr());
    2205     else if (m_jit->canReuse(op2.index()))
    2206         m_fpr = m_jit->reuse(op2.fpr());
    2207     else
    2208         m_fpr = m_jit->fprAllocate();
    2209 }
    2210 
    2211 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1)
    2212     : m_jit(jit)
    2213     , m_fpr(InvalidFPRReg)
    2214 {
    2215     if (m_jit->canReuse(op1.index()))
    2216         m_fpr = m_jit->reuse(op1.fpr());
    2217     else
    2218         m_fpr = m_jit->fprAllocate();
    2219 }
    2220 
    2221 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1, SpeculateDoubleOperand& op2)
    2222     : m_jit(jit)
    2223     , m_fpr(InvalidFPRReg)
    2224 {
    2225     if (m_jit->canReuse(op1.index()))
    2226         m_fpr = m_jit->reuse(op1.fpr());
    2227     else if (m_jit->canReuse(op2.index()))
    2228         m_fpr = m_jit->reuse(op2.fpr());
    2229     else
    2230         m_fpr = m_jit->fprAllocate();
    2231 }
    2232 
    2233 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
    2234     : m_jit(jit)
    2235     , m_fpr(InvalidFPRReg)
    2236 {
    2237     if (op1.isDouble() && m_jit->canReuse(op1.index()))
    2238         m_fpr = m_jit->reuse(op1.fpr());
    2239     else
    2240         m_fpr = m_jit->fprAllocate();
    2241 }
    2242 
    2243 } } // namespace JSC::DFG
    2244 
    2245 #endif
    2246 #endif
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp

    r96363 r96377  
    2828
    2929#if ENABLE(DFG_JIT)
    30 #if USE(JSVALUE64)
    31 
     30
     31#include "DFGJITCompilerInlineMethods.h"
    3232#include "DFGSpeculativeJIT.h"
    3333#include "LinkBuffer.h"
     
    3535namespace JSC { namespace DFG {
    3636
    37 const double JITCodeGenerator::twoToThe32 = (double)0x100000000ull;
    38 
    39 void JITCodeGenerator::clearGenerationInfo()
    40 {
    41     for (unsigned i = 0; i < m_generationInfo.size(); ++i)
    42         m_generationInfo[i] = GenerationInfo();
    43     m_gprs = RegisterBank<GPRInfo>();
    44     m_fprs = RegisterBank<FPRInfo>();
    45 }
     37#if USE(JSVALUE64)
    4638
    4739GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
     
    329321}
    330322
    331 GPRReg JITCodeGenerator::fillStorage(NodeIndex nodeIndex)
    332 {
    333     Node& node = m_jit.graph()[nodeIndex];
    334     VirtualRegister virtualRegister = node.virtualRegister();
    335     GenerationInfo& info = m_generationInfo[virtualRegister];
    336    
    337     switch (info.registerFormat()) {
    338     case DataFormatNone: {
    339         GPRReg gpr = allocate();
    340         ASSERT(info.spillFormat() == DataFormatStorage);
    341         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    342         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
    343         info.fillStorage(gpr);
    344         return gpr;
    345     }
    346        
    347     case DataFormatStorage: {
    348         GPRReg gpr = info.gpr();
    349         m_gprs.lock(gpr);
    350         return gpr;
    351     }
    352        
    353     default:
    354         ASSERT_NOT_REACHED();
    355     }
    356    
    357     return InvalidGPRReg;
    358 }
    359 
    360 void JITCodeGenerator::useChildren(Node& node)
    361 {
    362     if (node.op & NodeHasVarArgs) {
    363         for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
    364             use(m_jit.graph().m_varArgChildren[childIdx]);
    365     } else {
    366         NodeIndex child1 = node.child1();
    367         if (child1 == NoNode) {
    368             ASSERT(node.child2() == NoNode && node.child3() == NoNode);
    369             return;
    370         }
    371         use(child1);
    372        
    373         NodeIndex child2 = node.child2();
    374         if (child2 == NoNode) {
    375             ASSERT(node.child3() == NoNode);
    376             return;
    377         }
    378         use(child2);
    379        
    380         NodeIndex child3 = node.child3();
    381         if (child3 == NoNode)
    382             return;
    383         use(child3);
    384     }
    385 }
    386 
    387 bool JITCodeGenerator::isStrictInt32(NodeIndex nodeIndex)
    388 {
    389     if (isInt32Constant(nodeIndex))
    390         return true;
    391    
    392     Node& node = m_jit.graph()[nodeIndex];
    393     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    394    
    395     return info.registerFormat() == DataFormatInteger;
    396 }
    397 
    398 bool JITCodeGenerator::isKnownInteger(NodeIndex nodeIndex)
    399 {
    400     if (isInt32Constant(nodeIndex))
    401         return true;
    402 
    403     Node& node = m_jit.graph()[nodeIndex];
    404    
    405     if (node.hasInt32Result())
    406         return true;
    407    
    408     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    409 
    410     return info.isJSInteger();
    411 }
    412 
    413 bool JITCodeGenerator::isKnownNumeric(NodeIndex nodeIndex)
    414 {
    415     if (isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex))
    416         return true;
    417 
    418     Node& node = m_jit.graph()[nodeIndex];
    419    
    420     if (node.hasNumberResult())
    421         return true;
    422    
    423     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    424 
    425     return info.isJSInteger() || info.isJSDouble();
    426 }
    427 
    428 bool JITCodeGenerator::isKnownCell(NodeIndex nodeIndex)
    429 {
    430     return m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()].isJSCell();
    431 }
    432 
    433 bool JITCodeGenerator::isKnownNotCell(NodeIndex nodeIndex)
    434 {
    435     Node& node = m_jit.graph()[nodeIndex];
    436     VirtualRegister virtualRegister = node.virtualRegister();
    437     GenerationInfo& info = m_generationInfo[virtualRegister];
    438     if (node.hasConstant() && !valueOfJSConstant(nodeIndex).isCell())
    439         return true;
    440     return !(info.isJSCell() || info.isUnknownJS());
    441 }
    442 
    443 bool JITCodeGenerator::isKnownNotInteger(NodeIndex nodeIndex)
    444 {
    445     Node& node = m_jit.graph()[nodeIndex];
    446     VirtualRegister virtualRegister = node.virtualRegister();
    447     GenerationInfo& info = m_generationInfo[virtualRegister];
    448    
    449     return info.isJSDouble() || info.isJSCell() || info.isJSBoolean()
    450         || (node.hasConstant() && !valueOfJSConstant(nodeIndex).isInt32());
    451 }
    452 
    453 bool JITCodeGenerator::isKnownNotNumber(NodeIndex nodeIndex)
    454 {
    455     Node& node = m_jit.graph()[nodeIndex];
    456     VirtualRegister virtualRegister = node.virtualRegister();
    457     GenerationInfo& info = m_generationInfo[virtualRegister];
    458    
    459     return (!info.isJSDouble() && !info.isJSInteger() && !info.isUnknownJS())
    460         || (node.hasConstant() && !isNumberConstant(nodeIndex));
    461 }
    462 
    463 bool JITCodeGenerator::isKnownBoolean(NodeIndex nodeIndex)
    464 {
    465     Node& node = m_jit.graph()[nodeIndex];
    466     if (node.hasBooleanResult())
    467         return true;
    468    
    469     if (isBooleanConstant(nodeIndex))
    470         return true;
    471    
    472     VirtualRegister virtualRegister = node.virtualRegister();
    473     GenerationInfo& info = m_generationInfo[virtualRegister];
    474    
    475     return info.isJSBoolean();
    476 }
    477 
    478323void JITCodeGenerator::nonSpeculativeValueToNumber(Node& node)
    479324{
     
    11761021   
    11771022    return functionCall;
    1178 }
    1179 
    1180 void JITCodeGenerator::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
    1181 {
    1182     UNUSED_PARAM(jit);
    1183     UNUSED_PARAM(owner);
    1184     UNUSED_PARAM(scratch1);
    1185     UNUSED_PARAM(scratch2);
    1186     UNUSED_PARAM(useKind);
    1187     ASSERT(owner != scratch1);
    1188     ASSERT(owner != scratch2);
    1189     ASSERT(scratch1 != scratch2);
    1190 
    1191 #if ENABLE(WRITE_BARRIER_PROFILING)
    1192     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1193 #endif
    1194     markCellCard(jit, owner, scratch1, scratch2);
    1195 }
    1196 
    1197 void JITCodeGenerator::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
    1198 {
    1199     UNUSED_PARAM(jit);
    1200     UNUSED_PARAM(owner);
    1201     UNUSED_PARAM(scratch1);
    1202     UNUSED_PARAM(scratch2);
    1203    
    1204 #if ENABLE(GGC)
    1205     jit.move(owner, scratch1);
    1206     jit.andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch1);
    1207     jit.move(owner, scratch2);
    1208     jit.andPtr(TrustedImm32(static_cast<int32_t>(~MarkedBlock::blockMask)), scratch2);
    1209     jit.rshift32(TrustedImm32(MarkedBlock::log2CardSize), scratch2);
    1210     jit.store8(TrustedImm32(1), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfCards()));
    1211 #endif
    1212 }
    1213 
    1214 void JITCodeGenerator::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
    1215 {
    1216     UNUSED_PARAM(ownerGPR);
    1217     UNUSED_PARAM(valueGPR);
    1218     UNUSED_PARAM(scratch1);
    1219     UNUSED_PARAM(scratch2);
    1220     UNUSED_PARAM(useKind);
    1221 
    1222     if (isKnownNotCell(valueIndex))
    1223         return;
    1224 
    1225 #if ENABLE(WRITE_BARRIER_PROFILING)
    1226     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1227 #endif
    1228 
    1229 #if ENABLE(GGC)
    1230     JITCompiler::Jump rhsNotCell;
    1231     bool hadCellCheck = false;
    1232     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    1233         hadCellCheck = true;
    1234         rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
    1235     }
    1236 
    1237     GPRTemporary temp1;
    1238     GPRTemporary temp2;
    1239     if (scratch1 == InvalidGPRReg) {
    1240         GPRTemporary scratchGPR(this);
    1241         temp1.adopt(scratchGPR);
    1242         scratch1 = temp1.gpr();
    1243     }
    1244     if (scratch2 == InvalidGPRReg) {
    1245         GPRTemporary scratchGPR(this);
    1246         temp2.adopt(scratchGPR);
    1247         scratch2 = temp2.gpr();
    1248     }
    1249 
    1250     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
    1251     if (hadCellCheck)
    1252         rhsNotCell.link(&m_jit);
    1253 #endif
    1254 }
    1255 
    1256 void JITCodeGenerator::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch)
    1257 {
    1258     UNUSED_PARAM(owner);
    1259     UNUSED_PARAM(valueGPR);
    1260     UNUSED_PARAM(scratch);
    1261     UNUSED_PARAM(useKind);
    1262 
    1263     if (isKnownNotCell(valueIndex))
    1264         return;
    1265 
    1266 #if ENABLE(WRITE_BARRIER_PROFILING)
    1267     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
    1268 #endif
    1269 
    1270 #if ENABLE(GGC)
    1271     JITCompiler::Jump rhsNotCell;
    1272     bool hadCellCheck = false;
    1273     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
    1274         hadCellCheck = true;
    1275         rhsNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
    1276     }
    1277    
    1278     GPRTemporary temp;
    1279     if (scratch == InvalidGPRReg) {
    1280         GPRTemporary scratchGPR(this);
    1281         temp.adopt(scratchGPR);
    1282         scratch = temp.gpr();
    1283     }
    1284 
    1285     uint8_t* cardAddress = Heap::addressOfCardFor(owner);
    1286     m_jit.move(JITCompiler::TrustedImmPtr(cardAddress), scratch);
    1287     m_jit.store8(JITCompiler::TrustedImm32(1), JITCompiler::Address(scratch));
    1288 
    1289     if (hadCellCheck)
    1290         rhsNotCell.link(&m_jit);
    1291 #endif
    12921023}
    12931024
     
    15881319}
    15891320
    1590 bool JITCodeGenerator::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, Z_DFGOperation_EJJ helperFunction)
    1591 {
    1592     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    1593     if (branchNodeIndex != NoNode) {
    1594         ASSERT(node.adjustedRefCount() == 1);
    1595        
    1596         nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
    1597    
    1598         m_compileIndex = branchNodeIndex;
    1599        
    1600         return true;
    1601     }
    1602    
    1603     nonSpeculativeNonPeepholeCompare(node, cond, helperFunction);
    1604    
    1605     return false;
    1606 }
    1607 
    16081321void JITCodeGenerator::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
    16091322{
     
    17491462}
    17501463
    1751 bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert)
    1752 {
    1753     if (!invert && (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2())))
    1754         return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
    1755    
    1756     NodeIndex branchNodeIndex = detectPeepHoleBranch();
    1757     if (branchNodeIndex != NoNode) {
    1758         ASSERT(node.adjustedRefCount() == 1);
    1759        
    1760         nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
    1761    
    1762         m_compileIndex = branchNodeIndex;
    1763        
    1764         return true;
    1765     }
    1766    
    1767     nonSpeculativeNonPeepholeStrictEq(node, invert);
    1768    
    1769     return false;
    1770 }
    1771 
    17721464void JITCodeGenerator::emitBranch(Node& node)
    17731465{
     
    19481640}
    19491641
    1950 void JITCodeGenerator::speculationCheck(MacroAssembler::Jump jumpToFail)
    1951 {
    1952     ASSERT(m_isSpeculative);
    1953     static_cast<SpeculativeJIT*>(this)->speculationCheck(jumpToFail);
    1954 }
    1955 
    1956 #ifndef NDEBUG
    1957 static const char* dataFormatString(DataFormat format)
    1958 {
    1959     // These values correspond to the DataFormat enum.
    1960     const char* strings[] = {
    1961         "[  ]",
    1962         "[ i]",
    1963         "[ d]",
    1964         "[ c]",
    1965         "Err!",
    1966         "Err!",
    1967         "Err!",
    1968         "Err!",
    1969         "[J ]",
    1970         "[Ji]",
    1971         "[Jd]",
    1972         "[Jc]",
    1973         "Err!",
    1974         "Err!",
    1975         "Err!",
    1976         "Err!",
    1977     };
    1978     return strings[format];
    1979 }
    1980 
    1981 void JITCodeGenerator::dump(const char* label)
    1982 {
    1983     if (label)
    1984         fprintf(stderr, "<%s>\n", label);
    1985 
    1986     fprintf(stderr, "  gprs:\n");
    1987     m_gprs.dump();
    1988     fprintf(stderr, "  fprs:\n");
    1989     m_fprs.dump();
    1990     fprintf(stderr, "  VirtualRegisters:\n");
    1991     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
    1992         GenerationInfo& info = m_generationInfo[i];
    1993         if (info.alive())
    1994             fprintf(stderr, "    % 3d:%s%s", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
    1995         else
    1996             fprintf(stderr, "    % 3d:[__][__]", i);
    1997         if (info.registerFormat() == DataFormatDouble)
    1998             fprintf(stderr, ":fpr%d\n", info.fpr());
    1999         else if (info.registerFormat() != DataFormatNone) {
    2000             ASSERT(info.gpr() != InvalidGPRReg);
    2001             fprintf(stderr, ":%s\n", GPRInfo::debugName(info.gpr()));
    2002         } else
    2003             fprintf(stderr, "\n");
    2004     }
    2005     if (label)
    2006         fprintf(stderr, "</%s>\n", label);
    2007 }
    20081642#endif
    20091643
    2010 
    2011 #if ENABLE(DFG_CONSISTENCY_CHECK)
    2012 void JITCodeGenerator::checkConsistency()
    2013 {
    2014     bool failed = false;
    2015 
    2016     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
    2017         if (iter.isLocked()) {
    2018             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: gpr %s is locked.\n", iter.debugName());
    2019             failed = true;
    2020         }
    2021     }
    2022     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
    2023         if (iter.isLocked()) {
    2024             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: fpr %s is locked.\n", iter.debugName());
    2025             failed = true;
    2026         }
    2027     }
    2028 
    2029     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
    2030         VirtualRegister virtualRegister = (VirtualRegister)i;
    2031         GenerationInfo& info = m_generationInfo[virtualRegister];
    2032         if (!info.alive())
    2033             continue;
    2034         switch (info.registerFormat()) {
    2035         case DataFormatNone:
    2036             break;
    2037         case DataFormatInteger:
    2038         case DataFormatCell:
    2039         case DataFormatJS:
    2040         case DataFormatJSInteger:
    2041         case DataFormatJSDouble:
    2042         case DataFormatJSCell: {
    2043             GPRReg gpr = info.gpr();
    2044             ASSERT(gpr != InvalidGPRReg);
    2045             if (m_gprs.name(gpr) != virtualRegister) {
    2046                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (gpr %s).\n", virtualRegister, GPRInfo::debugName(gpr));
    2047                 failed = true;
    2048             }
    2049             break;
    2050         }
    2051         case DataFormatDouble: {
    2052             FPRReg fpr = info.fpr();
    2053             ASSERT(fpr != InvalidFPRReg);
    2054             if (m_fprs.name(fpr) != virtualRegister) {
    2055                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (fpr %s).\n", virtualRegister, FPRInfo::debugName(fpr));
    2056                 failed = true;
    2057             }
    2058             break;
    2059         }
    2060         }
    2061     }
    2062 
    2063     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
    2064         VirtualRegister virtualRegister = iter.name();
    2065         if (virtualRegister == InvalidVirtualRegister)
    2066             continue;
    2067 
    2068         GenerationInfo& info = m_generationInfo[virtualRegister];
    2069         if (iter.regID() != info.gpr()) {
    2070             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2071             failed = true;
    2072         }
    2073     }
    2074 
    2075     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
    2076         VirtualRegister virtualRegister = iter.name();
    2077         if (virtualRegister == InvalidVirtualRegister)
    2078             continue;
    2079 
    2080         GenerationInfo& info = m_generationInfo[virtualRegister];
    2081         if (iter.regID() != info.fpr()) {
    2082             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
    2083             failed = true;
    2084         }
    2085     }
    2086 
    2087     if (failed) {
    2088         dump();
    2089         CRASH();
    2090     }
    2091 }
     1644} } // namespace JSC::DFG
     1645
    20921646#endif
    2093 
    2094 GPRTemporary::GPRTemporary()
    2095     : m_jit(0)
    2096     , m_gpr(InvalidGPRReg)
    2097 {
    2098 }
    2099 
    2100 GPRTemporary::GPRTemporary(JITCodeGenerator* jit)
    2101     : m_jit(jit)
    2102     , m_gpr(InvalidGPRReg)
    2103 {
    2104     m_gpr = m_jit->allocate();
    2105 }
    2106 
    2107 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, GPRReg specific)
    2108     : m_jit(jit)
    2109     , m_gpr(InvalidGPRReg)
    2110 {
    2111     m_gpr = m_jit->allocate(specific);
    2112 }
    2113 
    2114 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1)
    2115     : m_jit(jit)
    2116     , m_gpr(InvalidGPRReg)
    2117 {
    2118     if (m_jit->canReuse(op1.index()))
    2119         m_gpr = m_jit->reuse(op1.gpr());
    2120     else
    2121         m_gpr = m_jit->allocate();
    2122 }
    2123 
    2124 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
    2125     : m_jit(jit)
    2126     , m_gpr(InvalidGPRReg)
    2127 {
    2128     if (m_jit->canReuse(op1.index()))
    2129         m_gpr = m_jit->reuse(op1.gpr());
    2130     else if (m_jit->canReuse(op2.index()))
    2131         m_gpr = m_jit->reuse(op2.gpr());
    2132     else
    2133         m_gpr = m_jit->allocate();
    2134 }
    2135 
    2136 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateStrictInt32Operand& op1)
    2137     : m_jit(jit)
    2138     , m_gpr(InvalidGPRReg)
    2139 {
    2140     if (m_jit->canReuse(op1.index()))
    2141         m_gpr = m_jit->reuse(op1.gpr());
    2142     else
    2143         m_gpr = m_jit->allocate();
    2144 }
    2145 
    2146 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1)
    2147     : m_jit(jit)
    2148     , m_gpr(InvalidGPRReg)
    2149 {
    2150     if (m_jit->canReuse(op1.index()))
    2151         m_gpr = m_jit->reuse(op1.gpr());
    2152     else
    2153         m_gpr = m_jit->allocate();
    2154 }
    2155 
    2156 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1, IntegerOperand& op2)
    2157     : m_jit(jit)
    2158     , m_gpr(InvalidGPRReg)
    2159 {
    2160     if (m_jit->canReuse(op1.index()))
    2161         m_gpr = m_jit->reuse(op1.gpr());
    2162     else if (m_jit->canReuse(op2.index()))
    2163         m_gpr = m_jit->reuse(op2.gpr());
    2164     else
    2165         m_gpr = m_jit->allocate();
    2166 }
    2167 
    2168 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateCellOperand& op1)
    2169     : m_jit(jit)
    2170     , m_gpr(InvalidGPRReg)
    2171 {
    2172     if (m_jit->canReuse(op1.index()))
    2173         m_gpr = m_jit->reuse(op1.gpr());
    2174     else
    2175         m_gpr = m_jit->allocate();
    2176 }
    2177 
    2178 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateBooleanOperand& op1)
    2179     : m_jit(jit)
    2180     , m_gpr(InvalidGPRReg)
    2181 {
    2182     if (m_jit->canReuse(op1.index()))
    2183         m_gpr = m_jit->reuse(op1.gpr());
    2184     else
    2185         m_gpr = m_jit->allocate();
    2186 }
    2187 
    2188 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
    2189     : m_jit(jit)
    2190     , m_gpr(InvalidGPRReg)
    2191 {
    2192     if (m_jit->canReuse(op1.index()))
    2193         m_gpr = m_jit->reuse(op1.gpr());
    2194     else
    2195         m_gpr = m_jit->allocate();
    2196 }
    2197 
    2198 GPRTemporary::GPRTemporary(JITCodeGenerator* jit, StorageOperand& op1)
    2199     : m_jit(jit)
    2200     , m_gpr(InvalidGPRReg)
    2201 {
    2202     if (m_jit->canReuse(op1.index()))
    2203         m_gpr = m_jit->reuse(op1.gpr());
    2204     else
    2205         m_gpr = m_jit->allocate();
    2206 }
    2207 
    2208 void GPRTemporary::adopt(GPRTemporary& other)
    2209 {
    2210     ASSERT(!m_jit);
    2211     ASSERT(m_gpr == InvalidGPRReg);
    2212     ASSERT(other.m_jit);
    2213     ASSERT(other.m_gpr != InvalidGPRReg);
    2214     m_jit = other.m_jit;
    2215     m_gpr = other.m_gpr;
    2216     other.m_jit = 0;
    2217     other.m_gpr = InvalidGPRReg;
    2218 }
    2219 
    2220 FPRTemporary::FPRTemporary(JITCodeGenerator* jit)
    2221     : m_jit(jit)
    2222     , m_fpr(InvalidFPRReg)
    2223 {
    2224     m_fpr = m_jit->fprAllocate();
    2225 }
    2226 
    2227 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1)
    2228     : m_jit(jit)
    2229     , m_fpr(InvalidFPRReg)
    2230 {
    2231     if (m_jit->canReuse(op1.index()))
    2232         m_fpr = m_jit->reuse(op1.fpr());
    2233     else
    2234         m_fpr = m_jit->fprAllocate();
    2235 }
    2236 
    2237 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1, DoubleOperand& op2)
    2238     : m_jit(jit)
    2239     , m_fpr(InvalidFPRReg)
    2240 {
    2241     if (m_jit->canReuse(op1.index()))
    2242         m_fpr = m_jit->reuse(op1.fpr());
    2243     else if (m_jit->canReuse(op2.index()))
    2244         m_fpr = m_jit->reuse(op2.fpr());
    2245     else
    2246         m_fpr = m_jit->fprAllocate();
    2247 }
    2248 
    2249 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1)
    2250     : m_jit(jit)
    2251     , m_fpr(InvalidFPRReg)
    2252 {
    2253     if (m_jit->canReuse(op1.index()))
    2254         m_fpr = m_jit->reuse(op1.fpr());
    2255     else
    2256         m_fpr = m_jit->fprAllocate();
    2257 }
    2258 
    2259 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1, SpeculateDoubleOperand& op2)
    2260     : m_jit(jit)
    2261     , m_fpr(InvalidFPRReg)
    2262 {
    2263     if (m_jit->canReuse(op1.index()))
    2264         m_fpr = m_jit->reuse(op1.fpr());
    2265     else if (m_jit->canReuse(op2.index()))
    2266         m_fpr = m_jit->reuse(op2.fpr());
    2267     else
    2268         m_fpr = m_jit->fprAllocate();
    2269 }
    2270 
    2271 } } // namespace JSC::DFG
    2272 
    2273 #endif
    2274 #endif
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r96375 r96377  
    166166#endif
    167167
     168    Jump branchIfNotCell(GPRReg reg)
     169    {
     170#if USE(JSVALUE64)
     171        return branchTestPtr(MacroAssembler::NonZero, reg, GPRInfo::tagMaskRegister);
     172#else
     173        return branch32(MacroAssembler::NotEqual, reg, TrustedImm32(JSValue::CellTag));
     174#endif
     175    }
     176   
    168177    static Address addressForGlobalVar(GPRReg global, int32_t varNumber)
    169178    {
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompilerInlineMethods.h

    r95902 r96377  
    55
    66#if ENABLE(DFG_JIT)
    7 #if USE(JSVALUE32_64)
    87
    98namespace JSC { namespace DFG {
     9
     10#if USE(JSVALUE32_64)
    1011
    1112inline void JITCompiler::emitLoadTag(NodeIndex index, GPRReg tag)
     
    135136}
    136137
     138#endif // USE(JSVALUE32_64)
     139
    137140} } // namespace JSC::DFG
    138141
    139 #endif // USE(JSVALUE32_64)
    140142#endif // ENABLE_DFG_JIT
    141143
Note: See TracChangeset for help on using the changeset viewer.