- rolled scope chain optimization out; it was breaking the world
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Jan 2008 19:47:21 +0000 (19:47 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Jan 2008 19:47:21 +0000 (19:47 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@29068 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/scope_chain.cpp
JavaScriptCore/kjs/scope_chain.h

index 91113dda97e21954aff7b2da9df7d63b0e2ccc0c..9a468e6b2c3d26a736f37ead44980bef61376a72 100644 (file)
@@ -1,3 +1,7 @@
+2008-01-01  Darin Adler  <darin@apple.com>
+
+        - rolled scope chain optimization out; it was breaking the world
+
 2008-01-01  Darin Adler  <darin@apple.com>
 
         Reviewed by Geoff.
index 28643bafd7977349dab675e7a3db6c9ca3033fd8..caa5a861d85f904f6c5745e22b3caf101129e10c 100644 (file)
@@ -592,6 +592,19 @@ inline void ScopeChain::mark()
     }
 }
 
+inline void ScopeChain::release()
+{
+    // This function is only called by deref(),
+    // Deref ensures these conditions are true.
+    ASSERT(_node && _node->refCount == 0);
+    ScopeChainNode *n = _node;
+    do {
+        ScopeChainNode *next = n->next;
+        delete n;
+        n = next;
+    } while (n && --n->refCount == 0);
+}
+
 inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
 {
     return defaultValue(exec, preferredType);
index 96f21ca80c9db43dd1ee1f56e658ddc8611eccf6..aba066ad1c068987531174f2262ee4b2808c68bb 100644 (file)
 
 namespace KJS {
 
+void ScopeChain::push(const ScopeChain &c)
+{
+    ScopeChainNode **tail = &_node;
+    for (ScopeChainNode *n = c._node; n; n = n->next) {
+        ScopeChainNode *newNode = new ScopeChainNode(*tail, n->object);
+        *tail = newNode;
+        tail = &newNode->next;
+    }
+}
+
 #ifndef NDEBUG
 
 void ScopeChain::print()
index 987bff81f93e93abcbffa965fde59e7502767b2a..a10abcdbba00eb2d903ff6113027ac3e514499ce 100644 (file)
 namespace KJS {
 
     class JSObject;
-    struct ScopeChainHeapNode;
+    class ExecState;
     
-    struct ScopeChainNode {
-        JSObject* object;
-        ScopeChainHeapNode* next;
-    };
+    class ScopeChainNode {
+    public:
+        ScopeChainNode(ScopeChainNode *n, JSObject *o)
+            : next(n), object(o), refCount(1) { }
 
-    struct ScopeChainHeapNode : ScopeChainNode {
+        ScopeChainNode *next;
+        JSObject *object;
         int refCount;
     };
 
@@ -64,7 +65,8 @@ namespace KJS {
         ScopeChain() : _node(0) { }
         ~ScopeChain() { deref(); }
 
-        ScopeChain(const ScopeChain&);
+        ScopeChain(const ScopeChain &c) : _node(c._node)
+            { if (_node) ++_node->refCount; }
         ScopeChain &operator=(const ScopeChain &);
 
         bool isEmpty() const { return !_node; }
@@ -77,6 +79,7 @@ namespace KJS {
 
         void clear() { deref(); _node = 0; }
         void push(JSObject *);
+        void push(const ScopeChain &);
         void pop();
         
         void mark();
@@ -86,65 +89,27 @@ namespace KJS {
 #endif
         
     private:
-        mutable ScopeChainNode* _node;
-        ScopeChainNode m_initialTopNode;
-
-        ScopeChainHeapNode* moveToHeap() const;
-
-        void deref();
+        ScopeChainNode *_node;
+        
+        void deref() { if (_node && --_node->refCount == 0) release(); }
         void ref() const;
+        
+        void release();
     };
 
-inline ScopeChainHeapNode* ScopeChain::moveToHeap() const
-{
-    if (_node != &m_initialTopNode)
-        return static_cast<ScopeChainHeapNode*>(_node);
-    ScopeChainHeapNode* heapNode = new ScopeChainHeapNode;
-    heapNode->object = m_initialTopNode.object;
-    heapNode->next = m_initialTopNode.next;
-    heapNode->refCount = 1;
-    _node = heapNode;
-    return heapNode;
-}
-
-inline ScopeChain::ScopeChain(const ScopeChain& otherChain)
-{
-    if (!otherChain._node)
-        _node = 0;
-    else {
-        ScopeChainHeapNode* top = otherChain.moveToHeap();
-        ++top->refCount;
-        _node = top;
-    }
-}
-
 inline void ScopeChain::ref() const
 {
-    ASSERT(_node != &m_initialTopNode);
-    for (ScopeChainHeapNode* n = static_cast<ScopeChainHeapNode*>(_node); n; n = n->next) {
-        if (n->refCount++)
+    for (ScopeChainNode *n = _node; n; n = n->next) {
+        if (n->refCount++ != 0)
             break;
     }
 }
 
-inline void ScopeChain::deref()
+inline ScopeChain &ScopeChain::operator=(const ScopeChain &c)
 {
-    ScopeChainHeapNode* node = static_cast<ScopeChainHeapNode*>(_node);
-    if (node == &m_initialTopNode)
-        node = node->next;
-    ScopeChainHeapNode* next;
-    for (; node && --node->refCount == 0; node = next) {
-        next = node->next;
-        delete node;
-    }
-}
-
-inline ScopeChain &ScopeChain::operator=(const ScopeChain& otherChain)
-{
-    otherChain.moveToHeap();
-    otherChain.ref();
+    c.ref();
     deref();
-    _node = otherChain._node;
+    _node = c._node;
     return *this;
 }
 
@@ -158,30 +123,24 @@ inline JSObject *ScopeChain::bottom() const
     return last->object;
 }
 
-inline void ScopeChain::push(JSObjecto)
+inline void ScopeChain::push(JSObject *o)
 {
     ASSERT(o);
-    ScopeChainHeapNode* heapNode = moveToHeap();
-    m_initialTopNode.object = o;
-    m_initialTopNode.next = heapNode;
-    _node = &m_initialTopNode;
+    _node = new ScopeChainNode(_node, o);
 }
 
 inline void ScopeChain::pop()
 {
     ScopeChainNode *oldNode = _node;
     ASSERT(oldNode);
-    ScopeChainHeapNode *newNode = oldNode->next;
+    ScopeChainNode *newNode = oldNode->next;
     _node = newNode;
-
-    if (oldNode != &m_initialTopNode) {
-        ScopeChainHeapNode* oldHeapNode = static_cast<ScopeChainHeapNode*>(oldNode);
-        if (--oldHeapNode->refCount != 0) {
-            if (newNode)
-                ++newNode->refCount;
-        } else {
-            delete oldHeapNode;
-        }
+    
+    if (--oldNode->refCount != 0) {
+        if (newNode)
+            ++newNode->refCount;
+    } else {
+        delete oldNode;
     }
 }