Changeset 182827 in webkit


Ignore:
Timestamp:
Apr 14, 2015 5:49:03 PM (9 years ago)
Author:
msaboff@apple.com
Message:

DFG register fillSpeculate*() functions should validate incoming spill format is compatible with requested fill format
https://bugs.webkit.org/show_bug.cgi?id=143727

Reviewed by Geoffrey Garen.

Used the result of AbstractInterpreter<>::filter() to check that the current spill format is compatible
with the requested fill format. If filter() reports a contradiction, then we force an OSR exit.
Removed individual checks made redundant by the new check.

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r182826 r182827  
     12015-04-14  Michael Saboff  <msaboff@apple.com>
     2
     3        DFG register fillSpeculate*() functions should validate incoming spill format is compatible with requested fill format
     4        https://bugs.webkit.org/show_bug.cgi?id=143727
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Used the result of AbstractInterpreter<>::filter() to check that the current spill format is compatible
     9        with the requested fill format.  If filter() reports a contradiction, then we force an OSR exit.
     10        Removed individual checks made redundant by the new check.
     11
     12        * dfg/DFGSpeculativeJIT32_64.cpp:
     13        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
     14        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     15        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     16        * dfg/DFGSpeculativeJIT64.cpp:
     17        (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
     18        (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
     19        (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
     20        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     21
    1222015-04-14  Joseph Pecoraro  <pecoraro@apple.com>
    223
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r182759 r182827  
    846846    SpeculatedType type = value.m_type;
    847847    ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
    848     m_interpreter.filter(value, SpecInt32);
    849     VirtualRegister virtualRegister = edge->virtualRegister();
    850     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    851 
    852     if (edge->hasConstant() && !edge->isInt32Constant()) {
     848
     849    if (m_interpreter.filter(value, SpecInt32) == Contradiction) {
    853850        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    854851        returnFormat = DataFormatInt32;
    855852        return allocate();
    856853    }
    857    
     854
     855    VirtualRegister virtualRegister = edge->virtualRegister();
     856    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     857
    858858    switch (info.registerFormat()) {
    859859    case DataFormatNone: {
     
    869869
    870870        DataFormat spillFormat = info.spillFormat();
    871 
    872         if (spillFormat == DataFormatCell) {
    873             terminateSpeculativeExecution(BadType, JSValueRegs(), edge);
    874             returnFormat = DataFormatInt32;
    875             return allocate();
    876         }
    877871
    878872        ASSERT_UNUSED(spillFormat, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
     
    921915    case DataFormatJSCell:
    922916    case DataFormatJSBoolean:
    923         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    924         returnFormat = DataFormatInt32;
    925         return allocate();
    926 
    927917    case DataFormatDouble:
    928918    case DataFormatStorage:
     
    983973    SpeculatedType type = value.m_type;
    984974    ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
    985     m_interpreter.filter(value, SpecCell);
     975
     976    if (m_interpreter.filter(value, SpecCell) == Contradiction) {
     977        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     978        return allocate();
     979    }
     980
    986981    VirtualRegister virtualRegister = edge->virtualRegister();
    987982    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    988    
    989     if (edge->hasConstant() && !edge->isCellConstant()) {
    990         // Protect the silent spill/fill logic by failing early. If we "speculate" on
    991         // the constant then the silent filler may think that we have a cell and a
    992         // constant, so it will try to fill this as an cell constant. Bad things will
    993         // happen.
    994         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    995         return allocate();
    996     }
    997983
    998984    switch (info.registerFormat()) {
    999985    case DataFormatNone: {
    1000         if (info.spillFormat() == DataFormatInt32) {
    1001             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1002             return allocate();
    1003         }
    1004 
    1005986        if (edge->hasConstant()) {
    1006987            JSValue jsValue = edge->asJSValue();
     
    10601041    case DataFormatJSBoolean:
    10611042    case DataFormatBoolean:
    1062         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1063         return allocate();
    1064 
    10651043    case DataFormatDouble:
    10661044    case DataFormatStorage:
     
    10771055    AbstractValue& value = m_state.forNode(edge);
    10781056    SpeculatedType type = value.m_type;
    1079     m_interpreter.filter(value, SpecBoolean);
     1057
     1058    if (m_interpreter.filter(value, SpecBoolean) == Contradiction) {
     1059        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1060        return allocate();
     1061    }
     1062
    10801063    VirtualRegister virtualRegister = edge->virtualRegister();
    10811064    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    10831066    switch (info.registerFormat()) {
    10841067    case DataFormatNone: {
    1085         if (info.spillFormat() == DataFormatInt32) {
    1086             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1087             return allocate();
    1088         }
    1089        
    10901068        if (edge->hasConstant()) {
    10911069            JSValue jsValue = edge->asJSValue();
    10921070            GPRReg gpr = allocate();
    1093             if (jsValue.isBoolean()) {
    1094                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    1095                 m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
    1096                 info.fillBoolean(*m_stream, gpr);
    1097                 return gpr;
    1098             }
    1099             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1071            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     1072            m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
     1073            info.fillBoolean(*m_stream, gpr);
    11001074            return gpr;
    11011075        }
     
    11411115    case DataFormatJSCell:
    11421116    case DataFormatCell:
    1143         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1144         return allocate();
    1145 
    11461117    case DataFormatDouble:
    11471118    case DataFormatStorage:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r182759 r182827  
    818818    SpeculatedType type = value.m_type;
    819819    ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32));
    820     m_interpreter.filter(value, SpecInt32);
    821     VirtualRegister virtualRegister = edge->virtualRegister();
    822     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    823 
    824     if (edge->hasConstant() && !edge->isInt32Constant()) {
    825         // Protect the silent spill/fill logic by failing early. If we "speculate" on
    826         // the constant then the silent filler may think that we have an int32 and a
    827         // constant, so it will try to fill this as an int32 constant. Bad things will
    828         // happen.
     820
     821    if (m_interpreter.filter(value, SpecInt32) == Contradiction) {
    829822        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    830823        returnFormat = DataFormatInt32;
    831824        return allocate();
    832825    }
    833    
     826
     827    VirtualRegister virtualRegister = edge->virtualRegister();
     828    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     829
    834830    switch (info.registerFormat()) {
    835831    case DataFormatNone: {
     
    930926    case DataFormatBoolean:
    931927    case DataFormatJSCell:
    932     case DataFormatJSBoolean: {
    933         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    934         returnFormat = DataFormatInt32;
    935         return allocate();
    936     }
    937 
     928    case DataFormatJSBoolean:
    938929    case DataFormatDouble:
    939930    case DataFormatStorage:
     
    968959    ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
    969960    AbstractValue& value = m_state.forNode(edge);
    970     m_interpreter.filter(value, SpecMachineInt);
     961
     962    if (m_interpreter.filter(value, SpecMachineInt) == Contradiction) {
     963        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     964        return allocate();
     965    }
     966
    971967    VirtualRegister virtualRegister = edge->virtualRegister();
    972968    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    974970    switch (info.registerFormat()) {
    975971    case DataFormatNone: {
    976         if (edge->hasConstant() && !edge->isMachineIntConstant()) {
    977             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    978             return allocate();
    979         }
    980        
    981972        GPRReg gpr = allocate();
    982973
     
    10971088    SpeculatedType type = value.m_type;
    10981089    ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
    1099     m_interpreter.filter(value, SpecCell);
     1090
     1091    if (m_interpreter.filter(value, SpecCell) == Contradiction) {
     1092        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1093        return allocate();
     1094    }
     1095
    11001096    VirtualRegister virtualRegister = edge->virtualRegister();
    11011097    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    1102 
    1103     if (edge->hasConstant() && !edge->isCellConstant()) {
    1104         // Better to fail early on constants.
    1105         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1106         return allocate();
    1107     }
    11081098
    11091099    switch (info.registerFormat()) {
     
    11181108            return gpr;
    11191109        }
    1120        
    1121         if (!(info.spillFormat() & DataFormatJS)) {
    1122             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1123             return gpr;
    1124         }
    1125        
     1110
    11261111        m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
    11271112        m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
     
    11591144    case DataFormatJSDouble:
    11601145    case DataFormatJSBoolean:
    1161     case DataFormatBoolean: {
    1162         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1163         return allocate();
    1164     }
    1165 
     1146    case DataFormatBoolean:
    11661147    case DataFormatDouble:
    11671148    case DataFormatStorage:
     
    11801161    AbstractValue& value = m_state.forNode(edge);
    11811162    SpeculatedType type = value.m_type;
    1182     m_interpreter.filter(value, SpecBoolean);
     1163
     1164    if (m_interpreter.filter(value, SpecBoolean) == Contradiction) {
     1165        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1166        return allocate();
     1167    }
     1168
    11831169    VirtualRegister virtualRegister = edge->virtualRegister();
    11841170    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     
    11861172    switch (info.registerFormat()) {
    11871173    case DataFormatNone: {
    1188         if (info.spillFormat() == DataFormatInt32) {
    1189             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1190             return allocate();
    1191         }
    1192        
    11931174        GPRReg gpr = allocate();
    11941175
    11951176        if (edge->hasConstant()) {
    11961177            JSValue jsValue = edge->asJSValue();
    1197             if (jsValue.isBoolean()) {
    1198                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    1199                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
    1200                 info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
    1201                 return gpr;
    1202             }
    1203             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1178            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     1179            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
     1180            info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
    12041181            return gpr;
    12051182        }
     
    12421219    case DataFormatJSCell:
    12431220    case DataFormatCell:
    1244         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
    1245         return allocate();
    1246        
    12471221    case DataFormatDouble:
    12481222    case DataFormatStorage:
Note: See TracChangeset for help on using the changeset viewer.