Title: [145401] trunk/Source
Revision
145401
Author
oli...@apple.com
Date
2013-03-11 14:02:39 -0700 (Mon, 11 Mar 2013)

Log Message

Make SegmentedVector Noncopyable
https://bugs.webkit.org/show_bug.cgi?id=112059

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

Copying a SegmentedVector is very expensive, and really shouldn't
be necessary.  So I've taken the one place where we currently copy
and replaced it with a regular Vector, and replaced the address
dependent logic with a indexing ref instead.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::newLabelScope):
(JSC::BytecodeGenerator::emitComplexJumpScopes):
* bytecompiler/BytecodeGenerator.h:
(BytecodeGenerator):
* bytecompiler/LabelScope.h:
(JSC):
(JSC::LabelScopePtr::LabelScopePtr):
(LabelScopePtr):
(JSC::LabelScopePtr::operator=):
(JSC::LabelScopePtr::~LabelScopePtr):
(JSC::LabelScopePtr::operator*):
(JSC::LabelScopePtr::operator->):
* bytecompiler/NodesCodegen.cpp:
(JSC::DoWhileNode::emitBytecode):
(JSC::WhileNode::emitBytecode):
(JSC::ForNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
(JSC::SwitchNode::emitBytecode):
(JSC::LabelNode::emitBytecode):

Source/WTF:

Copying a SegmentedVector can be extraordinarily expensive, so we beat
it with the Noncopyable stick - that way we can ensure that if anyone
wants an actual copy they know what they're doing.

* wtf/SegmentedVector.h:
(SegmentedVector):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (145400 => 145401)


--- trunk/Source/_javascript_Core/ChangeLog	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-03-11 21:02:39 UTC (rev 145401)
@@ -1,3 +1,36 @@
+2013-03-11  Oliver Hunt  <oli...@apple.com>
+
+        Make SegmentedVector Noncopyable
+        https://bugs.webkit.org/show_bug.cgi?id=112059
+
+        Reviewed by Geoffrey Garen.
+
+        Copying a SegmentedVector is very expensive, and really shouldn't
+        be necessary.  So I've taken the one place where we currently copy
+        and replaced it with a regular Vector, and replaced the address
+        dependent logic with a indexing ref instead.
+
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::newLabelScope):
+        (JSC::BytecodeGenerator::emitComplexJumpScopes):
+        * bytecompiler/BytecodeGenerator.h:
+        (BytecodeGenerator):
+        * bytecompiler/LabelScope.h:
+        (JSC):
+        (JSC::LabelScopePtr::LabelScopePtr):
+        (LabelScopePtr):
+        (JSC::LabelScopePtr::operator=):
+        (JSC::LabelScopePtr::~LabelScopePtr):
+        (JSC::LabelScopePtr::operator*):
+        (JSC::LabelScopePtr::operator->):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::DoWhileNode::emitBytecode):
+        (JSC::WhileNode::emitBytecode):
+        (JSC::ForNode::emitBytecode):
+        (JSC::ForInNode::emitBytecode):
+        (JSC::SwitchNode::emitBytecode):
+        (JSC::LabelNode::emitBytecode):
+
 2013-03-10  Andreas Kling  <akl...@apple.com>
 
         SpeculativeJIT should use OwnPtr<SlowPathGenerator>.

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (145400 => 145401)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2013-03-11 21:02:39 UTC (rev 145401)
@@ -639,7 +639,7 @@
     return result;
 }
 
-PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
+LabelScopePtr BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
 {
     // Reclaim free label scopes.
     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -648,7 +648,7 @@
     // Allocate new label scope.
     LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
     m_labelScopes.append(scope);
-    return &m_labelScopes.last();
+    return LabelScopePtr(&m_labelScopes, m_labelScopes.size() - 1);
 }
 
 PassRefPtr<Label> BytecodeGenerator::newLabel()
@@ -2281,7 +2281,7 @@
         Vector<SwitchInfo> savedSwitchContextStack;
         Vector<ForInContext> savedForInContextStack;
         Vector<TryContext> poppedTryContexts;
-        SegmentedVector<LabelScope, 8> savedLabelScopes;
+        LabelScopeStore savedLabelScopes;
         while (topScope > bottomScope && topScope->isFinallyBlock) {
             RefPtr<Label> beforeFinally = emitLabel(newLabel().get());
             

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (145400 => 145401)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2013-03-11 21:02:39 UTC (rev 145401)
@@ -331,7 +331,7 @@
             return dst == ignoredResult() ? 0 : (dst && dst != src) ? emitMove(dst, src) : src;
         }
 
-        PassRefPtr<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
+        LabelScopePtr newLabelScope(LabelScope::Type, const Identifier* = 0);
         PassRefPtr<Label> newLabel();
 
         // The emitNode functions are just syntactic sugar for calling
@@ -701,7 +701,7 @@
         SegmentedVector<RegisterID, 32> m_calleeRegisters;
         SegmentedVector<RegisterID, 32> m_parameters;
         SegmentedVector<Label, 32> m_labels;
-        SegmentedVector<LabelScope, 8> m_labelScopes;
+        LabelScopeStore m_labelScopes;
         RefPtr<RegisterID> m_lastVar;
         int m_finallyDepth;
         int m_dynamicScopeDepth;

Modified: trunk/Source/_javascript_Core/bytecompiler/LabelScope.h (145400 => 145401)


--- trunk/Source/_javascript_Core/bytecompiler/LabelScope.h	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/LabelScope.h	2013-03-11 21:02:39 UTC (rev 145401)
@@ -49,13 +49,6 @@
             , m_continueTarget(continueTarget)
         {
         }
-
-        void ref() { ++m_refCount; }
-        void deref()
-        {
-            --m_refCount;
-            ASSERT(m_refCount >= 0);
-        }
         int refCount() const { return m_refCount; }
 
         Label* breakTarget() const { return m_breakTarget.get(); }
@@ -66,6 +59,15 @@
         int scopeDepth() const { return m_scopeDepth; }
 
     private:
+        friend class LabelScopePtr;
+
+        void ref() { ++m_refCount; }
+        void deref()
+        {
+            --m_refCount;
+            ASSERT(m_refCount >= 0);
+        }
+
         int m_refCount;
         Type m_type;
         const Identifier* m_name;
@@ -74,6 +76,57 @@
         RefPtr<Label> m_continueTarget;
     };
 
+    typedef Vector<LabelScope, 8> LabelScopeStore;
+
+    class LabelScopePtr {
+    public:
+        LabelScopePtr()
+            : m_owner(0)
+            , m_index(0)
+        {
+        }
+        LabelScopePtr(LabelScopeStore* owner, size_t index)
+            : m_owner(owner)
+            , m_index(index)
+        {
+            m_owner->at(index).ref();
+        }
+
+        LabelScopePtr(const LabelScopePtr& other)
+            : m_owner(other.m_owner)
+            , m_index(other.m_index)
+        {
+            if (m_owner)
+                m_owner->at(m_index).ref();
+        }
+
+        const LabelScopePtr& operator=(const LabelScopePtr& other)
+        {
+            if (other.m_owner)
+                other.m_owner->at(other.m_index).ref();
+            if (m_owner)
+                m_owner->at(m_index).deref();
+            m_owner = other.m_owner;
+            m_index = other.m_index;
+            return *this;
+        }
+
+        ~LabelScopePtr()
+        {
+            if (m_owner)
+                m_owner->at(m_index).deref();
+        }
+
+        LabelScope& operator*() { ASSERT(m_owner); return m_owner->at(m_index); }
+        LabelScope* operator->() { ASSERT(m_owner); return &m_owner->at(m_index); }
+        const LabelScope& operator*() const { ASSERT(m_owner); return m_owner->at(m_index); }
+        const LabelScope* operator->() const { ASSERT(m_owner); return &m_owner->at(m_index); }
+
+    private:
+        LabelScopeStore* m_owner;
+        size_t m_index;
+    };
+
 } // namespace JSC
 
 #endif // LabelScope_h

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (145400 => 145401)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2013-03-11 21:02:39 UTC (rev 145401)
@@ -1594,7 +1594,7 @@
 
 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
 
     RefPtr<Label> topOfLoop = generator.newLabel();
     generator.emitLabel(topOfLoop.get());
@@ -1620,7 +1620,7 @@
 
 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
     RefPtr<Label> topOfLoop = generator.newLabel();
 
     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->columnNo());
@@ -1656,7 +1656,7 @@
 
 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
 
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
 
@@ -1701,7 +1701,7 @@
 
 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
 
     if (!m_lexpr->isLocation())
         return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
@@ -2010,7 +2010,7 @@
 {
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
     
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
 
     RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
@@ -2027,7 +2027,7 @@
 
     ASSERT(!generator.breakTarget(m_name));
 
-    RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
+    LabelScopePtr scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
     RegisterID* r0 = generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->breakTarget());

Modified: trunk/Source/WTF/ChangeLog (145400 => 145401)


--- trunk/Source/WTF/ChangeLog	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/WTF/ChangeLog	2013-03-11 21:02:39 UTC (rev 145401)
@@ -1,3 +1,17 @@
+2013-03-11  Oliver Hunt  <oli...@apple.com>
+
+        Make SegmentedVector Noncopyable
+        https://bugs.webkit.org/show_bug.cgi?id=112059
+
+        Reviewed by Geoffrey Garen.
+
+        Copying a SegmentedVector can be extraordinarily expensive, so we beat
+        it with the Noncopyable stick - that way we can ensure that if anyone
+        wants an actual copy they know what they're doing.
+
+        * wtf/SegmentedVector.h:
+        (SegmentedVector):
+
 2013-03-08  Benjamin Poulain  <benja...@webkit.org>
 
         [Mac] Add a feature flag for 'view-mode' Media Feature, disable it on Mac

Modified: trunk/Source/WTF/wtf/SegmentedVector.h (145400 => 145401)


--- trunk/Source/WTF/wtf/SegmentedVector.h	2013-03-11 21:01:53 UTC (rev 145400)
+++ trunk/Source/WTF/wtf/SegmentedVector.h	2013-03-11 21:02:39 UTC (rev 145401)
@@ -29,6 +29,7 @@
 #ifndef SegmentedVector_h
 #define SegmentedVector_h
 
+#include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
 
 namespace WTF {
@@ -104,6 +105,8 @@
     template <typename T, size_t SegmentSize, size_t InlineCapacity>
     class SegmentedVector {
         friend class SegmentedVectorIterator<T, SegmentSize, InlineCapacity>;
+        WTF_MAKE_NONCOPYABLE(SegmentedVector);
+
     public:
         typedef SegmentedVectorIterator<T, SegmentSize, InlineCapacity> Iterator;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to