Ignore:
Timestamp:
Feb 28, 2011, 1:05:22 PM (14 years ago)
Author:
[email protected]
Message:

2011-02-28 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Make ScopeChainNode GC allocated
https://bugs.webkit.org/show_bug.cgi?id=55283

Simplify lifetime and other issues with the scopechain
by making it gc allocated. This allows us to simplify
function exit and unwinding, as well as making the
current iterative refcounting go away.

  • JavaScriptCore.exp:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::createActivation):
  • bytecode/StructureStubInfo.cpp:
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::generate): (JSC::BytecodeGenerator::BytecodeGenerator): (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall): (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
  • bytecompiler/BytecodeGenerator.h:
  • debugger/Debugger.cpp: (JSC::Recompiler::operator()):
  • debugger/DebuggerCallFrame.h: (JSC::DebuggerCallFrame::scopeChain):
  • interpreter/CachedCall.h: (JSC::CachedCall::CachedCall):
  • interpreter/CallFrame.h:
  • interpreter/Interpreter.cpp: (JSC::depth): (JSC::Interpreter::unwindCallFrame): (JSC::Interpreter::throwException): (JSC::Interpreter::execute): (JSC::Interpreter::executeCall): (JSC::Interpreter::executeConstruct): (JSC::Interpreter::privateExecute):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCallInitializeCallFrame): (JSC::JIT::compileOpCall):
  • jit/JITCall32_64.cpp: (JSC::JIT::compileOpCallInitializeCallFrame): (JSC::JIT::emit_op_ret): (JSC::JIT::emit_op_ret_object_or_this): (JSC::JIT::compileOpCall):
  • jit/JITOpcodes.cpp: (JSC::JIT::emit_op_end): (JSC::JIT::emit_op_ret): (JSC::JIT::emit_op_ret_object_or_this):
  • jit/JITOpcodes32_64.cpp: (JSC::JIT::emit_op_end):
  • jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION):
  • jit/JITStubs.h:
  • runtime/ArgList.cpp:
  • runtime/Completion.cpp: (JSC::evaluate):
  • runtime/Completion.h:
  • runtime/DateConversion.cpp:
  • runtime/Executable.cpp: (JSC::EvalExecutable::compileInternal): (JSC::ProgramExecutable::compileInternal): (JSC::FunctionExecutable::compileForCallInternal): (JSC::FunctionExecutable::compileForConstructInternal):
  • runtime/FunctionConstructor.cpp: (JSC::constructFunction):
  • runtime/GCActivityCallbackCF.cpp:
  • runtime/Identifier.cpp:
  • runtime/JSCell.h:
  • runtime/JSChunk.cpp: Added.
  • runtime/JSChunk.h: Added.
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction): (JSC::JSFunction::markChildren): (JSC::JSFunction::getCallData): (JSC::JSFunction::getOwnPropertySlot): (JSC::JSFunction::getConstructData):
  • runtime/JSFunction.h: (JSC::JSFunction::scope): (JSC::JSFunction::setScope):
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • runtime/JSGlobalData.h:
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): (JSC::JSGlobalObject::markChildren):
  • runtime/JSGlobalObject.h: (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): (JSC::JSGlobalObject::globalScopeChain):
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncEval):
  • runtime/JSLock.cpp:
  • runtime/JSNumberCell.cpp:
  • runtime/JSZombie.cpp:
  • runtime/MarkedBlock.cpp:
  • runtime/MarkedSpace.cpp:
  • runtime/PropertyNameArray.cpp:
  • runtime/ScopeChain.cpp: (JSC::ScopeChainNode::print): (JSC::ScopeChainNode::localDepth): (JSC::ScopeChainNode::markChildren):
  • runtime/ScopeChain.h: (JSC::ScopeChainNode::ScopeChainNode): (JSC::ScopeChainNode::createStructure): (JSC::ScopeChainNode::push): (JSC::ScopeChainNode::pop): (JSC::ScopeChainIterator::ScopeChainIterator): (JSC::ScopeChainIterator::operator*): (JSC::ScopeChainIterator::operator->): (JSC::ScopeChainIterator::operator++): (JSC::ScopeChainNode::begin): (JSC::ScopeChainNode::end): (JSC::ExecState::globalData): (JSC::ExecState::lexicalGlobalObject): (JSC::ExecState::globalThisValue):
  • runtime/ScopeChainMark.h:
  • wtf/DateMath.cpp:

2011-02-28 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Make ScopeChainNode GC allocated
https://bugs.webkit.org/show_bug.cgi?id=55283

Update WebCore to deal with the absence of the ScopeChain
class.

  • ForwardingHeaders/runtime/ScopeChain.h: Added.
  • bindings/js/JSHTMLElementCustom.cpp: (WebCore::JSHTMLElement::pushEventHandlerScope):
  • bindings/js/JSJavaScriptCallFrameCustom.cpp: (WebCore::JSJavaScriptCallFrame::scopeChain): (WebCore::JSJavaScriptCallFrame::scopeType):
  • bindings/js/JSLazyEventListener.cpp: (WebCore::JSLazyEventListener::initializeJSFunction):
  • bindings/js/JSMainThreadExecState.h: (WebCore::JSMainThreadExecState::evaluate):
  • bindings/js/JSNodeCustom.cpp: (WebCore::JSNode::pushEventHandlerScope):
  • bindings/js/JavaScriptCallFrame.cpp: (WebCore::JavaScriptCallFrame::scopeChain):
  • bindings/js/JavaScriptCallFrame.h:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/c/c_class.cpp:
  • bridge/c/c_runtime.cpp:
  • bridge/jni/JNIBridge.cpp:
  • bridge/qt/qt_runtime.cpp: (JSC::Bindings::QtConnectionObject::execute):
  • plugins/PluginViewNone.cpp:

2011-02-28 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Make ScopeChainNode GC allocated
https://bugs.webkit.org/show_bug.cgi?id=55283

More updates for the absence of the ScopeChain class

  • WebView/WebScriptDebugDelegate.mm: (-[WebScriptCallFrame scopeChain]):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/ScopeChain.h

    r77151 r79904  
    2222#define ScopeChain_h
    2323
    24 #include "WriteBarrier.h"
     24#include "JSCell.h"
    2525#include <wtf/FastAllocBase.h>
    2626
     
    3333    class ScopeChainIterator;
    3434   
    35     class ScopeChainNode {
    36         WTF_MAKE_FAST_ALLOCATED;
     35    class ScopeChainNode : public JSCell {
    3736    public:
    3837        ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
    39             : next(next)
    40             , object(object)
     38            : JSCell(globalData->scopeChainNodeStructure.get())
    4139            , globalData(globalData)
    42             , globalObject(globalObject)
    43             , globalThis(globalThis)
    44             , refCount(1)
     40            , next(*globalData, this, next)
     41            , object(*globalData, this, object)
     42            , globalObject(*globalData, this, globalObject)
     43            , globalThis(*globalData, this, globalThis)
    4544        {
    4645            ASSERT(globalData);
    4746            ASSERT(globalObject);
    4847        }
    49 #ifndef NDEBUG
    50         // Due to the number of subtle and timing dependent bugs that have occurred due
    51         // to deleted but still "valid" ScopeChainNodes we now deliberately clobber the
    52         // contents in debug builds.
    53         ~ScopeChainNode()
    54         {
    55             next = 0;
    56             globalData = 0;
    57             globalObject = 0;
    58             globalThis = 0;
    59         }
    60 #endif
    6148
    62         ScopeChainNode* next;
    63         DeprecatedPtr<JSObject> object;
    6449        JSGlobalData* globalData;
    65         JSGlobalObject* globalObject;
    66         JSObject* globalThis;
    67         int refCount;
    68 
    69         void deref() { ASSERT(refCount); if (--refCount == 0) { release();} }
    70         void ref() { ASSERT(refCount); ++refCount; }
    71         void release();
    72 
    73         // Before calling "push" on a bare ScopeChainNode, a client should
    74         // logically "copy" the node. Later, the client can "deref" the head
    75         // of its chain of ScopeChainNodes to reclaim all the nodes it added
    76         // after the logical copy, leaving nodes added before the logical copy
    77         // (nodes shared with other clients) untouched.
    78         ScopeChainNode* copy()
    79         {
    80             ref();
    81             return this;
    82         }
     50        WriteBarrier<ScopeChainNode> next;
     51        WriteBarrier<JSObject> object;
     52        WriteBarrier<JSGlobalObject> globalObject;
     53        WriteBarrier<JSObject> globalThis;
    8354
    8455        ScopeChainNode* push(JSObject*);
    8556        ScopeChainNode* pop();
    8657
    87         ScopeChainIterator begin() const;
    88         ScopeChainIterator end() const;
     58        ScopeChainIterator begin();
     59        ScopeChainIterator end();
     60
     61        int localDepth();
    8962
    9063#ifndef NDEBUG       
    91         void print() const;
     64        void print();
    9265#endif
     66       
     67        static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(CompoundType, StructureFlags), AnonymousSlotCount, 0); }
     68        virtual void markChildren(MarkStack&);
     69    private:
     70        static const unsigned StructureFlags = OverridesMarkChildren;
    9371    };
    9472
     
    9674    {
    9775        ASSERT(o);
    98         return new ScopeChainNode(this, o, globalData, globalObject, globalThis);
     76        return new (globalData) ScopeChainNode(this, o, globalData, globalObject.get(), globalThis.get());
    9977    }
    10078
     
    10280    {
    10381        ASSERT(next);
    104         ScopeChainNode* result = next;
    105 
    106         if (--refCount != 0)
    107             ++result->refCount;
    108         else
    109             delete this;
    110 
    111         return result;
    112     }
    113 
    114     inline void ScopeChainNode::release()
    115     {
    116         // This function is only called by deref(),
    117         // Deref ensures these conditions are true.
    118         ASSERT(refCount == 0);
    119         ScopeChainNode* n = this;
    120         do {
    121             ScopeChainNode* next = n->next;
    122             delete n;
    123             n = next;
    124         } while (n && --n->refCount == 0);
     82        return next.get();
    12583    }
    12684
    12785    class ScopeChainIterator {
    12886    public:
    129         ScopeChainIterator(const ScopeChainNode* node)
     87        ScopeChainIterator(ScopeChainNode* node)
    13088            : m_node(node)
    13189        {
    13290        }
    13391
    134         DeprecatedPtr<JSObject> const & operator*() const { return m_node->object; }
    135         DeprecatedPtr<JSObject> const * operator->() const { return &(operator*()); }
     92        WriteBarrier<JSObject> const & operator*() const { return m_node->object; }
     93        WriteBarrier<JSObject> const * operator->() const { return &(operator*()); }
    13694   
    137         ScopeChainIterator& operator++() { m_node = m_node->next; return *this; }
     95        ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; }
    13896
    13997        // postfix ++ intentionally omitted
     
    143101
    144102    private:
    145         const ScopeChainNode* m_node;
     103        DeprecatedPtr<ScopeChainNode> m_node;
    146104    };
    147105
    148     inline ScopeChainIterator ScopeChainNode::begin() const
     106    inline ScopeChainIterator ScopeChainNode::begin()
    149107    {
    150108        return ScopeChainIterator(this);
    151109    }
    152110
    153     inline ScopeChainIterator ScopeChainNode::end() const
     111    inline ScopeChainIterator ScopeChainNode::end()
    154112    {
    155113        return ScopeChainIterator(0);
    156114    }
    157115
    158     class NoScopeChain {};
    159 
    160     class ScopeChain {
    161         friend class JIT;
    162     public:
    163         ScopeChain(NoScopeChain)
    164             : m_node(0)
    165         {
    166         }
    167 
    168         ScopeChain(JSObject* o, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
    169             : m_node(new ScopeChainNode(0, o, globalData, globalObject, globalThis))
    170         {
    171         }
    172 
    173         ScopeChain(const ScopeChain& c)
    174             : m_node(c.m_node->copy())
    175         {
    176         }
    177 
    178         ScopeChain& operator=(const ScopeChain& c);
    179 
    180         explicit ScopeChain(ScopeChainNode* node)
    181             : m_node(node->copy())
    182         {
    183         }
    184 
    185         ~ScopeChain()
    186         {
    187             if (m_node)
    188                 m_node->deref();
    189 #ifndef NDEBUG
    190             m_node = 0;
    191 #endif
    192         }
    193 
    194         void swap(ScopeChain&);
    195 
    196         ScopeChainNode* node() const { return m_node; }
    197 
    198         JSObject* top() const { return m_node->object.get(); }
    199 
    200         ScopeChainIterator begin() const { return m_node->begin(); }
    201         ScopeChainIterator end() const { return m_node->end(); }
    202 
    203         void push(JSObject* o) { m_node = m_node->push(o); }
    204 
    205         void pop() { m_node = m_node->pop(); }
    206         void clear() { m_node->deref(); m_node = 0; }
    207        
    208         JSGlobalObject* globalObject() const { return m_node->globalObject; }
    209 
    210         void markAggregate(MarkStack&) const;
    211 
    212         // Caution: this should only be used if the codeblock this is being used
    213         // with needs a full scope chain, otherwise this returns the depth of
    214         // the preceeding call frame
    215         //
    216         // Returns the depth of the current call frame's scope chain
    217         int localDepth() const;
    218 
    219 #ifndef NDEBUG       
    220         void print() const { m_node->print(); }
    221 #endif
    222 
    223     private:
    224         ScopeChainNode* m_node;
    225     };
    226 
    227     inline void ScopeChain::swap(ScopeChain& o)
     116    ALWAYS_INLINE JSGlobalData& ExecState::globalData() const
    228117    {
    229         ScopeChainNode* tmp = m_node;
    230         m_node = o.m_node;
    231         o.m_node = tmp;
     118        ASSERT(scopeChain()->globalData);
     119        return *scopeChain()->globalData;
    232120    }
    233121
    234     inline ScopeChain& ScopeChain::operator=(const ScopeChain& c)
     122    ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const
    235123    {
    236         ScopeChain tmp(c);
    237         swap(tmp);
    238         return *this;
     124        return scopeChain()->globalObject.get();
     125    }
     126   
     127    ALWAYS_INLINE JSObject* ExecState::globalThisValue() const
     128    {
     129        return scopeChain()->globalThis.get();
    239130    }
    240131
Note: See TracChangeset for help on using the changeset viewer.