[webkit-changes] cvs commit: WebCore/kwq KWQKHTMLPart.mm KWQPageState.mm KWQTimer.h KWQTimer.mm WebCoreBridge.mm WebCoreJavaScript.mm WebCoreScriptDebugger.mm

Maciej mjs at opensource.apple.com
Mon Sep 19 11:52:15 PDT 2005


mjs         05/09/19 11:52:14

  Modified:    .        ChangeLog
               khtml/dom dom_misc.h
               khtml/ecma kjs_events.cpp kjs_events.h kjs_proxy.cpp
                        kjs_traversal.cpp kjs_traversal.h kjs_window.cpp
                        kjs_window.h xmlhttprequest.cpp
               khtml/misc main_thread_malloc.cpp
               kwq      KWQKHTMLPart.mm KWQPageState.mm KWQTimer.h
                        KWQTimer.mm WebCoreBridge.mm WebCoreJavaScript.mm
                        WebCoreScriptDebugger.mm
  Log:
          Reviewed by Geoff.
  
  	- fixed <rdar://problem/4214783> REGRESSION: kjs_fast_malloc crash due to lack of locking on multiple threads (seen selecting volumes in the installer)
  
  	Make sure to lock using the InterpreterLock class in all places that need it
  	(including anything that uses the collector, the parser, the protect count hash table,
  	and anything that allocates via fast_malloc).
  
  	Added assertions to ensure that main_thread_malloc and friends are
  	only called on the main thread.
  
  	Also changed main_thread_free to schedule a free on the main
  	thread if called from a background thread. This contingency is
  	rare, but unavoidable in the case that JavaScript runs on
  	background threads, since then objects can be garbage collected on
  	any thread.
  
          Test cases added: Node, this is impossible to reproduce in Safari without the use of
  	PAC files.
  
          * Makefile.am:
          * khtml/dom/dom_misc.h:
          * khtml/ecma/kjs_events.cpp:
          (JSAbstractEventListener::handleEvent):
          (JSLazyEventListener::parseCode):
          (KJS::getDOMEvent):
          * khtml/ecma/kjs_events.h:
          * khtml/ecma/kjs_proxy.cpp:
          (KJSProxyImpl::~KJSProxyImpl):
          (KJSProxyImpl::evaluate):
          (KJSProxyImpl::clear):
          (KJSProxyImpl::createHTMLEventHandler):
          (KJSProxyImpl::initScript):
          * khtml/ecma/kjs_traversal.cpp:
          (JSNodeFilterCondition::acceptNode):
          * khtml/ecma/kjs_traversal.h:
          * khtml/ecma/kjs_window.cpp:
          (Window::clear):
          (ScheduledAction::execute):
          * khtml/ecma/kjs_window.h:
          * khtml/ecma/xmlhttprequest.cpp:
          (KJS::XMLHttpRequest::send):
          (KJS::XMLHttpRequest::abort):
          (KJS::XMLHttpRequest::slotFinished):
          * khtml/misc/main_thread_malloc.cpp:
          (khtml::main_thread_malloc):
          (khtml::main_thread_calloc):
          (khtml::main_thread_free):
          (khtml::main_thread_realloc):
          (khtml::initialize_scheduled_free_list):
          (khtml::drain_scheduled_free_list):
          (khtml::schedule_free_on_main_thread):
          (khtml::public_fREe):
          * kwq/KWQKHTMLPart.mm:
          (KWQKHTMLPart::bindingRootObject):
          (KWQKHTMLPart::windowScriptObject):
          (KWQKHTMLPart::saveLocationProperties):
          (KWQKHTMLPart::restoreLocationProperties):
          (KWQKHTMLPart::openURLFromPageCache):
          (KWQKHTMLPart::cleanupPluginRootObjects):
          * kwq/KWQPageState.mm:
          (-[KWQPageState clear]):
          * kwq/KWQTimer.h:
          * kwq/KWQTimer.mm:
          (-[KWQMainThreadPerformTarget initWithFunction:]):
          (-[KWQMainThreadPerformTarget callFunction:]):
          (QTimer::immediateSingleShotOnMainThread):
          * kwq/WebCoreBridge.mm:
          (-[WebCoreBridge saveDocumentToPageCache]):
          * kwq/WebCoreJavaScript.mm:
          (+[WebCoreJavaScript rootObjectClasses]):
          (+[WebCoreJavaScript garbageCollect]):
          * kwq/WebCoreScriptDebugger.mm:
          (-[WebCoreScriptCallFrame evaluateWebScript:]):
  
  Revision  Changes    Path
  1.132     +81 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.131
  retrieving revision 1.132
  diff -u -r1.131 -r1.132
  --- ChangeLog	18 Sep 2005 21:45:25 -0000	1.131
  +++ ChangeLog	19 Sep 2005 18:52:09 -0000	1.132
  @@ -1,3 +1,84 @@
  +2005-09-14  Maciej Stachowiak  <mjs at apple.com>
  +
  +        Reviewed by Geoff.
  +
  +	- fixed <rdar://problem/4214783> REGRESSION: kjs_fast_malloc crash due to lack of locking on multiple threads (seen selecting volumes in the installer)
  +
  +	Make sure to lock using the InterpreterLock class in all places that need it
  +	(including anything that uses the collector, the parser, the protect count hash table,
  +	and anything that allocates via fast_malloc).
  +
  +	Added assertions to ensure that main_thread_malloc and friends are
  +	only called on the main thread.
  +
  +	Also changed main_thread_free to schedule a free on the main
  +	thread if called from a background thread. This contingency is
  +	rare, but unavoidable in the case that JavaScript runs on
  +	background threads, since then objects can be garbage collected on
  +	any thread.
  +	
  +        Test cases added: Node, this is impossible to reproduce in Safari without the use of
  +	PAC files.
  +
  +        * Makefile.am:
  +        * khtml/dom/dom_misc.h:
  +        * khtml/ecma/kjs_events.cpp:
  +        (JSAbstractEventListener::handleEvent):
  +        (JSLazyEventListener::parseCode):
  +        (KJS::getDOMEvent):
  +        * khtml/ecma/kjs_events.h:
  +        * khtml/ecma/kjs_proxy.cpp:
  +        (KJSProxyImpl::~KJSProxyImpl):
  +        (KJSProxyImpl::evaluate):
  +        (KJSProxyImpl::clear):
  +        (KJSProxyImpl::createHTMLEventHandler):
  +        (KJSProxyImpl::initScript):
  +        * khtml/ecma/kjs_traversal.cpp:
  +        (JSNodeFilterCondition::acceptNode):
  +        * khtml/ecma/kjs_traversal.h:
  +        * khtml/ecma/kjs_window.cpp:
  +        (Window::clear):
  +        (ScheduledAction::execute):
  +        * khtml/ecma/kjs_window.h:
  +        * khtml/ecma/xmlhttprequest.cpp:
  +        (KJS::XMLHttpRequest::send):
  +        (KJS::XMLHttpRequest::abort):
  +        (KJS::XMLHttpRequest::slotFinished):
  +        * khtml/misc/main_thread_malloc.cpp:
  +        (khtml::main_thread_malloc):
  +        (khtml::main_thread_calloc):
  +        (khtml::main_thread_free):
  +        (khtml::main_thread_realloc):
  +        (khtml::initialize_scheduled_free_list):
  +        (khtml::drain_scheduled_free_list):
  +        (khtml::schedule_free_on_main_thread):
  +        (khtml::public_fREe):
  +        * kwq/KWQKHTMLPart.mm:
  +        (KWQKHTMLPart::bindingRootObject):
  +        (KWQKHTMLPart::windowScriptObject):
  +        (KWQKHTMLPart::saveLocationProperties):
  +        (KWQKHTMLPart::restoreLocationProperties):
  +        (KWQKHTMLPart::openURLFromPageCache):
  +        (KWQKHTMLPart::cleanupPluginRootObjects):
  +        * kwq/KWQPageState.mm:
  +        (-[KWQPageState clear]):
  +        * kwq/KWQTimer.h:
  +        * kwq/KWQTimer.mm:
  +        (-[KWQMainThreadPerformTarget initWithFunction:]):
  +        (-[KWQMainThreadPerformTarget callFunction:]):
  +        (QTimer::immediateSingleShotOnMainThread):
  +        * kwq/WebCoreBridge.mm:
  +        (-[WebCoreBridge saveDocumentToPageCache]):
  +        * kwq/WebCoreJavaScript.mm:
  +        (+[WebCoreJavaScript rootObjectClasses]):
  +        (+[WebCoreJavaScript garbageCollect]):
  +        * kwq/WebCoreScriptDebugger.mm:
  +        (-[WebCoreScriptCallFrame evaluateWebScript:]):
  +
  +2005-09-14  Maciej Stachowiak  <mjs at apple.com>
  +
  +=== WebCore-417 ===
  +
   2005-09-18  Eric Seidel  <eseidel at apple.com>
   
           No review needed, SVG build fix only.
  
  
  
  1.10      +5 -1      WebCore/khtml/dom/dom_misc.h
  
  Index: dom_misc.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/dom/dom_misc.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- dom_misc.h	11 May 2005 00:58:28 -0000	1.9
  +++ dom_misc.h	19 Sep 2005 18:52:10 -0000	1.10
  @@ -55,8 +55,12 @@
       // An implementation object will delete itself, if it has
       // no DOMObject referencing it, and deleteMe() returns true.
       unsigned int _ref;
  +
  +private:
  +  DomShared(const DomShared &);
  +  DomShared &operator=(const DomShared &);
   };
   
  -}; // namespace
  +} // namespace
   
   #endif
  
  
  
  1.62      +60 -74    WebCore/khtml/ecma/kjs_events.cpp
  
  Index: kjs_events.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_events.cpp,v
  retrieving revision 1.61
  retrieving revision 1.62
  diff -u -r1.61 -r1.62
  --- kjs_events.cpp	16 Sep 2005 22:42:05 -0000	1.61
  +++ kjs_events.cpp	19 Sep 2005 18:52:10 -0000	1.62
  @@ -18,8 +18,6 @@
    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    */
   
  -#include <kjs/protected_object.h> // temporary, remove after landing interpreter lock patch
  -
   #include "kjs_events.h"
   #include "kjs_events.lut.h"
   
  @@ -42,6 +40,7 @@
   using DOM::AtomicString;
   using DOM::ClipboardEventImpl;
   using DOM::DocumentImpl;
  +using DOM::DOMString;
   using DOM::EventImpl;
   using DOM::EventListenerEvent;
   using DOM::KeyboardEventImpl;
  @@ -87,7 +86,11 @@
     KJSProxy *proxy = 0;
     if (part)
         proxy = KJSProxy::proxy( part );
  +  if (!proxy)
  +    return;
   
  +  InterpreterLock lock;
  +  
     ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(proxy->interpreter());
     ExecState *exec = interpreter->globalExec();
     
  @@ -98,74 +101,65 @@
     handleEventFuncValue = listener->get(exec, "handleEvent");
     if (handleEventFuncValue->isObject()) {      
         handleEventFunc = static_cast<ObjectImp *>(handleEventFuncValue);
  -            
  +      
         if (handleEventFunc->implementsCall())
             hasHandleEvent = true;
     }
     
  -  if (proxy && (listener->implementsCall() || hasHandleEvent)) {
  -    ref();
  -
  -    List args;
  -    args.append(getDOMEvent(exec,evt));
  -
  -    Window *window = static_cast<Window*>(win);
  -    // Set the event we're handling in the Window object
  -    window->setCurrentEvent(evt);
  -    // ... and in the interpreter
  -    interpreter->setCurrentEvent(evt);
  -
  -    ObjectImp *thisObj;
  -    if (isWindowEvent) {
  -        thisObj = win;
  -    } else {
  -        Interpreter::lock();
  -        thisObj = static_cast<ObjectImp *>(getDOMNode(exec, evt->currentTarget()));
  -        Interpreter::unlock();
  -    }
  -
  -    Interpreter::lock();
  -    ValueImp *retval;
  -    if (hasHandleEvent)
  -        retval = handleEventFunc->call(exec, listener, args);
  -    else
  -        retval = listener->call(exec, thisObj, args);
  -    Interpreter::unlock();
  -
  -    window->setCurrentEvent( 0 );
  -    interpreter->setCurrentEvent( 0 );
  -#if APPLE_CHANGES
  -    if ( exec->hadException() ) {
  -        Interpreter::lock();
  -        char *message = exec->exception()->toObject(exec)->get(exec, messagePropertyName)->toString(exec).ascii();
  -        int lineNumber =  exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
  -        QString sourceURL;
  -        {
  -          // put this in a block to make sure UString is deallocated inside the lock
  -          UString uSourceURL = exec->exception()->toObject(exec)->get(exec, "sourceURL")->toString(exec);
  -          sourceURL = uSourceURL.qstring();
  -        }
  -        Interpreter::unlock();
  -        if (Interpreter::shouldPrintExceptions()) {
  -	    printf("(event handler):%s\n", message);
  -	}
  -        KWQ(part)->addMessageToConsole(message, lineNumber, sourceURL);
  -        exec->clearException();
  -    }
  -#else
  -    if ( exec->hadException() )
  -        exec->clearException();
  -#endif
  -
  -    else if (html)
  -    {
  -        QVariant ret = ValueToVariant(exec, retval);
  +  if (listener->implementsCall() || hasHandleEvent) {
  +      ref();
  +      
  +      List args;
  +      args.append(getDOMEvent(exec,evt));
  +      
  +      Window *window = static_cast<Window*>(win);
  +      // Set the event we're handling in the Window object
  +      window->setCurrentEvent(evt);
  +      // ... and in the interpreter
  +      interpreter->setCurrentEvent(evt);
  +      
  +      ObjectImp *thisObj;
  +      if (isWindowEvent) {
  +          thisObj = win;
  +      } else {
  +          thisObj = static_cast<ObjectImp *>(getDOMNode(exec, evt->currentTarget()));
  +      }
  +      
  +      ValueImp *retval;
  +      if (hasHandleEvent)
  +          retval = handleEventFunc->call(exec, listener, args);
  +      else
  +          retval = listener->call(exec, thisObj, args);
  +      
  +      window->setCurrentEvent( 0 );
  +      interpreter->setCurrentEvent( 0 );
  +      if ( exec->hadException() ) {
  +          char *message = exec->exception()->toObject(exec)->get(exec, messagePropertyName)->toString(exec).ascii();
  +          int lineNumber =  exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
  +          QString sourceURL;
  +          {
  +              // put this in a block to make sure UString is deallocated inside the lock
  +              UString uSourceURL = exec->exception()->toObject(exec)->get(exec, "sourceURL")->toString(exec);
  +              sourceURL = uSourceURL.qstring();
  +          }
  +          if (Interpreter::shouldPrintExceptions()) {
  +              printf("(event handler):%s\n", message);
  +          }
  +          KWQ(part)->addMessageToConsole(message, lineNumber, sourceURL);
  +          
  +          if (Interpreter::shouldPrintExceptions())
  +              printf("(event handler):%s\n", message);
  +          exec->clearException();
  +      } else if (html) {
  +          QVariant ret = ValueToVariant(exec, retval);
           if (ret.type() == QVariant::Bool && ret.toBool() == false)
               evt->preventDefault();
  -    }
  -    DOM::DocumentImpl::updateDocumentsRendering();
  -    deref();
  +      }
     }
  +  
  +  DOM::DocumentImpl::updateDocumentsRendering();
  +  
  +  deref();
   }
   
   DOM::DOMString JSAbstractEventListener::eventListenerType()
  @@ -302,19 +296,16 @@
         ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(proxy->interpreter());
         ExecState *exec = interpreter->globalExec();
   
  -      Interpreter::lock();
  -      //Constructor constr(Global::current().get("Function"));
  +      InterpreterLock lock;
         ObjectImp *constr = interpreter->builtinFunction();
         List args;
   
  -      static ProtectedValue eventString = String("event");
  +      static ProtectedPtr<ValueImp> eventString = String("event");
         UString sourceURL(part->m_url.url());
         args.append(eventString);
         args.append(String(code));
         listener = constr->construct(exec, args, sourceURL, lineNumber); // ### is globalExec ok ?
   
  -      Interpreter::unlock();
  -
         if (exec->hadException()) {
   	exec->clearException();
   
  @@ -330,10 +321,7 @@
           Interpreter::unlock();
           
           if (thisObj) {
  -          Interpreter::lock();
             static_cast<DOMNode*>(thisObj)->pushEventHandlerScope(exec, scope);
  -          Interpreter::unlock();
  -          
             listener->setScope(scope);
           }
         }
  @@ -555,7 +543,7 @@
       return Null();
     ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
   
  -  Interpreter::lock();
  +  InterpreterLock lock;
   
     DOMObject *ret = interp->getDOMObject(e);
     if (!ret) {
  @@ -575,8 +563,6 @@
       interp->putDOMObject(e, ret);
     }
   
  -  Interpreter::unlock();
  -
     return ret;
   }
   
  
  
  
  1.33      +5 -5      WebCore/khtml/ecma/kjs_events.h
  
  Index: kjs_events.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_events.h,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- kjs_events.h	31 Aug 2005 04:38:36 -0000	1.32
  +++ kjs_events.h	19 Sep 2005 18:52:10 -0000	1.33
  @@ -1,4 +1,3 @@
  -// -*- c-basic-offset: 2 -*-
   /*
    *  This file is part of the KDE libraries
    *  Copyright (C) 2001 Peter Kelly (pmk at post.com)
  @@ -19,13 +18,14 @@
    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    */
   
  -#ifndef _KJS_EVENTS_H_
  -#define _KJS_EVENTS_H_
  +#ifndef KJS_EVENTS_H
  +#define KJS_EVENTS_H
   
   #include "kjs_dom.h"
   #include "kjs_html.h"
   
   #include "dom/dom2_events.h"
  +#include <kjs/protect.h>
   
   namespace DOM {
       class ClipboardImpl;
  @@ -76,8 +76,8 @@
       virtual ObjectImp *windowObj() const;
       void clearWindowObj();
     protected:
  -    mutable ProtectedObject listener;
  -    ProtectedObject win;
  +    mutable ProtectedPtr<ObjectImp> listener;
  +    ProtectedPtr<ObjectImp> win;
     };
   
     class JSLazyEventListener : public JSEventListener {
  
  
  
  1.23      +13 -23    WebCore/khtml/ecma/kjs_proxy.cpp
  
  Index: kjs_proxy.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_proxy.cpp,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- kjs_proxy.cpp	8 Aug 2005 04:07:41 -0000	1.22
  +++ kjs_proxy.cpp	19 Sep 2005 18:52:11 -0000	1.23
  @@ -1,4 +1,3 @@
  -// -*- c-basic-offset: 2 -*-
   /*
    *  This file is part of the KDE libraries
    *  Copyright (C) 1999-2001 Harri Porten (porten at kde.org)
  @@ -30,6 +29,8 @@
   
   using namespace KJS;
   
  +using DOM::EventListener;
  +
   extern "C" {
     KJSProxy *kjs_html_init(KHTMLPart *khtmlpart);
   }
  @@ -75,20 +76,22 @@
   
   KJSProxyImpl::~KJSProxyImpl()
   {
  -  //kdDebug() << "KJSProxyImpl::~KJSProxyImpl deleting interpreter " << m_script << endl;
  +  InterpreterLock lock;
     delete m_script;
  +
   #ifndef NDEBUG
     s_count--;
     // If it was the last interpreter, we should have nothing left
   #ifdef KJS_DEBUG_MEM
  -  if ( s_count == 0 )
  +  if (s_count == 0)
       Interpreter::finalCheck();
   #endif
   #endif
   }
   
   QVariant KJSProxyImpl::evaluate(QString filename, int baseLine,
  -                                const QString&str, DOM::NodeImpl *n) {
  +                                const QString&str, DOM::NodeImpl *n) 
  +{
     // evaluate code. Returns the JS return value or an invalid QVariant
     // if there was none, an error occured or the type couldn't be converted.
   
  @@ -98,42 +101,32 @@
     // expected value in all cases.
     // See smart window.open policy for where this is used.
     bool inlineCode = filename.isNull();
  -  //kdDebug(6070) << "KJSProxyImpl::evaluate inlineCode=" << inlineCode << endl;
   
   #ifdef KJS_DEBUGGER
  -  // ###    KJSDebugWin::instance()->attach(m_script);
     if (inlineCode)
       filename = "(unknown file)";
     if (KJSDebugWin::instance())
       KJSDebugWin::instance()->setNextSourceInfo(filename,baseLine);
  -  //    KJSDebugWin::instance()->setMode(KJS::Debugger::Step);
  -#else
  -  Q_UNUSED(baseLine);
   #endif
   
     m_script->setInlineCode(inlineCode);
  -  KJS::ValueImp *thisNode = n ? Window::retrieve(m_part) : getDOMNode(m_script->globalExec(), n);
   
  -  KJS::Interpreter::lock();
  -  UString code( str );
  -  KJS::Interpreter::unlock();
  +  InterpreterLock lock;
   
  +  KJS::ValueImp *thisNode = n ? Window::retrieve(m_part) : getDOMNode(m_script->globalExec(), n);
  +  UString code(str);
     Completion comp = m_script->evaluate(filename, baseLine, code, thisNode);
  +
     bool success = ( comp.complType() == Normal ) || ( comp.complType() == ReturnValue );  
  -#ifdef KJS_DEBUGGER
  -    //    KJSDebugWin::instance()->setCode(QString::null);
  -#endif
   
     // let's try to convert the return value
     if (success && comp.value())
       return ValueToVariant(m_script->globalExec(), comp.value());
   
     if ( comp.complType() == Throw ) {
  -    KJS::Interpreter::lock();
       UString errorMessage = comp.value()->toString(m_script->globalExec());
       int lineNumber =  comp.value()->toObject(m_script->globalExec())->get(m_script->globalExec(), "line")->toInt32(m_script->globalExec());
       UString sourceURL = comp.value()->toObject(m_script->globalExec())->get(m_script->globalExec(), "sourceURL")->toString(m_script->globalExec());
  -    KJS::Interpreter::unlock();
   
   #if APPLE_CHANGES
       KWQ(m_part)->addMessageToConsole(errorMessage.qstring(), lineNumber, sourceURL.qstring());
  @@ -153,7 +146,6 @@
       KJSDebugWin *debugWin = KJSDebugWin::instance();
       if (debugWin && debugWin->currentScript() == m_script) {
           debugWin->setMode(KJSDebugWin::Stop);
  -//        debugWin->leaveSession();
       }
   #endif
       Window *win = Window::retrieveWindow(m_part);
  @@ -172,6 +164,7 @@
   #endif
   
     initScript();
  +  InterpreterLock lock;
     return KJS::Window::retrieveWindow(m_part)->getJSLazyEventListener(code,node,m_handlerLineno);
   }
   
  @@ -265,9 +258,8 @@
       return;
   
     // Build the global object - which is a Window instance
  -  KJS::Interpreter::lock();
  +  KJS::InterpreterLock lock;
     ObjectImp *globalObject( new Window(m_part) );
  -  KJS::Interpreter::unlock();
   
     // Create a KJS interpreter for this part
     m_script = new KJS::ScriptInterpreter(globalObject, m_part);
  @@ -276,9 +268,7 @@
     m_script->setDebuggingEnabled(m_debugEnabled);
   #endif
     //m_script->enableDebug();
  -  KJS::Interpreter::lock();
     globalObject->put(m_script->globalExec(), "debug", new TestFunctionImp(), Internal);
  -  KJS::Interpreter::unlock();
   
   #if APPLE_CHANGES
     QString userAgent = KWQ(m_part)->userAgent();
  
  
  
  1.17      +3 -1      WebCore/khtml/ecma/kjs_traversal.cpp
  
  Index: kjs_traversal.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_traversal.cpp,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- kjs_traversal.cpp	16 Aug 2005 00:47:45 -0000	1.16
  +++ kjs_traversal.cpp	19 Sep 2005 18:52:11 -0000	1.17
  @@ -1,4 +1,3 @@
  -// -*- c-basic-offset: 2 -*-
   /*
    *  This file is part of the KDE libraries
    *  Copyright (C) 2001 Peter Kelly (pmk at post.com)
  @@ -20,12 +19,14 @@
   
   #include "kjs_traversal.h"
   #include "kjs_traversal.lut.h"
  +
   #include "kjs_proxy.h"
   #include <dom/dom_node.h>
   #include <xml/dom_nodeimpl.h>
   #include <xml/dom_docimpl.h>
   #include <khtmlview.h>
   #include <kdebug.h>
  +#include <kjs/protect.h>
   
   using DOM::FilterNode;
   using DOM::NodeFilterImpl;
  @@ -322,6 +323,7 @@
       KHTMLPart *part = node->getDocument()->part();
       KJSProxy *proxy = KJSProxy::proxy(part);
       if (proxy && filter->implementsCall()) {
  +        InterpreterLock lock;
           ExecState *exec = proxy->interpreter()->globalExec();
           List args;
           args.append(getDOMNode(exec, node));
  
  
  
  1.11      +3 -3      WebCore/khtml/ecma/kjs_traversal.h
  
  Index: kjs_traversal.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_traversal.h,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- kjs_traversal.h	8 Aug 2005 04:07:41 -0000	1.10
  +++ kjs_traversal.h	19 Sep 2005 18:52:11 -0000	1.11
  @@ -23,7 +23,7 @@
   
   #include "kjs_dom.h"
   #include "dom/dom2_traversal.h"
  -#include <kjs/protected_object.h>
  +#include "kjs/protect.h"
   
   namespace DOM {
       class NodeFilterImpl;
  @@ -103,9 +103,9 @@
       virtual ~JSNodeFilterCondition() {}
       virtual short acceptNode(DOM::FilterNode) const;
     protected:
  -    ProtectedObject filter;
  +    ProtectedPtr<ObjectImp> filter;
     };
   
  -}; // namespace
  +} // namespace
   
   #endif
  
  
  
  1.179     +21 -28    WebCore/khtml/ecma/kjs_window.cpp
  
  Index: kjs_window.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.cpp,v
  retrieving revision 1.178
  retrieving revision 1.179
  diff -u -r1.178 -r1.179
  --- kjs_window.cpp	5 Sep 2005 23:10:18 -0000	1.178
  +++ kjs_window.cpp	19 Sep 2005 18:52:11 -0000	1.179
  @@ -1488,21 +1488,21 @@
   
   void Window::clear( ExecState *exec )
   {
  -  Interpreter::lock();
  +  InterpreterLock lock;
     if (m_returnValueSlot)
       if (ValueImp *returnValue = getDirect("returnValue"))
         *m_returnValueSlot = returnValue;
     kdDebug(6070) << "Window::clear " << this << endl;
     delete winq;
     winq = new WindowQObject(this);
  -  // Get rid of everything, those user vars could hold references to DOM nodes
  +
     clearProperties();
  -  // Really delete those properties, so that the DOM nodes get deref'ed
  +  // there's likely to be lots of garbage now
     Collector::collect();
  +
     // Now recreate a working global object for the next URL that will use us
     Interpreter *interpreter = KJSProxy::proxy( m_part )->interpreter();
     interpreter->initGlobalObject();
  -  Interpreter::unlock();
   }
   
   void Window::setCurrentEvent(EventImpl *evt)
  @@ -2044,43 +2044,36 @@
   void ScheduledAction::execute(Window *window)
   {
     ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
  -
  +  
     interpreter->setProcessingTimerCallback(true);
  -
  +  
     //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
     if (isFunction) {
       if (func->implementsCall()) {
         // #### check this
  -      Q_ASSERT( window->m_part );
  -      if ( window->m_part )
  -      {
  -        Interpreter *interpreter = KJSProxy::proxy( window->m_part )->interpreter();
  +      Q_ASSERT(window->m_part);
  +      if (window->m_part) {
  +        Interpreter *interpreter = KJSProxy::proxy(window->m_part)->interpreter();
           ExecState *exec = interpreter->globalExec();
  -        Q_ASSERT( window == interpreter->globalObject() );
  -        ObjectImp *obj( window );
  -	Interpreter::lock();
  -        func->call(exec,obj,args); // note that call() creates its own execution state for the func call
  -	Interpreter::unlock();
  -	if ( exec->hadException() ) {
  -#if APPLE_CHANGES
  -          Interpreter::lock();
  +        Q_ASSERT(window == interpreter->globalObject());
  +        ObjectImp *obj(window);
  +	InterpreterLock lock;
  +        func->call(exec, obj, args); // note that call() creates its own execution state for the func call
  +	if (exec->hadException()) {
             char *message = exec->exception()->toObject(exec)->get(exec, messagePropertyName)->toString(exec).ascii();
  -          int lineNumber =  exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
  -          Interpreter::unlock();
  +          int lineNumber = exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
   	  if (Interpreter::shouldPrintExceptions()) {
   	    printf("(timer):%s\n", message);
  -	  }
  -          KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
  -#endif
  +            
  +            KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
  +          }
   	  exec->clearException();
  -	}
  +        }
         }
       }
  -  }
  -  else {
  +  } else
       window->m_part->executeScript(code);
  -  }
  -
  +  
     // Update our document's rendering following the execution of the timeout callback.
     if (DocumentImpl *doc = window->m_part->xmlDocImpl())
       doc->updateRendering();
  
  
  
  1.53      +2 -2      WebCore/khtml/ecma/kjs_window.h
  
  Index: kjs_window.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.h,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- kjs_window.h	31 Aug 2005 04:38:37 -0000	1.52
  +++ kjs_window.h	19 Sep 2005 18:52:11 -0000	1.53
  @@ -27,7 +27,7 @@
   #include <qptrdict.h>
   
   #include "kjs_binding.h"
  -#include <kjs/protected_object.h>
  +#include <kjs/protect.h>
   
   class QTimer;
   class KHTMLView;
  @@ -191,7 +191,7 @@
       ScheduledAction(const QString &_code, bool _singleShot);
       void execute(Window *window);
   
  -    ProtectedObject func;
  +    ProtectedPtr<ObjectImp> func;
       List args;
       QString code;
       bool isFunction;
  
  
  
  1.42      +9 -4      WebCore/khtml/ecma/xmlhttprequest.cpp
  
  Index: xmlhttprequest.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/xmlhttprequest.cpp,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- xmlhttprequest.cpp	29 Aug 2005 21:29:13 -0000	1.41
  +++ xmlhttprequest.cpp	19 Sep 2005 18:52:11 -0000	1.42
  @@ -1,4 +1,3 @@
  -// -*- c-basic-offset: 2 -*-
   /*
    *  This file is part of the KDE libraries
    *  Copyright (C) 2004 Apple Computer, Inc.
  @@ -370,7 +369,10 @@
     }
   #endif
   
  -  gcProtect (this);
  +  {
  +    InterpreterLock lock;
  +    gcProtect(this);
  +  }
     
     qObject->connect( job, SIGNAL( result( KIO::Job* ) ),
   		    SLOT( slotFinished( KIO::Job* ) ) );
  @@ -408,8 +410,10 @@
     }
     aborted = true;
   
  -  if (hadJob)
  +  if (hadJob) {
  +    InterpreterLock lock;
       gcUnprotect(this);
  +  }
   }
   
   void XMLHttpRequest::setRequestHeader(const QString& name, const QString &value)
  @@ -554,7 +558,8 @@
       decoder = 0;
     }
   
  -  gcUnprotect (this);
  +  InterpreterLock lock;
  +  gcUnprotect(this);
   }
   
   void XMLHttpRequest::slotRedirection(KIO::Job*, const KURL& url)
  
  
  
  1.4       +57 -1     WebCore/khtml/misc/main_thread_malloc.cpp
  
  Index: main_thread_malloc.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/misc/main_thread_malloc.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- main_thread_malloc.cpp	2 Sep 2005 18:08:29 -0000	1.3
  +++ main_thread_malloc.cpp	19 Sep 2005 18:52:12 -0000	1.4
  @@ -239,21 +239,26 @@
   
   void *main_thread_malloc(size_t n)
   {
  +    assert(pthread_main_np());
       return malloc(n);
   }
   
   void *main_thread_calloc(size_t n_elements, size_t element_size)
   {
  +    assert(pthread_main_np());
       return calloc(n_elements, element_size);
   }
   
   void main_thread_free(void* p)
   {
  +    // it's ok to main_thread_free on a non-main thread - the actual
  +    // free will be scheduled on the main thread in that case.
       free(p);
   }
   
   void *main_thread_realloc(void* p, size_t n)
   {
  +    assert(pthread_main_np());
       return realloc(p, n);
   }
   
  @@ -1606,7 +1611,58 @@
     return m;
   }
   
  +
  +static pthread_once_t free_mutex_once = PTHREAD_ONCE_INIT;
  +static pthread_mutex_t free_mutex;
  +static int scheduled_free_size;
  +static int scheduled_free_capacity;
  +static int scheduled_free_list;
  +bool free_is_scheduled;
  +
  +static void initialize_scheduled_free_list()
  +{
  +    pthread_mutex_init(&free_mutex, NULL);
  +}
  +
  +static void drain_scheduled_free_list()
  +{
  +    pthread_mutex_lock(&free_mutex);
  +    if (free_is_scheduled) {
  +        for(int i = 0; i < scheduled_free_size; i++) {
  +            main_thread_free(scheduled_free_list[i]);
  +        }
  +        free(scheduled_free_list);
  +        scheduled_free_list = NULL;
  +        scheduled_free_size = 0;
  +        scheduled_free_capacity = 0;
  +        free_is_scheduled = false;
  +    }
  +    pthread_mutex_unlock(&free_mutex);
  +}
  +
  +static void schedule_free_on_main_thread(Void_t* m)
  +{
  +    pthread_once(&free_mutex_once, initialize_scheduled_free_list);
  +
  +    pthread_mutex_lock(&free_mutex);
  +    if (scheduled_free_size == scheduled_free_capacity) {
  +        scheduled_free_capacity = scheduled_free_capacity == 0 ? 16 : scheduled_free_capacity * 1.2;
  +        scheduled_free_list = (Void_t**)realloc(scheduled_free_list, sizeof(Void_t*) * scheduled_free_capacity);
  +    }
  +    scheduled_free_list[scheduled_free_size++] = m;
  +    if (!free_is_scheduled) {
  +        QTimer::immediateSingleShotOnMainThread(0, drain_scheduled_free_list);
  +        free_is_scheduled = true;
  +    }
  +    pthread_mutex_unlock(&free_mutex);
  +}
  +
   void public_fREe(Void_t* m) {
  +  if (!pthread_main_np()) {
  +      schedule_free_on_main_thread(m);
  +      return;
  +  }
  +
     if (MALLOC_PREACTION != 0) {
       return;
     }
  @@ -5452,7 +5508,7 @@
   
   #endif /* WIN32 */
   
  -#endif
  +#endif // NDEBUG
   
   }  /* end of namespace KJS */
   
  
  
  
  1.673     +15 -8     WebCore/kwq/KWQKHTMLPart.mm
  
  Index: KWQKHTMLPart.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.mm,v
  retrieving revision 1.672
  retrieving revision 1.673
  diff -u -r1.672 -r1.673
  --- KWQKHTMLPart.mm	16 Sep 2005 22:42:23 -0000	1.672
  +++ KWQKHTMLPart.mm	19 Sep 2005 18:52:12 -0000	1.673
  @@ -77,6 +77,7 @@
   
   #import <JavaScriptCore/identifier.h>
   #import <JavaScriptCore/property_map.h>
  +#import <JavaScriptCore/interpreter.h>
   #import <JavaScriptCore/runtime.h>
   #import <JavaScriptCore/runtime_root.h>
   #import <JavaScriptCore/WebScriptObjectPrivate.h>
  @@ -158,6 +159,7 @@
   using KIO::Job;
   
   using KJS::Interpreter;
  +using KJS::InterpreterLock;
   using KJS::Location;
   using KJS::SavedBuiltins;
   using KJS::SavedProperties;
  @@ -1420,6 +1422,7 @@
   KJS::Bindings::RootObject *KWQKHTMLPart::bindingRootObject()
   {
       if (!_bindingRoot) {
  +        InterpreterLock lock;
           _bindingRoot = new KJS::Bindings::RootObject(0);    // The root gets deleted by JavaScriptCore.
           KJS::ObjectImp *win = KJS::Window::retrieveWindow(this);
           _bindingRoot->setRootObjectImp (win);
  @@ -1432,6 +1435,7 @@
   WebScriptObject *KWQKHTMLPart::windowScriptObject()
   {
       if (!_windowScriptObject) {
  +        KJS::InterpreterLock lock;
           KJS::ObjectImp *win = KJS::Window::retrieveWindow(this);
           _windowScriptObject = KWQRetainNSRelease([[WebScriptObject alloc] _initWithObjectImp:win originExecutionContext:bindingRootObject() executionContext:bindingRootObject()]);
       }
  @@ -1505,9 +1509,8 @@
   {
       Window *window = Window::retrieveWindow(this);
       if (window) {
  -        Interpreter::lock();
  +        InterpreterLock lock;
           Location *location = window->location();
  -        Interpreter::unlock();
           location->saveProperties(*locationProperties);
       }
   }
  @@ -1523,9 +1526,8 @@
   {
       Window *window = Window::retrieveWindow(this);
       if (window) {
  -        Interpreter::lock();
  +        InterpreterLock lock;
           Location *location = window->location();
  -        Interpreter::unlock();
           location->restoreProperties(*locationProperties);
       }
   }
  @@ -1622,10 +1624,13 @@
       doc->setParseMode ([state parseMode]);
       
       updatePolicyBaseURL();
  -        
  -    restoreWindowProperties (windowProperties);
  -    restoreLocationProperties (locationProperties);
  -    restoreInterpreterBuiltins (*interpreterBuiltins);
  +
  +    { // scope the lock
  +        InterpreterLock lock;
  +        restoreWindowProperties (windowProperties);
  +        restoreLocationProperties (locationProperties);
  +        restoreInterpreterBuiltins (*interpreterBuiltins);
  +    }
   
       if (actions)
           resumeActions (actions, state);
  @@ -3911,6 +3916,8 @@
   
   void KWQKHTMLPart::cleanupPluginRootObjects()
   {
  +    InterpreterLock lock;
  +
       KJS::Bindings::RootObject *root;
       while ((root = rootObjects.getLast())) {
           root->removeAllNativeReferences ();
  
  
  
  1.19      +7 -0      WebCore/kwq/KWQPageState.mm
  
  Index: KWQPageState.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPageState.mm,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- KWQPageState.mm	24 May 2005 17:44:19 -0000	1.18
  +++ KWQPageState.mm	19 Sep 2005 18:52:13 -0000	1.19
  @@ -25,6 +25,7 @@
   
   #import "KWQPageState.h"
   
  +#import <JavaScriptCore/interpreter.h>
   #import <JavaScriptCore/property_map.h>
   
   #import "dom_docimpl.h"
  @@ -39,6 +40,8 @@
   
   using khtml::RenderObject;
   
  +using KJS::Interpreter;
  +using KJS::InterpreterLock;
   using KJS::SavedProperties;
   using KJS::SavedBuiltins;
   
  @@ -96,12 +99,16 @@
   
       delete URL;
       URL = 0;
  +
  +    InterpreterLock lock;
  +
       delete windowProperties;
       windowProperties = 0;
       delete locationProperties;
       locationProperties = 0;
       delete interpreterBuiltins;
       interpreterBuiltins = 0;
  +
       [self _cleanupPausedActions];
   }
   
  
  
  
  1.12      +2 -0      WebCore/kwq/KWQTimer.h
  
  Index: KWQTimer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQTimer.h,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- KWQTimer.h	3 Jul 2005 10:13:51 -0000	1.11
  +++ KWQTimer.h	19 Sep 2005 18:52:13 -0000	1.12
  @@ -47,6 +47,8 @@
       
       static void singleShot(int msec, QObject *receiver, const char *member);
       
  +    static void immediateSingleShotOnMainThread(void (*func)());
  +
       // This is just a hack used by KWQKHTMLPart. The monitor function
       // gets called when the timer starts and when it is stopped before firing,
       // but not when the timer fires.
  
  
  
  1.17      +30 -0     WebCore/kwq/KWQTimer.mm
  
  Index: KWQTimer.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQTimer.mm,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- KWQTimer.mm	3 Jul 2005 10:13:51 -0000	1.16
  +++ KWQTimer.mm	19 Sep 2005 18:52:13 -0000	1.17
  @@ -161,3 +161,33 @@
                                       repeats:NO];
   }
   
  + at interface KWQMainThreadPerformTarget : NSObject
  +{
  +    void (*_func)();
  +}
  +
  +- (id)initWithFunction:(void (*)())func;
  +- (void)callFunction:(id)ignore;
  + at end
  +
  + at implementation KWQMainThreadPerformTarget
  +- (id)initWithFunction:(void (*)())func
  +{
  +    if ((self = [super init])) {
  +        _func = func;
  +    }
  +    return self;
  +}
  +
  +- (void)callFunction:(id)ignore
  +{
  +    _func();
  +}
  +
  + at end
  +
  +void QTimer::immediateSingleShotOnMainThread(void (*func)())
  +{
  +    [[[KWQMainThreadPerformTarget alloc] initWithFunction:func] performSelectorOnMainThread:@selector(callFunction) withObject:nil waitUntilDone:NO];
  +}
  +
  
  
  
  1.415     +7 -2      WebCore/kwq/WebCoreBridge.mm
  
  Index: WebCoreBridge.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreBridge.mm,v
  retrieving revision 1.414
  retrieving revision 1.415
  diff -u -r1.414 -r1.415
  --- WebCoreBridge.mm	16 Sep 2005 22:42:24 -0000	1.414
  +++ WebCoreBridge.mm	19 Sep 2005 18:52:13 -0000	1.415
  @@ -56,11 +56,12 @@
   #import "visible_units.h"
   #import "xml_tokenizer.h"
   
  -#import <JavaScriptCore/npruntime.h>
  +#import <JavaScriptCore/interpreter.h>
   #import <JavaScriptCore/jni_jsobject.h>
  +#import <JavaScriptCore/npruntime.h>
   #import <JavaScriptCore/object.h>
  -#import <JavaScriptCore/runtime_root.h>
   #import <JavaScriptCore/property_map.h>
  +#import <JavaScriptCore/runtime_root.h>
   
   #import "KWQAssertions.h"
   #import "KWQCharsets.h"
  @@ -131,6 +132,8 @@
   using khtml::VisiblePosition;
   
   using KJS::ExecState;
  +using KJS::Interpreter;
  +using KJS::InterpreterLock;
   using KJS::ObjectImp;
   using KJS::SavedProperties;
   using KJS::SavedBuiltins;
  @@ -462,6 +465,8 @@
       }
       _part->clearTimers();
   
  +    InterpreterLock lock;
  +
       SavedProperties *windowProperties = new SavedProperties;
       _part->saveWindowProperties(windowProperties);
   
  
  
  
  1.8       +4 -6      WebCore/kwq/WebCoreJavaScript.mm
  
  Index: WebCoreJavaScript.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreJavaScript.mm,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- WebCoreJavaScript.mm	21 Dec 2003 20:40:23 -0000	1.7
  +++ WebCoreJavaScript.mm	19 Sep 2005 18:52:13 -0000	1.8
  @@ -30,6 +30,7 @@
   
   using KJS::Collector;
   using KJS::Interpreter;
  +using KJS::InterpreterLock;
   
   @implementation WebCoreJavaScript
   
  @@ -55,17 +56,14 @@
   
   + (NSSet *)rootObjectClasses
   {
  -    Interpreter::lock();
  -    NSSet *classes = (NSSet *)Collector::rootObjectClasses();
  -    Interpreter::unlock();
  -    return [classes autorelease];
  +    InterpreterLock lock;
  +    return [(NSSet *)Collector::rootObjectClasses() autorelease];
   }
   
   + (void)garbageCollect
   {
  -    Interpreter::lock();
  +    InterpreterLock lock;
       while (Collector::collect()) { }
  -    Interpreter::unlock();
   }
   
   + (BOOL)shouldPrintExceptions
  
  
  
  1.3       +1 -2      WebCore/kwq/WebCoreScriptDebugger.mm
  
  Index: WebCoreScriptDebugger.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreScriptDebugger.mm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WebCoreScriptDebugger.mm	8 Aug 2005 04:07:46 -0000	1.2
  +++ WebCoreScriptDebugger.mm	19 Sep 2005 18:52:13 -0000	1.3
  @@ -335,11 +335,10 @@
       // evaluate
       ValueImp *result;
       if (eval) {
  -        Interpreter::lock();
  +        InterpreterLock lock;
           List args;
           args.append(String(code));
           result = eval->call(state, NULL, args);
  -        Interpreter::unlock();
       }
       else {
           // no "eval", or no context (i.e. global scope) - use global fallback
  
  
  



More information about the webkit-changes mailing list