Changeset 13568 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Mar 29, 2006, 6:39:24 PM (19 years ago)
Author:
ggaren
Message:

JavaScriptCore:

Reviewed by Darin.

  • JavaScriptCore side of fix for <rdar://problem/4308243> 8F36 Regression: crash in malloc_consolidate if you use a .PAC file

The crash was a result of threaded deallocation of thread-unsafe
objects. Pure JS objects are thread-safe because all JS execution
is synchronized through JSLock. However, JS objects that wrap WebCore
objects are thread-unsafe because JS and WebCore execution are not
synchronized. That unsafety comes into play when the collector
deallocates a JS object that wraps a WebCore object, thus causing the
WebCore object to be deallocated.

The solution here is to have each JSCell know whether it is safe to
collect on a non-main thread, and to avoid collecting unsafe cells
when on a non-main thread.

We don't have a way to test PAC files yet, so there's no test
attached to this patch.

  • kjs/collector.cpp: (KJS::Collector::collect):
(1) Added the test "currentThreadIsMainThread

imp->m_destructorIsThreadSafe".

  • kjs/protect.h: (KJS::gcProtectNullTolerant): (KJS::gcUnprotectNullTolerant):
  • kjs/value.h: (KJS::JSCell::JSCell): The bools here must be bitfields, otherwise m_destructorIsThreadSafe becomes another whole word, ruining the collector optimizations we've made based on the size of a JSObject.
  • kxmlcore/FastMalloc.cpp: (KXMLCore::currentThreadIsMainThread): (KXMLCore::fastMallocRegisterThread):
  • kxmlcore/FastMalloc.h:

WebCore:

Reviewed by Hyatt.

  • css/html4.css: Added default style info for new text fields.
  • rendering/RenderTextField.cpp: (WebCore::RenderTextField::createDivStyle): Added an extra 1px of padding on the left & right to match Win IE & the latest Mozilla. (WebCore::RenderTextField::updateFromElement): Removed some outdated comments. Cleaned up the way we add text nodes to the div. (WebCore::RenderTextField::setSelectionStart): Tweaked selection code to better match Mozilla behavior. (WebCore::RenderTextField::setSelectionEnd): ditto. (WebCore::RenderTextField::select): Cleaned this up by having it call setSelectionRange. (WebCore::RenderTextField::setSelectionRange): Calls updateLayout now in case this is called in an onload handler, and no other layout has occurred. (WebCore::RenderTextField::calcMinMaxWidth): Use floatWidth to calculate the width of the "0" character.
  • rendering/RenderTheme.cpp: (WebCore::RenderTheme::isControlStyled): If the text field's specified border is different from the default border, then treat the control as styled, so the engine knows to turn off the aqua appearance.
  • rendering/RenderThemeMac.mm: (WebCore::RenderThemeMac::paintTextField): return false so the engine knows not to try to draw the border. (WebCore::RenderThemeMac::adjustTextFieldStyle): text field style info has been moved to html4.css. We also add intrinsic margins here if the font size is large enough.
  • html/HTMLTextFieldInnerElement.cpp: (WebCore::HTMLTextFieldInnerElement::defaultEventHandler): No longer check for appearance. All text fields with m_type == TEXT will use the new implementation.
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::isKeyboardFocusable): ditto. (WebCore::HTMLInputElement::focus): ditto. (WebCore::HTMLInputElement::selectionStart): ditto. (WebCore::HTMLInputElement::selectionEnd): ditto. (WebCore::HTMLInputElement::setSelectionStart): ditto. (WebCore::HTMLInputElement::setSelectionEnd): ditto. (WebCore::HTMLInputElement::select): ditto. (WebCore::HTMLInputElement::setSelectionRange): ditto. (WebCore::HTMLInputElement::createRenderer): ditto. (WebCore::HTMLInputElement::defaultEventHandler): ditto. (WebCore::HTMLInputElement::isMouseFocusable): Added. Old text fields relied on the widget to provide a focus policy. A text field that is focusable should be mouse focusable, and shouldn't need to ask the base class.
  • html/HTMLInputElement.h: Added isMouseFocusable.
  • html/HTMLGenericFormElement.cpp: (WebCore::HTMLGenericFormElement::isMouseFocusable): Removed specific text field code since that is now done in HTMLInputElement::isMouseFocusable.
  • dom/Document.cpp: (WebCore::Document::clearSelectionIfNeeded): Check that the new selection is does not have a shadowAncestorNode that is focused.
Location:
trunk/JavaScriptCore/kjs
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/collector.cpp

    r13089 r13568  
    444444    InterpreterImp *scr = InterpreterImp::s_hook;
    445445    do {
    446       //fprintf( stderr, "Collector marking interpreter %p\n",(void*)scr);
    447446      scr->mark();
    448447      scr = scr->next;
     
    461460  size_t numLiveObjects = heap.numLiveObjects;
    462461
     462#if USE(MULTIPLE_THREADS)
     463  bool currentThreadIsMainThread = !pthread_is_threaded_np() || pthread_main_np();
     464#else
     465  bool currentThreadIsMainThread = true;
     466#endif
     467 
    463468  for (size_t block = 0; block < heap.usedBlocks; block++) {
    464469    CollectorBlock *curBlock = heap.blocks[block];
     
    474479        if (imp->m_marked) {
    475480          imp->m_marked = false;
    476         } else {
     481        } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe) {
    477482          imp->~JSCell();
    478483          --usedCells;
     
    495500          if (imp->m_marked) {
    496501            imp->m_marked = false;
    497           } else {
     502          } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe) {
    498503            imp->~JSCell();
    499504            --usedCells;
  • trunk/JavaScriptCore/kjs/object.h

    r13465 r13568  
    118118     * @param proto The prototype
    119119     */
    120     JSObject(JSObject *proto);
     120    JSObject(JSObject *proto, bool destructorIsThreadSafe = true);
    121121
    122122    /**
     
    124124     * (that is, the ECMAScript "null" value, not a null object pointer).
    125125     */
    126     JSObject();
     126    explicit JSObject(bool destructorIsThreadSafe = true);
    127127
    128128    virtual void mark();
     
    580580JSObject *throwError(ExecState *, ErrorType);
    581581
    582 inline JSObject::JSObject(JSObject *proto)
    583     : _proto(proto), _internalValue(0)
     582inline JSObject::JSObject(JSObject *proto, bool destructorIsThreadSafe)
     583    : JSCell(destructorIsThreadSafe)
     584    , _proto(proto)
     585    , _internalValue(0)
    584586{
    585587    assert(proto);
    586588}
    587589
    588 inline JSObject::JSObject()
    589     : _proto(jsNull()), _internalValue(0)
     590inline JSObject::JSObject(bool destructorIsThreadSafe)
     591    : JSCell(destructorIsThreadSafe)
     592    , _proto(jsNull())
     593    , _internalValue(0)
    590594{
    591595}
  • trunk/JavaScriptCore/kjs/protect.h

    r12301 r13568  
    4444    inline void gcProtectNullTolerant(JSValue *val)
    4545    {
    46         if (val) gcProtect(val);
     46        if (val)
     47            gcProtect(val);
    4748    }
    4849
    4950    inline void gcUnprotectNullTolerant(JSValue *val)
    5051    {
    51         if (val) gcUnprotect(val);
     52        if (val)
     53            gcUnprotect(val);
    5254    }
    5355   
  • trunk/JavaScriptCore/kjs/value.h

    r12949 r13568  
    122122    friend class GetterSetterImp;
    123123private:
    124     JSCell();
     124    explicit JSCell(bool destructorIsThreadSafe = true);
    125125    virtual ~JSCell();
    126126public:
     
    156156
    157157private:
    158     bool m_marked;
     158    bool m_destructorIsThreadSafe : 1;
     159    bool m_marked : 1;
    159160};
    160161
     
    209210}
    210211
    211 inline JSCell::JSCell()
    212     : m_marked(false)
     212inline JSCell::JSCell(bool destructorIsThreadSafe)
     213    : m_destructorIsThreadSafe(destructorIsThreadSafe)
     214    , m_marked(false)
    213215{
    214216}
Note: See TracChangeset for help on using the changeset viewer.