Changeset 13568 in webkit
- Timestamp:
- Mar 29, 2006 6:39:24 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r13541 r13568 1 2006-03-29 Geoffrey Garen <ggaren@apple.com> 2 3 Reviewed by Darin. 4 5 - JavaScriptCore side of fix for <rdar://problem/4308243> 8F36 6 Regression: crash in malloc_consolidate if you use a .PAC file 7 8 The crash was a result of threaded deallocation of thread-unsafe 9 objects. Pure JS objects are thread-safe because all JS execution 10 is synchronized through JSLock. However, JS objects that wrap WebCore 11 objects are thread-unsafe because JS and WebCore execution are not 12 synchronized. That unsafety comes into play when the collector 13 deallocates a JS object that wraps a WebCore object, thus causing the 14 WebCore object to be deallocated. 15 16 The solution here is to have each JSCell know whether it is safe to 17 collect on a non-main thread, and to avoid collecting unsafe cells 18 when on a non-main thread. 19 20 We don't have a way to test PAC files yet, so there's no test 21 attached to this patch. 22 23 * kjs/collector.cpp: 24 (KJS::Collector::collect): 25 (1) Added the test "currentThreadIsMainThread || 26 imp->m_destructorIsThreadSafe". 27 28 * kjs/protect.h: 29 (KJS::gcProtectNullTolerant): 30 (KJS::gcUnprotectNullTolerant): 31 * kjs/value.h: 32 (KJS::JSCell::JSCell): The bools here must be bitfields, otherwise 33 m_destructorIsThreadSafe becomes another whole word, ruining the 34 collector optimizations we've made based on the size of a JSObject. 35 * kxmlcore/FastMalloc.cpp: 36 (KXMLCore::currentThreadIsMainThread): 37 (KXMLCore::fastMallocRegisterThread): 38 * kxmlcore/FastMalloc.h: 39 1 40 2006-03-28 Darin Adler <darin@apple.com> 2 41 -
trunk/JavaScriptCore/kjs/collector.cpp
r13089 r13568 444 444 InterpreterImp *scr = InterpreterImp::s_hook; 445 445 do { 446 //fprintf( stderr, "Collector marking interpreter %p\n",(void*)scr);447 446 scr->mark(); 448 447 scr = scr->next; … … 461 460 size_t numLiveObjects = heap.numLiveObjects; 462 461 462 #if USE(MULTIPLE_THREADS) 463 bool currentThreadIsMainThread = !pthread_is_threaded_np() || pthread_main_np(); 464 #else 465 bool currentThreadIsMainThread = true; 466 #endif 467 463 468 for (size_t block = 0; block < heap.usedBlocks; block++) { 464 469 CollectorBlock *curBlock = heap.blocks[block]; … … 474 479 if (imp->m_marked) { 475 480 imp->m_marked = false; 476 } else {481 } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe) { 477 482 imp->~JSCell(); 478 483 --usedCells; … … 495 500 if (imp->m_marked) { 496 501 imp->m_marked = false; 497 } else {502 } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe) { 498 503 imp->~JSCell(); 499 504 --usedCells; -
trunk/JavaScriptCore/kjs/object.h
r13465 r13568 118 118 * @param proto The prototype 119 119 */ 120 JSObject(JSObject *proto );120 JSObject(JSObject *proto, bool destructorIsThreadSafe = true); 121 121 122 122 /** … … 124 124 * (that is, the ECMAScript "null" value, not a null object pointer). 125 125 */ 126 JSObject();126 explicit JSObject(bool destructorIsThreadSafe = true); 127 127 128 128 virtual void mark(); … … 580 580 JSObject *throwError(ExecState *, ErrorType); 581 581 582 inline JSObject::JSObject(JSObject *proto) 583 : _proto(proto), _internalValue(0) 582 inline JSObject::JSObject(JSObject *proto, bool destructorIsThreadSafe) 583 : JSCell(destructorIsThreadSafe) 584 , _proto(proto) 585 , _internalValue(0) 584 586 { 585 587 assert(proto); 586 588 } 587 589 588 inline JSObject::JSObject() 589 : _proto(jsNull()), _internalValue(0) 590 inline JSObject::JSObject(bool destructorIsThreadSafe) 591 : JSCell(destructorIsThreadSafe) 592 , _proto(jsNull()) 593 , _internalValue(0) 590 594 { 591 595 } -
trunk/JavaScriptCore/kjs/protect.h
r12301 r13568 44 44 inline void gcProtectNullTolerant(JSValue *val) 45 45 { 46 if (val) gcProtect(val); 46 if (val) 47 gcProtect(val); 47 48 } 48 49 49 50 inline void gcUnprotectNullTolerant(JSValue *val) 50 51 { 51 if (val) gcUnprotect(val); 52 if (val) 53 gcUnprotect(val); 52 54 } 53 55 -
trunk/JavaScriptCore/kjs/value.h
r12949 r13568 122 122 friend class GetterSetterImp; 123 123 private: 124 JSCell();124 explicit JSCell(bool destructorIsThreadSafe = true); 125 125 virtual ~JSCell(); 126 126 public: … … 156 156 157 157 private: 158 bool m_marked; 158 bool m_destructorIsThreadSafe : 1; 159 bool m_marked : 1; 159 160 }; 160 161 … … 209 210 } 210 211 211 inline JSCell::JSCell() 212 : m_marked(false) 212 inline JSCell::JSCell(bool destructorIsThreadSafe) 213 : m_destructorIsThreadSafe(destructorIsThreadSafe) 214 , m_marked(false) 213 215 { 214 216 } -
trunk/JavaScriptCore/kxmlcore/FastMalloc.cpp
r13091 r13568 104 104 #endif 105 105 106 } // namespace K JS106 } // namespace KXMLCore 107 107 108 108 #else … … 1396 1396 if (thread != mainThreadID) { 1397 1397 // We lock when writing isMultiThreaded but not when reading it. 1398 // It's ok if the main thread temporarily gets it wrong - the global1399 // variable cache is the same as the thread-specific cache for the main thread.1398 // It's ok if the main thread gets it wrong - for the main thread, the 1399 // global variable cache is the same as the thread-specific cache. 1400 1400 // And other threads can't get it wrong because they must have gone through 1401 1401 // this function before allocating so they've synchronized. 1402 1402 // Also, mainThreadCache is only set when isMultiThreaded is false, 1403 // to save a branch in some cases.1403 // to save a branch in some cases. 1404 1404 SpinLockHolder lock(&multiThreadedLock); 1405 1405 isMultiThreaded = true; … … 2316 2316 2317 2317 #if KXC_CHANGES 2318 } // namespace K JS2318 } // namespace KXMLCore 2319 2319 #endif 2320 2320 -
trunk/JavaScriptCore/kxmlcore/FastMalloc.h
r13089 r13568 33 33 void fastFree(void* p); 34 34 void *fastRealloc(void* p, size_t n); 35 35 36 36 } // namespace KXMLCore 37 37 -
trunk/WebCore/ChangeLog
r13567 r13568 76 76 (WebCore::Image::getNSImage): Use KWQRetainNSRelease to properly retain 77 77 a reference to an Objective-C object in a C++ class. 78 79 2006-03-29 Geoffrey Garen <ggaren@apple.com> 80 81 Reviewed by Darin. 82 83 - WebCore side of fix for <rdar://problem/4308243> 8F36 Regression: 84 crash in malloc_consolidate if you use a .PAC file 85 86 (1) To ensure thread-safe deallocation, set the "unsafe to destroy on 87 non-main threads" bit in the DOMObject constructor. 88 89 (2) Made all binding objects inherit from DOMObject, because the 90 WebCore data structures they wrap are not thread-safe. "DOMObject" is 91 a slightly awkward name for things like the Window object, but the 92 DOM spec is considering adding a Window object, and creating a whole 93 new base class for this purpose seemed like overkill. 94 95 * khtml/ecma/JSDOMParser.h: 96 * khtml/ecma/JSXMLHttpRequest.h: 97 * khtml/ecma/JSXMLSerializer.cpp: 98 (KJS::XMLSerializerConstructorImp::XMLSerializerConstructorImp): 99 * khtml/ecma/JSXMLSerializer.h: 100 * khtml/ecma/JSXSLTProcessor.h: 101 * khtml/ecma/kjs_binding.h: 102 (KJS::DOMObject::DOMObject): Unset the "safe to collect on non-main 103 threads bit" to ensure thread-safe deallocation. 104 * khtml/ecma/kjs_html.h: 105 * khtml/ecma/kjs_navigator.cpp: 106 (KJS::Navigator::Navigator): 107 (KJS::PluginBase::PluginBase): 108 * khtml/ecma/kjs_navigator.h: 109 * khtml/ecma/kjs_proxy.cpp: 110 * khtml/ecma/kjs_window.cpp: 111 (KJS::History::History): 112 (KJS::FrameArray::FrameArray): 113 (KJS::Screen::Screen): 114 (KJS::Window::Window): 115 (KJS::BarInfo::BarInfo): 116 * khtml/ecma/kjs_window.h: 78 117 79 118 2006-03-29 Geoffrey Garen <ggaren@apple.com> -
trunk/WebCore/khtml/ecma/JSDOMParser.h
r13393 r13568 27 27 namespace KJS { 28 28 29 class DOMParserConstructorImp : public JSObject {29 class DOMParserConstructorImp : public DOMObject { 30 30 public: 31 31 DOMParserConstructorImp(ExecState*, WebCore::Document*); -
trunk/WebCore/khtml/ecma/JSXMLHttpRequest.h
r13393 r13568 33 33 namespace KJS { 34 34 35 class JSXMLHttpRequestConstructorImp : public JSObject {35 class JSXMLHttpRequestConstructorImp : public DOMObject { 36 36 public: 37 37 JSXMLHttpRequestConstructorImp(ExecState *exec, WebCore::Document *d); -
trunk/WebCore/khtml/ecma/JSXMLSerializer.cpp
r13393 r13568 42 42 43 43 XMLSerializerConstructorImp::XMLSerializerConstructorImp(ExecState *exec) 44 : JSObject()45 44 { 46 45 putDirect(prototypePropertyName, XMLSerializerProto::self(exec), DontEnum|DontDelete|ReadOnly); -
trunk/WebCore/khtml/ecma/JSXMLSerializer.h
r13393 r13568 28 28 class JSEventListener; 29 29 30 class XMLSerializerConstructorImp : public JSObject {30 class XMLSerializerConstructorImp : public DOMObject { 31 31 public: 32 32 XMLSerializerConstructorImp(ExecState *); -
trunk/WebCore/khtml/ecma/JSXSLTProcessor.h
r13393 r13568 58 58 }; 59 59 60 class XSLTProcessorConstructorImp : public JSObject {60 class XSLTProcessorConstructorImp : public DOMObject { 61 61 public: 62 62 XSLTProcessorConstructorImp(ExecState *); -
trunk/WebCore/khtml/ecma/kjs_binding.h
r13405 r13568 47 47 class DOMObject : public JSObject { 48 48 protected: 49 DOMObject() : JSObject() {} 49 // DOMObject Destruction is not thread-safe because JS DOM objects 50 // wrap unsafe WebCore DOM data structures 51 DOMObject() : JSObject(false) {} 50 52 public: 51 virtual UString toString(ExecState *exec) const;53 virtual UString toString(ExecState *exec) const; 52 54 }; 53 55 -
trunk/WebCore/khtml/ecma/kjs_html.h
r13393 r13568 340 340 ////////////////////// Option Object //////////////////////// 341 341 342 class OptionConstructorImp : public JSObject {342 class OptionConstructorImp : public DOMObject { 343 343 public: 344 344 OptionConstructorImp(ExecState *exec, WebCore::Document *d); … … 351 351 ////////////////////// Image Object //////////////////////// 352 352 353 class ImageConstructorImp : public JSObject {353 class ImageConstructorImp : public DOMObject { 354 354 public: 355 355 ImageConstructorImp(ExecState *exec, WebCore::Document *d); -
trunk/WebCore/khtml/ecma/kjs_navigator.cpp
r13410 r13568 37 37 namespace KJS { 38 38 39 class PluginBase : public JSObject {39 class PluginBase : public DOMObject { 40 40 public: 41 41 PluginBase(ExecState *exec); … … 142 142 KJS_IMPLEMENT_PROTOFUNC(NavigatorFunc) 143 143 144 Navigator::Navigator(ExecState *exec, Frame *p) 145 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), m_frame(p) { } 144 Navigator::Navigator(ExecState *exec, Frame *f) 145 : m_frame(f) 146 { 147 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 148 } 146 149 147 150 bool Navigator::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) … … 225 228 226 229 PluginBase::PluginBase(ExecState *exec) 227 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype() ) 228 { 230 { 231 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 232 229 233 cachePluginDataIfNecessary(); 230 234 m_plugInCacheRefCount++; -
trunk/WebCore/khtml/ecma/kjs_navigator.h
r13014 r13568 22 22 #define KJS_Navigator_H 23 23 24 #include "kjs_binding.h" 24 25 #include <kjs/object.h> 25 26 … … 30 31 namespace KJS { 31 32 32 class Navigator : public JSObject {33 class Navigator : public DOMObject { 33 34 public: 34 35 Navigator(ExecState *exec, WebCore::Frame *p); -
trunk/WebCore/khtml/ecma/kjs_proxy.cpp
r13527 r13568 126 126 127 127 // Implementation of the debug() function 128 class TestFunctionImp : public JSObject {128 class TestFunctionImp : public DOMObject { 129 129 public: 130 TestFunctionImp() : JSObject() {}131 130 virtual bool implementsCall() const { return true; } 132 131 virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); -
trunk/WebCore/khtml/ecma/kjs_window.cpp
r13532 r13568 96 96 ////////////////////// History Object //////////////////////// 97 97 98 class History : public JSObject {98 class History : public DOMObject { 99 99 friend class HistoryFunc; 100 100 public: 101 History(ExecState *exec, Frame *p) 102 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), m_frame(p) { } 101 History(ExecState *exec, Frame *f) 102 : m_frame(f) 103 { 104 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 105 } 103 106 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 104 107 JSValue *getValueProperty(ExecState *exec, int token) const; … … 112 115 }; 113 116 114 class FrameArray : public JSObject { 117 118 class FrameArray : public DOMObject { 115 119 public: 116 FrameArray(ExecState *exec, Frame *p) 117 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), m_frame(p) { } 120 FrameArray(ExecState *exec, Frame *f) 121 : m_frame(f) 122 { 123 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 124 } 118 125 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); 119 126 JSValue *getValueProperty(ExecState *exec, int token); … … 157 164 // We set the object prototype so that toString is implemented 158 165 Screen::Screen(ExecState* exec, Frame* f) 159 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), m_frame(f) 160 { 166 : m_frame(f) 167 { 168 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 161 169 } 162 170 … … 307 315 KJS_IMPLEMENT_PROTOFUNC(WindowFunc) 308 316 309 Window::Window(Frame *p) 310 : JSObject(/*no proto*/) 311 , m_frame(p) 317 Window::Window(Frame *f) 318 : m_frame(f) 312 319 , screen(0) 313 320 , history(0) … … 2378 2385 @end 2379 2386 */ 2380 BarInfo::BarInfo(ExecState *exec, Frame *p, Type barType) 2381 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()) 2382 , m_frame(p) 2387 BarInfo::BarInfo(ExecState *exec, Frame *f, Type barType) 2388 : m_frame(f) 2383 2389 , m_type(barType) 2384 2390 { 2391 setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); 2385 2392 } 2386 2393 -
trunk/WebCore/khtml/ecma/kjs_window.h
r13393 r13568 68 68 class DOMWindowTimer; 69 69 70 class Screen : public JSObject {70 class Screen : public DOMObject { 71 71 public: 72 72 enum { Height, Width, ColorDepth, PixelDepth, AvailLeft, AvailTop, AvailHeight, AvailWidth }; … … 81 81 }; 82 82 83 class Window : public JSObject {83 class Window : public DOMObject { 84 84 friend class Location; 85 85 friend class WindowFunc; … … 219 219 }; 220 220 221 class Location : public JSObject {221 class Location : public DOMObject { 222 222 public: 223 223 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); … … 237 237 }; 238 238 239 class Selection : public JSObject {239 class Selection : public DOMObject { 240 240 public: 241 241 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); … … 255 255 }; 256 256 257 class BarInfo : public JSObject {257 class BarInfo : public DOMObject { 258 258 public: 259 259 virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
Note: See TracChangeset
for help on using the changeset viewer.