Title: [199686] trunk/Source/_javascript_Core
Revision
199686
Author
[email protected]
Date
2016-04-18 13:33:47 -0700 (Mon, 18 Apr 2016)

Log Message

ToThis should have a fast path based on type info flags
https://bugs.webkit.org/show_bug.cgi?id=156712

Reviewed by Geoffrey Garen.

Prior to this change, if we couldn't nail down the type of ToThis to something easy, we'd emit code
that would take slow path if the argument was not a final object. We'd end up taking that slow path
a lot.

This adds a type info flag for ToThis having non-obvious behavior and changes the DFG and FTL paths
to test this flag. This is a sub-1% speed-up on SunSpider and Octane.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileToThis):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::create):
* runtime/JSLexicalEnvironment.h:
(JSC::JSLexicalEnvironment::create):
* runtime/JSString.h:
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::overridesGetOwnPropertySlot):
(JSC::TypeInfo::interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero):
(JSC::TypeInfo::structureIsImmortal):
(JSC::TypeInfo::overridesToThis):
(JSC::TypeInfo::overridesGetPropertyNames):
(JSC::TypeInfo::prohibitsPropertyCaching):
(JSC::TypeInfo::getOwnPropertySlotIsImpure):
* runtime/StrictEvalActivation.h:
(JSC::StrictEvalActivation::create):
* runtime/Symbol.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (199685 => 199686)


--- trunk/Source/_javascript_Core/ChangeLog	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-04-18 20:33:47 UTC (rev 199686)
@@ -1,5 +1,42 @@
 2016-04-18  Filip Pizlo  <[email protected]>
 
+        ToThis should have a fast path based on type info flags
+        https://bugs.webkit.org/show_bug.cgi?id=156712
+
+        Reviewed by Geoffrey Garen.
+
+        Prior to this change, if we couldn't nail down the type of ToThis to something easy, we'd emit code
+        that would take slow path if the argument was not a final object. We'd end up taking that slow path
+        a lot.
+
+        This adds a type info flag for ToThis having non-obvious behavior and changes the DFG and FTL paths
+        to test this flag. This is a sub-1% speed-up on SunSpider and Octane.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileToThis):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::create):
+        * runtime/JSLexicalEnvironment.h:
+        (JSC::JSLexicalEnvironment::create):
+        * runtime/JSString.h:
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::overridesGetOwnPropertySlot):
+        (JSC::TypeInfo::interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero):
+        (JSC::TypeInfo::structureIsImmortal):
+        (JSC::TypeInfo::overridesToThis):
+        (JSC::TypeInfo::overridesGetPropertyNames):
+        (JSC::TypeInfo::prohibitsPropertyCaching):
+        (JSC::TypeInfo::getOwnPropertySlotIsImpure):
+        * runtime/StrictEvalActivation.h:
+        (JSC::StrictEvalActivation::create):
+        * runtime/Symbol.h:
+
+2016-04-18  Filip Pizlo  <[email protected]>
+
         Check to see how the perf bots react to megamorphic load being disabled.
 
         Rubber stamped by Chris Dumez.

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (199685 => 199686)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-04-18 20:33:47 UTC (rev 199686)
@@ -3842,10 +3842,11 @@
         
         MacroAssembler::JumpList slowCases;
         slowCases.append(m_jit.branchIfNotCell(thisValue.jsValueRegs()));
-        slowCases.append(m_jit.branch8(
-            MacroAssembler::NotEqual,
-            MacroAssembler::Address(thisValuePayloadGPR, JSCell::typeInfoTypeOffset()),
-            TrustedImm32(FinalObjectType)));
+        slowCases.append(
+            m_jit.branchTest8(                             
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(thisValuePayloadGPR, JSCell::typeInfoFlagsOffset()),
+                MacroAssembler::TrustedImm32(OverridesToThis)));
         m_jit.move(thisValuePayloadGPR, tempGPR);
         m_jit.move(thisValueTagGPR, tempTagGPR);
         J_JITOperation_EJ function;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (199685 => 199686)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-04-18 20:33:47 UTC (rev 199686)
@@ -3897,10 +3897,11 @@
         
         MacroAssembler::JumpList slowCases;
         slowCases.append(m_jit.branchIfNotCell(JSValueRegs(thisValueGPR)));
-        slowCases.append(m_jit.branch8(
-            MacroAssembler::NotEqual,
-            MacroAssembler::Address(thisValueGPR, JSCell::typeInfoTypeOffset()),
-            TrustedImm32(FinalObjectType)));
+        slowCases.append(
+            m_jit.branchTest8(                             
+                MacroAssembler::NonZero,
+                MacroAssembler::Address(thisValueGPR, JSCell::typeInfoFlagsOffset()),
+                MacroAssembler::TrustedImm32(OverridesToThis)));
         m_jit.move(thisValueGPR, tempGPR);
         J_JITOperation_EJ function;
         if (m_jit.graph().executableFor(node->origin.semantic)->isStrictMode())

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (199685 => 199686)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-04-18 20:33:47 UTC (rev 199686)
@@ -1461,7 +1461,11 @@
         
         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
         ValueFromBlock fastResult = m_out.anchor(value);
-        m_out.branch(isType(value, FinalObjectType), usually(continuation), rarely(slowCase));
+        m_out.branch(
+            m_out.testIsZero32(
+                m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
+                m_out.constInt32(OverridesToThis)),
+            usually(continuation), rarely(slowCase));
         
         m_out.appendTo(slowCase, continuation);
         J_JITOperation_EJ function;

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -356,7 +356,7 @@
         
 public:
     typedef JSSegmentedVariableObject Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesToThis;
 
     static JSGlobalObject* create(VM& vm, Structure* structure)
     {

Modified: trunk/Source/_javascript_Core/runtime/JSLexicalEnvironment.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/JSLexicalEnvironment.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/JSLexicalEnvironment.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -44,7 +44,7 @@
     
 public:
     typedef JSEnvironmentRecord Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesToThis;
 
     static JSLexicalEnvironment* create(
         VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable, JSValue initialValue)

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -82,7 +82,7 @@
     friend struct ThunkHelpers;
 
     typedef JSCell Base;
-    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
+    static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal | OverridesToThis;
 
     static const bool needsDestruction = true;
     static void destroy(JSCell*);

Modified: trunk/Source/_javascript_Core/runtime/JSTypeInfo.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/JSTypeInfo.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/JSTypeInfo.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -42,7 +42,8 @@
 static const unsigned OverridesGetOwnPropertySlot = 1 << 3;
 static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 4;
 static const unsigned StructureIsImmortal = 1 << 5;
-// There are two free bits at the end of the InlineTypeFlags.
+static const unsigned OverridesToThis = 1 << 6; // If this is false then this returns something other than 'this'. Non-object cells that are visible to JS have this set as do some exotic objects.
+// There is one free bit at the end of the InlineTypeFlags.
 
 static const unsigned ImplementsHasInstance = 1 << 8;
 static const unsigned OverridesGetPropertyNames = 1 << 9;
@@ -84,6 +85,7 @@
     static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
     bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
     bool structureIsImmortal() const { return isSetOnFlags1(StructureIsImmortal); }
+    bool overridesToThis() const { return isSetOnFlags1(OverridesToThis); }
     bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
     bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
     bool getOwnPropertySlotIsImpure() const { return isSetOnFlags2(GetOwnPropertySlotIsImpure); }

Modified: trunk/Source/_javascript_Core/runtime/StrictEvalActivation.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/StrictEvalActivation.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/StrictEvalActivation.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -33,7 +33,7 @@
 class StrictEvalActivation : public JSScope {
 public:
     typedef JSScope Base;
-    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord;
+    static const unsigned StructureFlags = Base::StructureFlags | IsEnvironmentRecord | OverridesToThis;
 
     static StrictEvalActivation* create(ExecState* exec, JSScope* currentScope)
     {

Modified: trunk/Source/_javascript_Core/runtime/Symbol.h (199685 => 199686)


--- trunk/Source/_javascript_Core/runtime/Symbol.h	2016-04-18 20:28:51 UTC (rev 199685)
+++ trunk/Source/_javascript_Core/runtime/Symbol.h	2016-04-18 20:33:47 UTC (rev 199686)
@@ -37,7 +37,7 @@
 class Symbol final : public JSCell {
 public:
     typedef JSCell Base;
-    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal | OverridesToThis;
 
     DECLARE_EXPORT_INFO;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to