source: webkit/trunk/JavaScriptCore/kjs/protect.h@ 13568

Last change on this file since 13568 was 13568, checked in by ggaren, 19 years ago

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.
  • Property svn:eol-style set to native
File size: 4.2 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 2004 Apple Computer, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23
24#ifndef _KJS_PROTECT_H_
25#define _KJS_PROTECT_H_
26
27#include "reference.h"
28#include "value.h"
29#include "collector.h"
30#include "JSLock.h"
31
32namespace KJS {
33
34 inline void gcProtect(JSValue *val)
35 {
36 Collector::protect(val);
37 }
38
39 inline void gcUnprotect(JSValue *val)
40 {
41 Collector::unprotect(val);
42 }
43
44 inline void gcProtectNullTolerant(JSValue *val)
45 {
46 if (val)
47 gcProtect(val);
48 }
49
50 inline void gcUnprotectNullTolerant(JSValue *val)
51 {
52 if (val)
53 gcUnprotect(val);
54 }
55
56 // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
57 // and the implicit conversion to raw pointer
58 template <class T> class ProtectedPtr {
59 public:
60 ProtectedPtr() : m_ptr(NULL) { }
61 ProtectedPtr(T *ptr);
62 ProtectedPtr(const ProtectedPtr &);
63 ~ProtectedPtr();
64
65 template <class U> ProtectedPtr(const ProtectedPtr<U> &);
66
67 T *get() const { return m_ptr; }
68 operator T *() const { return m_ptr; }
69 T *operator->() const { return m_ptr; }
70
71 bool operator!() const { return m_ptr == NULL; }
72
73 ProtectedPtr &operator=(const ProtectedPtr &);
74 ProtectedPtr &operator=(T *);
75
76 private:
77 T *m_ptr;
78 };
79
80 template <class T> ProtectedPtr<T>::ProtectedPtr(T *ptr)
81 : m_ptr(ptr)
82 {
83 if (ptr) {
84 JSLock lock;
85 gcProtect(ptr);
86 }
87 }
88
89 template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o)
90 : m_ptr(o.get())
91 {
92 if (T *ptr = m_ptr) {
93 JSLock lock;
94 gcProtect(ptr);
95 }
96 }
97
98 template <class T> ProtectedPtr<T>::~ProtectedPtr()
99 {
100 if (T *ptr = m_ptr) {
101 JSLock lock;
102 gcUnprotect(ptr);
103 }
104 }
105
106 template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o)
107 : m_ptr(o.get())
108 {
109 if (T *ptr = m_ptr) {
110 JSLock lock;
111 gcProtect(ptr);
112 }
113 }
114
115 template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o)
116 {
117 JSLock lock;
118 T *optr = o.m_ptr;
119 gcProtectNullTolerant(optr);
120 gcUnprotectNullTolerant(m_ptr);
121 m_ptr = optr;
122 return *this;
123 }
124
125 template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr)
126 {
127 JSLock lock;
128 gcProtectNullTolerant(optr);
129 gcUnprotectNullTolerant(m_ptr);
130 m_ptr = optr;
131 return *this;
132 }
133
134 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() == b.get(); }
135 template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b) { return a.get() == b; }
136 template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b) { return a == b.get(); }
137
138 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() != b.get(); }
139 template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b) { return a.get() != b; }
140 template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b) { return a != b.get(); }
141
142} // namespace
143
144#endif
Note: See TracBrowser for help on using the repository browser.