Changeset 20004 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Mar 6, 2007, 8:25:49 PM (18 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/collector.cpp
r19994 r20004 109 109 static CollectorHeap heap = {NULL, 0, 0, 0, NULL, 0, 0, 0, 0}; 110 110 111 size_t Collector::mainThreadOnlyObjectCount = 0; 111 112 bool Collector::memoryFull = false; 112 113 … … 474 475 } 475 476 477 void Collector::collectOnMainThreadOnly(JSValue* value) 478 { 479 ASSERT(value); 480 ASSERT(JSLock::lockCount() > 0); 481 482 if (JSImmediate::isImmediate(value)) 483 return; 484 485 JSCell* cell = value->downcast(); 486 cell->m_collectOnMainThreadOnly = true; 487 ++mainThreadOnlyObjectCount; 488 } 489 476 490 void Collector::markProtectedObjects() 477 491 { … … 485 499 } 486 500 501 void Collector::markMainThreadOnlyObjects() 502 { 503 ASSERT(!pthread_main_np()); 504 505 // Optimization for clients that never register "main thread only" objects. 506 if (!mainThreadOnlyObjectCount) 507 return; 508 509 // FIXME: We can optimize this marking algorithm by keeping an exact set of 510 // "main thread only" objects when the "main thread only" object count is 511 // small. We don't want to keep an exact set all the time, because WebCore 512 // tends to create lots of "main thread only" objects, and all that set 513 // thrashing can be expensive. 514 515 size_t count = 0; 516 517 for (size_t block = 0; block < heap.usedBlocks; block++) { 518 ASSERT(count < mainThreadOnlyObjectCount); 519 520 CollectorBlock* curBlock = heap.blocks[block]; 521 size_t minimumCellsToProcess = curBlock->usedCells; 522 for (size_t i = 0; (i < minimumCellsToProcess) & (i < CELLS_PER_BLOCK); i++) { 523 CollectorCell* cell = curBlock->cells + i; 524 if (cell->u.freeCell.zeroIfFree == 0) 525 ++minimumCellsToProcess; 526 else { 527 JSCell* imp = reinterpret_cast<JSCell*>(cell); 528 if (imp->m_collectOnMainThreadOnly) { 529 if(!imp->marked()) 530 imp->mark(); 531 if (++count == mainThreadOnlyObjectCount) 532 return; 533 } 534 } 535 } 536 } 537 538 for (size_t cell = 0; cell < heap.usedOversizeCells; cell++) { 539 ASSERT(count < mainThreadOnlyObjectCount); 540 541 JSCell* imp = reinterpret_cast<JSCell*>(heap.oversizeCells[cell]); 542 if (imp->m_collectOnMainThreadOnly) { 543 if (!imp->marked()) 544 imp->mark(); 545 if (++count == mainThreadOnlyObjectCount) 546 return; 547 } 548 } 549 } 550 487 551 bool Collector::collect() 488 552 { … … 502 566 Interpreter* scr = Interpreter::s_hook; 503 567 do { 504 scr->mark( currentThreadIsMainThread);568 scr->mark(); 505 569 scr = scr->next; 506 570 } while (scr != Interpreter::s_hook); … … 512 576 markProtectedObjects(); 513 577 List::markProtectedLists(); 578 if (!currentThreadIsMainThread) 579 markMainThreadOnlyObjects(); 514 580 515 581 // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else … … 531 597 if (imp->m_marked) { 532 598 imp->m_marked = false; 533 } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe){599 } else { 534 600 // special case for allocated but uninitialized object 535 // (We don't need this check earlier because nothing prior this point assumes the object has a valid vptr.) 601 // (We don't need this check earlier because nothing prior this point 602 // assumes the object has a valid vptr.) 536 603 if (cell->u.freeCell.zeroIfFree == 0) 537 604 continue; 538 605 606 ASSERT(currentThreadIsMainThread || !imp->m_collectOnMainThreadOnly); 607 if (imp->m_collectOnMainThreadOnly) 608 --mainThreadOnlyObjectCount; 539 609 imp->~JSCell(); 540 610 --usedCells; … … 557 627 if (imp->m_marked) { 558 628 imp->m_marked = false; 559 } else if (currentThreadIsMainThread || imp->m_destructorIsThreadSafe) { 629 } else { 630 ASSERT(currentThreadIsMainThread || !imp->m_collectOnMainThreadOnly); 631 if (imp->m_collectOnMainThreadOnly) 632 --mainThreadOnlyObjectCount; 560 633 imp->~JSCell(); 561 634 --usedCells; … … 600 673 JSCell *imp = (JSCell *)heap.oversizeCells[cell]; 601 674 602 if (!imp->m_marked && (currentThreadIsMainThread || imp->m_destructorIsThreadSafe)) { 675 if (imp->m_marked) { 676 imp->m_marked = false; 677 cell++; 678 } else { 679 ASSERT(currentThreadIsMainThread || !imp->m_collectOnMainThreadOnly); 680 if (imp->m_collectOnMainThreadOnly) 681 --mainThreadOnlyObjectCount; 603 682 imp->~JSCell(); 604 683 #if DEBUG_COLLECTOR … … 618 697 heap.oversizeCells = (CollectorCell **)fastRealloc(heap.oversizeCells, heap.numOversizeCells * sizeof(CollectorCell *)); 619 698 } 620 } else {621 imp->m_marked = false;622 cell++;623 699 } 624 700 } -
trunk/JavaScriptCore/kjs/collector.h
r15696 r20004 32 32 namespace KJS { 33 33 34 /**35 * @short Garbage collector.36 */37 34 class Collector { 38 // disallow direct construction/destruction39 Collector();40 35 public: 41 36 static void* allocate(size_t s); … … 54 49 static void protect(JSValue*); 55 50 static void unprotect(JSValue*); 51 52 static void collectOnMainThreadOnly(JSValue*); 56 53 57 54 static size_t numInterpreters(); … … 61 58 class Thread; 62 59 static void registerThread(); 63 60 64 61 private: 62 Collector(); 65 63 66 64 static void markProtectedObjects(); 65 static void markMainThreadOnlyObjects(); 67 66 static void markCurrentThreadConservatively(); 68 67 static void markOtherThreadConservatively(Thread* thread); … … 70 69 static void markStackObjectsConservatively(void* start, void* end); 71 70 71 static size_t mainThreadOnlyObjectCount; 72 72 static bool memoryFull; 73 73 }; -
trunk/JavaScriptCore/kjs/date_object.cpp
r19945 r20004 597 597 : InternalFunctionImp(funcProto) 598 598 { 599 // ECMA 15.9.4.1 Date.prototype 599 static const Identifier* parsePropertyName = new Identifier("parse"); 600 static const Identifier* UTCPropertyName = new Identifier("UTC"); 601 600 602 putDirect(prototypePropertyName, dateProto, DontEnum|DontDelete|ReadOnly); 601 602 static const Identifier parsePropertyName("parse"); 603 putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::Parse, 1, parsePropertyName), DontEnum); 604 static const Identifier UTCPropertyName("UTC"); 605 putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::UTC, 7, UTCPropertyName), DontEnum); 606 607 // no. of arguments for constructor 603 putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::Parse, 1, *parsePropertyName), DontEnum); 604 putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::UTC, 7, *UTCPropertyName), DontEnum); 608 605 putDirect(lengthPropertyName, 7, ReadOnly|DontDelete|DontEnum); 609 606 } -
trunk/JavaScriptCore/kjs/function_object.cpp
r19203 r20004 41 41 FunctionPrototype::FunctionPrototype(ExecState *exec) 42 42 { 43 static const Identifier* applyPropertyName = new Identifier("apply"); 44 static const Identifier* callPropertyName = new Identifier("call"); 45 43 46 putDirect(lengthPropertyName, jsNumber(0), DontDelete|ReadOnly|DontEnum); 44 47 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::ToString, 0, toStringPropertyName), DontEnum); 45 static const Identifier applyPropertyName("apply"); 46 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Apply, 2, applyPropertyName), DontEnum); 47 static const Identifier callPropertyName("call"); 48 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Call, 1, callPropertyName), DontEnum); 48 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Apply, 2, *applyPropertyName), DontEnum); 49 putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Call, 1, *callPropertyName), DontEnum); 49 50 } 50 51 -
trunk/JavaScriptCore/kjs/identifier.cpp
r17405 r20004 39 39 #include "identifier.h" 40 40 41 #include "JSLock.h" 42 #include <new> // for placement new 43 #include <string.h> // for strlen 44 #include <wtf/Assertions.h> 41 45 #include <wtf/FastMalloc.h> 42 46 #include <wtf/HashSet.h> 43 #include <string.h> // for strlen44 #include <new> // for placement new45 47 46 48 namespace WTF { … … 67 69 static inline IdentifierTable& identifierTable() 68 70 { 71 ASSERT(JSLock::lockCount() > 0); 72 69 73 if (!table) 70 74 table = new IdentifierTable; -
trunk/JavaScriptCore/kjs/interpreter.cpp
r19901 r20004 538 538 } 539 539 540 void Interpreter::mark( bool)540 void Interpreter::mark() 541 541 { 542 542 if (m_context) -
trunk/JavaScriptCore/kjs/interpreter.h
r19901 r20004 287 287 * implementing custom mark methods must make sure to chain to this one. 288 288 */ 289 virtual void mark( bool currentThreadIsMainThread);289 virtual void mark(); 290 290 291 291 #ifdef KJS_DEBUG_MEM -
trunk/JavaScriptCore/kjs/list.cpp
r15698 r20004 142 142 static inline ListImp *allocateListImp() 143 143 { 144 ASSERT(JSLock::lockCount() > 0); 145 144 146 // Find a free one in the pool. 145 147 if (poolUsed < poolSize) { … … 202 204 203 205 void List::release() 204 { 206 { 207 ASSERT(JSLock::lockCount() > 0); 208 205 209 ListImp *imp = static_cast<ListImp *>(_impBase); 206 210 … … 222 226 poolUsed--; 223 227 } else { 224 assert(imp->state == usedOnHeap);228 ASSERT(imp->state == usedOnHeap); 225 229 HeapListImp *list = static_cast<HeapListImp *>(imp); 226 230 … … 259 263 void List::append(JSValue *v) 260 264 { 265 ASSERT(JSLock::lockCount() > 0); 266 261 267 ListImp *imp = static_cast<ListImp *>(_impBase); 262 268 … … 332 338 } 333 339 334 const List &List::empty()335 { 336 static List emptyList;337 return emptyList;340 const List& List::empty() 341 { 342 static List* staticEmptyList = new List; 343 return *staticEmptyList; 338 344 } 339 345 -
trunk/JavaScriptCore/kjs/object.h
r17372 r20004 107 107 * @param proto The prototype 108 108 */ 109 JSObject(JSValue* proto , bool destructorIsThreadSafe = true);109 JSObject(JSValue* proto); 110 110 111 111 /** … … 113 113 * (that is, the ECMAScript "null" value, not a null object pointer). 114 114 */ 115 explicit JSObject(bool destructorIsThreadSafe = true);115 JSObject(); 116 116 117 117 virtual void mark(); … … 503 503 JSObject *throwError(ExecState *, ErrorType); 504 504 505 inline JSObject::JSObject(JSValue* proto, bool destructorIsThreadSafe) 506 : JSCell(destructorIsThreadSafe) 507 , _proto(proto) 505 inline JSObject::JSObject(JSValue* proto) 506 : _proto(proto) 508 507 { 509 508 assert(proto); 510 509 } 511 510 512 inline JSObject::JSObject(bool destructorIsThreadSafe) 513 : JSCell(destructorIsThreadSafe) 514 , _proto(jsNull()) 511 inline JSObject::JSObject() 512 : _proto(jsNull()) 515 513 { 516 514 } -
trunk/JavaScriptCore/kjs/object_object.cpp
r13833 r20004 34 34 : JSObject() // [[Prototype]] is null 35 35 { 36 static const Identifier* hasOwnPropertyPropertyName = new Identifier("hasOwnProperty"); 37 static const Identifier* propertyIsEnumerablePropertyName = new Identifier("propertyIsEnumerable"); 38 static const Identifier* isPrototypeOfPropertyName = new Identifier("isPrototypeOf"); 39 static const Identifier* defineGetterPropertyName = new Identifier("__defineGetter__"); 40 static const Identifier* defineSetterPropertyName = new Identifier("__defineSetter__"); 41 static const Identifier* lookupGetterPropertyName = new Identifier("__lookupGetter__"); 42 static const Identifier* lookupSetterPropertyName = new Identifier("__lookupSetter__"); 43 36 44 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToString, 0, toStringPropertyName), DontEnum); 37 45 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ToLocaleString, 0, toLocaleStringPropertyName), DontEnum); 38 46 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::ValueOf, 0, valueOfPropertyName), DontEnum); 39 static Identifier hasOwnPropertyPropertyName("hasOwnProperty"); 40 static Identifier propertyIsEnumerablePropertyName("propertyIsEnumerable"); 41 static Identifier isPrototypeOfPropertyName("isPrototypeOf"); 42 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::HasOwnProperty, 1, hasOwnPropertyPropertyName), DontEnum); 43 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::PropertyIsEnumerable, 1, propertyIsEnumerablePropertyName), DontEnum); 44 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::IsPrototypeOf, 1, isPrototypeOfPropertyName), DontEnum); 47 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::HasOwnProperty, 1, *hasOwnPropertyPropertyName), DontEnum); 48 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::PropertyIsEnumerable, 1, *propertyIsEnumerablePropertyName), DontEnum); 49 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::IsPrototypeOf, 1, *isPrototypeOfPropertyName), DontEnum); 45 50 46 51 // Mozilla extensions 47 static const Identifier defineGetterPropertyName("__defineGetter__"); 48 static const Identifier defineSetterPropertyName("__defineSetter__"); 49 static const Identifier lookupGetterPropertyName("__lookupGetter__"); 50 static const Identifier lookupSetterPropertyName("__lookupSetter__"); 51 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineGetter, 2, defineGetterPropertyName), DontEnum); 52 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineSetter, 2, defineSetterPropertyName), DontEnum); 53 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupGetter, 1, lookupGetterPropertyName), DontEnum); 54 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupSetter, 1, lookupSetterPropertyName), DontEnum); 52 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineGetter, 2, *defineGetterPropertyName), DontEnum); 53 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::DefineSetter, 2, *defineSetterPropertyName), DontEnum); 54 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupGetter, 1, *lookupGetterPropertyName), DontEnum); 55 putDirectFunction(new ObjectProtoFunc(exec, funcProto, ObjectProtoFunc::LookupSetter, 1, *lookupSetterPropertyName), DontEnum); 55 56 } 56 57 -
trunk/JavaScriptCore/kjs/regexp_object.cpp
r18256 r20004 49 49 : JSObject(objProto) 50 50 { 51 // The constructor will be added later in RegExpObject's constructor (?) 52 53 static const Identifier execPropertyName("exec"); 54 static const Identifier testPropertyName("test"); 55 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Exec, 0, execPropertyName), DontEnum); 56 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Test, 0, testPropertyName), DontEnum); 51 static const Identifier* execPropertyName = new Identifier("exec"); 52 static const Identifier* testPropertyName = new Identifier("test"); 53 54 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Exec, 0, *execPropertyName), DontEnum); 55 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::Test, 0, *testPropertyName), DontEnum); 57 56 putDirectFunction(new RegExpProtoFunc(exec, funcProto, RegExpProtoFunc::ToString, 0, toStringPropertyName), DontEnum); 58 57 } -
trunk/JavaScriptCore/kjs/ustring.cpp
r19679 r20004 25 25 #include "ustring.h" 26 26 27 #include "JSLock.h" 28 #include "dtoa.h" 29 #include "identifier.h" 30 #include "operations.h" 27 31 #include <assert.h> 32 #include <ctype.h> 33 #include <float.h> 34 #include <math.h> 35 #include <stdio.h> 28 36 #include <stdlib.h> 29 #include < stdio.h>30 #include <ctype.h> 37 #include <wtf/Vector.h> 38 31 39 #if HAVE(STRING_H) 32 40 #include <string.h> … … 35 43 #include <strings.h> 36 44 #endif 37 38 #include "dtoa.h"39 #include "identifier.h"40 #include "operations.h"41 #include <float.h>42 #include <math.h>43 #include <wtf/Vector.h>44 45 45 46 using std::max; … … 155 156 UChar& UCharReference::ref() const 156 157 { 158 ASSERT(JSLock::lockCount() > 0); 159 157 160 if (offset < str->rep()->len) 158 161 return *(str->rep()->data() + offset); … … 165 168 PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l) 166 169 { 170 ASSERT(JSLock::lockCount() > 0); 171 167 172 int sizeInBytes = l * sizeof(UChar); 168 173 UChar *copyD = static_cast<UChar *>(fastMalloc(sizeInBytes)); … … 174 179 PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l) 175 180 { 181 ASSERT(JSLock::lockCount() > 0); 182 176 183 Rep *r = new Rep; 177 184 r->offset = 0; … … 193 200 PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length) 194 201 { 195 assert(base); 202 ASSERT(JSLock::lockCount() > 0); 203 ASSERT(base); 196 204 197 205 int baseOffset = base->offset; … … 223 231 void UString::Rep::destroy() 224 232 { 233 ASSERT(JSLock::lockCount() > 0); 234 225 235 if (isIdentifier) 226 236 Identifier::remove(this); … … 467 477 } 468 478 469 const UString &UString::null()470 { 471 static UString n;472 return n;479 const UString& UString::null() 480 { 481 static UString* n = new UString; 482 return *n; 473 483 } 474 484 -
trunk/JavaScriptCore/kjs/ustring.h
r19679 r20004 25 25 #define _KJS_USTRING_H_ 26 26 27 #include "JSLock.h" 28 #include <stdint.h> 29 #include <wtf/Assertions.h> 27 30 #include <wtf/FastMalloc.h> 31 #include <wtf/PassRefPtr.h> 28 32 #include <wtf/RefPtr.h> 29 #include <wtf/PassRefPtr.h>30 31 #include <stdint.h>32 33 33 34 /* On ARM some versions of GCC don't pack structures by default so sizeof(UChar) … … 200 201 static unsigned computeHash(const char *); 201 202 202 Rep* ref() { ++rc; return this; }203 void deref() { if (--rc == 0) destroy(); }203 Rep* ref() { ASSERT(JSLock::lockCount() > 0); ++rc; return this; } 204 void deref() { ASSERT(JSLock::lockCount() > 0); if (--rc == 0) destroy(); } 204 205 205 206 // unshared data -
trunk/JavaScriptCore/kjs/value.h
r18715 r20004 123 123 friend class GetterSetterImp; 124 124 private: 125 explicit JSCell(bool destructorIsThreadSafe = true);125 JSCell(); 126 126 virtual ~JSCell(); 127 127 public: … … 157 157 158 158 private: 159 bool m_ destructorIsThreadSafe: 1;159 bool m_collectOnMainThreadOnly : 1; 160 160 bool m_marked : 1; 161 161 }; … … 204 204 } 205 205 206 inline JSCell::JSCell( bool destructorIsThreadSafe)207 : m_ destructorIsThreadSafe(destructorIsThreadSafe)206 inline JSCell::JSCell() 207 : m_collectOnMainThreadOnly(false) 208 208 , m_marked(false) 209 209 {
Note:
See TracChangeset
for help on using the changeset viewer.