Title: [220852] trunk/Source/_javascript_Core
Revision
220852
Author
[email protected]
Date
2017-08-17 05:15:48 -0700 (Thu, 17 Aug 2017)

Log Message

[JSC] Avoid code bloating for iteration if block does not have "break"
https://bugs.webkit.org/show_bug.cgi?id=173228

Reviewed by Keith Miller.

Currently, we always emit code for breaked path when emitting for-of iteration.
But we can know that this breaked path can be used when emitting the bytecode.

This patch adds LabelScope::breakTargetMayBeBound(), which returns true if
the break label may be bound. We emit a breaked path only when it returns
true. This reduces bytecode bloating when using for-of iteration.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::Label::setLocation):
(JSC::BytecodeGenerator::newLabel):
(JSC::BytecodeGenerator::emitLabel):
(JSC::BytecodeGenerator::pushFinallyControlFlowScope):
(JSC::BytecodeGenerator::breakTarget):
(JSC::BytecodeGenerator::continueTarget):
(JSC::BytecodeGenerator::emitEnumeration):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/Label.h:
(JSC::Label::bind const):
(JSC::Label::hasOneRef const):
(JSC::Label::isBound const):
(JSC::Label::Label): Deleted.
* bytecompiler/LabelScope.h:
(JSC::LabelScope::hasOneRef const):
(JSC::LabelScope::breakTargetMayBeBound const):
* bytecompiler/NodesCodegen.cpp:
(JSC::ContinueNode::trivialTarget):
(JSC::ContinueNode::emitBytecode):
(JSC::BreakNode::trivialTarget):
(JSC::BreakNode::emitBytecode):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (220851 => 220852)


--- trunk/Source/_javascript_Core/ChangeLog	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-08-17 12:15:48 UTC (rev 220852)
@@ -1,3 +1,40 @@
+2017-08-17  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Avoid code bloating for iteration if block does not have "break"
+        https://bugs.webkit.org/show_bug.cgi?id=173228
+
+        Reviewed by Keith Miller.
+
+        Currently, we always emit code for breaked path when emitting for-of iteration.
+        But we can know that this breaked path can be used when emitting the bytecode.
+
+        This patch adds LabelScope::breakTargetMayBeBound(), which returns true if
+        the break label may be bound. We emit a breaked path only when it returns
+        true. This reduces bytecode bloating when using for-of iteration.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::Label::setLocation):
+        (JSC::BytecodeGenerator::newLabel):
+        (JSC::BytecodeGenerator::emitLabel):
+        (JSC::BytecodeGenerator::pushFinallyControlFlowScope):
+        (JSC::BytecodeGenerator::breakTarget):
+        (JSC::BytecodeGenerator::continueTarget):
+        (JSC::BytecodeGenerator::emitEnumeration):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/Label.h:
+        (JSC::Label::bind const):
+        (JSC::Label::hasOneRef const):
+        (JSC::Label::isBound const):
+        (JSC::Label::Label): Deleted.
+        * bytecompiler/LabelScope.h:
+        (JSC::LabelScope::hasOneRef const):
+        (JSC::LabelScope::breakTargetMayBeBound const):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ContinueNode::trivialTarget):
+        (JSC::ContinueNode::emitBytecode):
+        (JSC::BreakNode::trivialTarget):
+        (JSC::BreakNode::emitBytecode):
+
 2017-08-17  Csaba Osztrogonác  <[email protected]>
 
         ARM build fix after r220807 and r220834.

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (220851 => 220852)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-08-17 12:15:48 UTC (rev 220852)
@@ -70,13 +70,13 @@
         segmentedVector.removeLast();
 }
 
-void Label::setLocation(unsigned location)
+void Label::setLocation(BytecodeGenerator& generator, unsigned location)
 {
     m_location = location;
     
     unsigned size = m_unresolvedJumps.size();
     for (unsigned i = 0; i < size; ++i)
-        m_generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
+        generator.instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
 }
 
 void Variable::dump(PrintStream& out) const
@@ -1228,7 +1228,7 @@
     shrinkToFit(m_labels);
 
     // Allocate new label ID.
-    m_labels.append(*this);
+    m_labels.append();
     return m_labels.last();
 }
 
@@ -1242,7 +1242,7 @@
 void BytecodeGenerator::emitLabel(Label& l0)
 {
     unsigned newLabelIndex = instructions().size();
-    l0.setLocation(newLabelIndex);
+    l0.setLocation(*this, newLabelIndex);
 
     if (m_codeBlock->numberOfJumpTargets()) {
         unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
@@ -3836,8 +3836,6 @@
 
 FinallyContext* BytecodeGenerator::pushFinallyControlFlowScope(Label& finallyLabel)
 {
-    shrinkToFit(m_labelScopes);
-
     ControlFlowScope scope(ControlFlowScope::Finally, currentLexicalScopeIndex(), FinallyContext(m_currentFinallyContext, finallyLabel));
     m_controlFlowScopeStack.append(WTFMove(scope));
 
@@ -3857,7 +3855,7 @@
     return m_controlFlowScopeStack.takeLast().finallyContext;
 }
 
-RefPtr<LabelScope> BytecodeGenerator::breakTarget(const Identifier& name)
+LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
 {
     shrinkToFit(m_labelScopes);
 
@@ -3884,7 +3882,7 @@
     return nullptr;
 }
 
-RefPtr<LabelScope> BytecodeGenerator::continueTarget(const Identifier& name)
+LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
 {
     shrinkToFit(m_labelScopes);
 
@@ -4371,12 +4369,15 @@
             emitJump(loopStart.get());
         }
 
-        emitLabel(scope->breakTarget());
+        bool breakLabelIsBound = scope->breakTargetMayBeBound();
+        if (breakLabelIsBound)
+            emitLabel(scope->breakTarget());
+        popFinallyControlFlowScope();
+        if (breakLabelIsBound) {
+            // IteratorClose sequence for break-ed control flow.
+            emitIteratorClose(iterator.get(), node);
+        }
     }
-
-    // IteratorClose sequence for break-ed control flow.
-    popFinallyControlFlowScope();
-    emitIteratorClose(iterator.get(), node);
     emitLabel(loopDone.get());
 }
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (220851 => 220852)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-08-17 12:15:48 UTC (rev 220852)
@@ -898,8 +898,8 @@
         void popStructureForInScope(RegisterID* local);
         void invalidateForInContextForLocal(RegisterID* local);
 
-        RefPtr<LabelScope> breakTarget(const Identifier&);
-        RefPtr<LabelScope> continueTarget(const Identifier&);
+        LabelScope* breakTarget(const Identifier&);
+        LabelScope* continueTarget(const Identifier&);
 
         void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
         void endSwitch(uint32_t clauseCount, const Vector<Ref<Label>, 8>&, ExpressionNode**, Label& defaultLabel, int32_t min, int32_t range);

Modified: trunk/Source/_javascript_Core/bytecompiler/Label.h (220851 => 220852)


--- trunk/Source/_javascript_Core/bytecompiler/Label.h	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/bytecompiler/Label.h	2017-08-17 12:15:48 UTC (rev 220852)
@@ -40,17 +40,13 @@
     class Label {
     WTF_MAKE_NONCOPYABLE(Label);
     public:
-        explicit Label(BytecodeGenerator& generator)
-            : m_refCount(0)
-            , m_location(invalidLocation)
-            , m_generator(generator)
-        {
-        }
+        Label() = default;
 
-        void setLocation(unsigned);
+        void setLocation(BytecodeGenerator&, unsigned);
 
         int bind(int opcode, int offset) const
         {
+            m_bound = true;
             if (m_location == invalidLocation) {
                 m_unresolvedJumps.append(std::make_pair(opcode, offset));
                 return 0;
@@ -65,6 +61,7 @@
             ASSERT(m_refCount >= 0);
         }
         int refCount() const { return m_refCount; }
+        bool hasOneRef() const { return m_refCount == 1; }
 
         bool isForward() const { return m_location == invalidLocation; }
         
@@ -74,14 +71,16 @@
             return bind(0, 0);
         }
 
+        bool isBound() const { return m_bound; }
+
     private:
         typedef Vector<std::pair<int, int>, 8> JumpVector;
 
         static const unsigned invalidLocation = UINT_MAX;
 
-        int m_refCount;
-        unsigned m_location;
-        BytecodeGenerator& m_generator;
+        int m_refCount { 0 };
+        unsigned m_location { invalidLocation };
+        mutable bool m_bound { false };
         mutable JumpVector m_unresolvedJumps;
     };
 

Modified: trunk/Source/_javascript_Core/bytecompiler/LabelScope.h (220851 => 220852)


--- trunk/Source/_javascript_Core/bytecompiler/LabelScope.h	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/bytecompiler/LabelScope.h	2017-08-17 12:15:48 UTC (rev 220852)
@@ -63,7 +63,17 @@
         ASSERT(m_refCount >= 0);
     }
     int refCount() const { return m_refCount; }
+    bool hasOneRef() const { return m_refCount == 1; }
 
+    bool breakTargetMayBeBound() const
+    {
+        if (!hasOneRef())
+            return true;
+        if (!m_breakTarget->hasOneRef())
+            return true;
+        return m_breakTarget->isBound();
+    }
+
 private:
     int m_refCount;
     Type m_type;

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (220851 => 220852)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-08-17 10:02:08 UTC (rev 220851)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-08-17 12:15:48 UTC (rev 220852)
@@ -3076,7 +3076,7 @@
     if (generator.shouldEmitDebugHooks())
         return nullptr;
 
-    RefPtr<LabelScope> scope = generator.continueTarget(m_ident);
+    LabelScope* scope = generator.continueTarget(m_ident);
     ASSERT(scope);
 
     if (generator.labelScopeDepth() != scope->scopeDepth())
@@ -3087,7 +3087,7 @@
 
 void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
-    RefPtr<LabelScope> scope = generator.continueTarget(m_ident);
+    LabelScope* scope = generator.continueTarget(m_ident);
     ASSERT(scope);
 
     bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), *scope->continueTarget());
@@ -3107,7 +3107,7 @@
     if (generator.shouldEmitDebugHooks())
         return nullptr;
 
-    RefPtr<LabelScope> scope = generator.breakTarget(m_ident);
+    LabelScope* scope = generator.breakTarget(m_ident);
     ASSERT(scope);
 
     if (generator.labelScopeDepth() != scope->scopeDepth())
@@ -3118,7 +3118,7 @@
 
 void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
-    RefPtr<LabelScope> scope = generator.breakTarget(m_ident);
+    LabelScope* scope = generator.breakTarget(m_ident);
     ASSERT(scope);
 
     bool hasFinally = generator.emitJumpViaFinallyIfNeeded(scope->scopeDepth(), scope->breakTarget());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to