ValueRecovery should distinguish between doubles in an FPR and JSValues in an FPR
authorbasile_clement@apple.com <basile_clement@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 31 Aug 2015 23:13:13 +0000 (23:13 +0000)
committerbasile_clement@apple.com <basile_clement@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 31 Aug 2015 23:13:13 +0000 (23:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148336

Reviewed by Michael Saboff.

Currently, ValueRecovery::InFPR means "this is a *double* value in an
FPR". Let's change the semantics to be "this is a *JSValue* in an FPR"
(to match ValueRecovery::InGPR), and introduce
ValueRecovery::UnboxedDoubleInFPR to mean "this is a double value in an
FPR".

* bytecode/ValueRecovery.cpp:
(JSC::ValueRecovery::dumpInContext):
* bytecode/ValueRecovery.h:
(JSC::ValueRecovery::operator bool):
(JSC::ValueRecovery::inFPR):
(JSC::ValueRecovery::isInGPR):
(JSC::ValueRecovery::isInFPR):
(JSC::ValueRecovery::isInRegisters):
(JSC::ValueRecovery::isInJSStack):
(JSC::ValueRecovery::dataFormat):
(JSC::ValueRecovery::gpr):
(JSC::ValueRecovery::isInJSValueRegs):
(JSC::ValueRecovery::jsValueRegs):
(JSC::ValueRecovery::fpr):
(JSC::ValueRecovery::virtualRegister):
(JSC::ValueRecovery::constant):
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::VariableEventStream::reconstruct):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189192 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/ValueRecovery.cpp
Source/JavaScriptCore/bytecode/ValueRecovery.h
Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp

index e88842e..895d1d5 100644 (file)
@@ -1,3 +1,39 @@
+2015-08-24  Basile Clement  <basile_clement@apple.com>
+
+        ValueRecovery should distinguish between doubles in an FPR and JSValues in an FPR
+        https://bugs.webkit.org/show_bug.cgi?id=148336
+
+        Reviewed by Michael Saboff.
+
+        Currently, ValueRecovery::InFPR means "this is a *double* value in an
+        FPR". Let's change the semantics to be "this is a *JSValue* in an FPR"
+        (to match ValueRecovery::InGPR), and introduce
+        ValueRecovery::UnboxedDoubleInFPR to mean "this is a double value in an
+        FPR".
+
+        * bytecode/ValueRecovery.cpp:
+        (JSC::ValueRecovery::dumpInContext):
+        * bytecode/ValueRecovery.h:
+        (JSC::ValueRecovery::operator bool):
+        (JSC::ValueRecovery::inFPR):
+        (JSC::ValueRecovery::isInGPR):
+        (JSC::ValueRecovery::isInFPR):
+        (JSC::ValueRecovery::isInRegisters):
+        (JSC::ValueRecovery::isInJSStack):
+        (JSC::ValueRecovery::dataFormat):
+        (JSC::ValueRecovery::gpr):
+        (JSC::ValueRecovery::isInJSValueRegs):
+        (JSC::ValueRecovery::jsValueRegs):
+        (JSC::ValueRecovery::fpr):
+        (JSC::ValueRecovery::virtualRegister):
+        (JSC::ValueRecovery::constant):
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::VariableEventStream::reconstruct):
+
 2015-08-31  Chris Dumez  <cdumez@apple.com>
 
         NodeFilter.SHOW_ALL has wrong value on 32-bit
index 996fd3b..9c083b0 100644 (file)
@@ -86,6 +86,9 @@ void ValueRecovery::dumpInContext(PrintStream& out, DumpContext* context) const
     case InFPR:
         out.print(fpr());
         return;
+    case UnboxedDoubleInFPR:
+        out.print("double(", fpr(), ")");
+        return;
 #if USE(JSVALUE32_64)
     case InPair:
         out.print("pair(", tagGPR(), ", ", payloadGPR(), ")");
index 42651e2..d88c55c 100644 (file)
@@ -55,6 +55,7 @@ enum ValueRecoveryTechnique {
     InPair,
 #endif
     InFPR,
+    UnboxedDoubleInFPR,
     // It's in the stack, but at a different location.
     DisplacedInJSStack,
     // It's in the stack, at a different location, and it's unboxed.
@@ -82,6 +83,7 @@ public:
     
     bool isSet() const { return m_technique != DontKnow; }
     bool operator!() const { return !isSet(); }
+    explicit operator bool() const { return isSet(); }
     
     static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
     {
@@ -117,10 +119,14 @@ public:
     }
 #endif
 
-    static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr)
+    static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr, DataFormat dataFormat)
     {
+        ASSERT(dataFormat == DataFormatDouble || dataFormat & DataFormatJS);
         ValueRecovery result;
-        result.m_technique = InFPR;
+        if (dataFormat == DataFormatDouble)
+            result.m_technique = UnboxedDoubleInFPR;
+        else
+            result.m_technique = InFPR;
         result.m_source.fpr = fpr;
         return result;
     }
@@ -185,12 +191,12 @@ public:
         result.m_source.nodeID = id.bits();
         return result;
     }
-    
+
     ValueRecoveryTechnique technique() const { return m_technique; }
     
     bool isConstant() const { return m_technique == Constant; }
-    
-    bool isInRegisters() const
+
+    bool isInGPR() const
     {
         switch (m_technique) {
         case InGPR:
@@ -199,19 +205,81 @@ public:
         case UnboxedCellInGPR:
         case UnboxedInt52InGPR:
         case UnboxedStrictInt52InGPR:
-#if USE(JSVALUE32_64)
-        case InPair:
-#endif
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isInFPR() const
+    {
+        switch (m_technique) {
         case InFPR:
+        case UnboxedDoubleInFPR:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    bool isInRegisters() const
+    {
+        return isInJSValueRegs() || isInGPR() || isInFPR();
+    }
+
+    bool isInJSStack() const
+    {
+        switch (m_technique) {
+        case DisplacedInJSStack:
+        case Int32DisplacedInJSStack:
+        case Int52DisplacedInJSStack:
+        case StrictInt52DisplacedInJSStack:
+        case DoubleDisplacedInJSStack:
+        case CellDisplacedInJSStack:
+        case BooleanDisplacedInJSStack:
             return true;
         default:
             return false;
         }
     }
+
+    DataFormat dataFormat() const
+    {
+        switch (m_technique) {
+        case InGPR:
+        case InFPR:
+        case DisplacedInJSStack:
+        case Constant:
+#if USE(JSVALUE32_64)
+        case InPair:
+#endif
+            return DataFormatJS;
+        case UnboxedInt32InGPR:
+        case Int32DisplacedInJSStack:
+            return DataFormatInt32;
+        case UnboxedInt52InGPR:
+        case Int52DisplacedInJSStack:
+            return DataFormatInt52;
+        case UnboxedStrictInt52InGPR:
+        case StrictInt52DisplacedInJSStack:
+            return DataFormatStrictInt52;
+        case UnboxedBooleanInGPR:
+        case BooleanDisplacedInJSStack:
+            return DataFormatBoolean;
+        case UnboxedCellInGPR:
+        case CellDisplacedInJSStack:
+            return DataFormatCell;
+        case UnboxedDoubleInFPR:
+        case DoubleDisplacedInJSStack:
+            return DataFormatDouble;
+        default:
+            return DataFormatNone;
+        }
+    }
     
     MacroAssembler::RegisterID gpr() const
     {
-        ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR);
+        ASSERT(isInGPR());
         return m_source.gpr;
     }
     
@@ -227,17 +295,39 @@ public:
         ASSERT(m_technique == InPair);
         return m_source.pair.payloadGPR;
     }
+
+    bool isInJSValueRegs() const
+    {
+        return m_technique == InPair;
+    }
+
+    JSValueRegs jsValueRegs() const
+    {
+        ASSERT(isInJSValueRegs());
+        return JSValueRegs(tagGPR(), payloadGPR());
+    }
+#else
+    bool isInJSValueRegs() const
+    {
+        return isInGPR();
+    }
+
+    JSValueRegs jsValueRegs() const
+    {
+        ASSERT(isInGPR());
+        return JSValueRegs(gpr());
+    }
 #endif
     
     MacroAssembler::FPRegisterID fpr() const
     {
-        ASSERT(m_technique == InFPR);
+        ASSERT(isInFPR());
         return m_source.fpr;
     }
     
     VirtualRegister virtualRegister() const
     {
-        ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack || m_technique == Int52DisplacedInJSStack || m_technique == StrictInt52DisplacedInJSStack);
+        ASSERT(isInJSStack());
         return VirtualRegister(m_source.virtualReg);
     }
     
@@ -264,7 +354,7 @@ public:
     
     JSValue constant() const
     {
-        ASSERT(m_technique == Constant);
+        ASSERT(isConstant());
         return JSValue::decode(m_source.constant);
     }
     
index 0851a58..e1b72cf 100644 (file)
@@ -191,6 +191,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         const ValueRecovery& recovery = operands[index];
         
         switch (recovery.technique()) {
+        case UnboxedDoubleInFPR:
         case InFPR:
             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
             m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
@@ -252,6 +253,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         switch (recovery.technique()) {
         case InPair:
         case DisplacedInJSStack:
+        case InFPR:
             m_jit.load32(
                 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag,
                 GPRInfo::regT0);
@@ -266,7 +268,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
                 AssemblyHelpers::payloadFor(operand));
             break;
             
-        case InFPR:
+        case UnboxedDoubleInFPR:
         case DoubleDisplacedInJSStack:
             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
             m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
index 5bb0a4f..f547554 100644 (file)
@@ -209,6 +209,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         const ValueRecovery& recovery = operands[index];
         
         switch (recovery.technique()) {
+        case UnboxedDoubleInFPR:
         case InFPR:
             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
             m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));
@@ -265,6 +266,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
         case DisplacedInJSStack:
         case CellDisplacedInJSStack:
         case BooleanDisplacedInJSStack:
+        case InFPR:
             m_jit.load64(scratch + index, GPRInfo::regT0);
             m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
             break;
@@ -293,7 +295,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
             m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
             break;
             
-        case InFPR:
+        case UnboxedDoubleInFPR:
         case DoubleDisplacedInJSStack:
             m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);
             m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);
index 339ff09..be8e2a7 100644 (file)
@@ -209,7 +209,7 @@ void VariableEventStream::reconstruct(
         
         if (info.filled) {
             if (info.format == DataFormatDouble) {
-                valueRecoveries[i] = ValueRecovery::inFPR(info.u.fpr);
+                valueRecoveries[i] = ValueRecovery::inFPR(info.u.fpr, DataFormatDouble);
                 continue;
             }
 #if USE(JSVALUE32_64)